programing

Jackson이 값을 문자열로 읽음

sourcejob 2023. 2. 8. 17:51
반응형

Jackson이 값을 문자열로 읽음

값을 알 수 없는 객체가 있습니다.

{
 "data": [
    {"a":...,
    "dont_know_what_else_is_here":....}
 ]
}

"data" 값을 문자열로 변수/데이터베이스에 저장하려고 합니다.

스트리밍 API에서 어떻게 읽으면 좋을까요?

이 오브젝트를 이미 읽어들이고 있는 경우JsonNode, 다음과 같이 할 수 있습니다.

String content = jsonNode.get("data").textValue();

UPD: 스트리밍 파서를 사용 중이므로 잭슨 사용에 대한 이 예가 도움이 될 수 있습니다.

UPD: 메서드 이름이 textValue() - docs가 되었습니다.

JsonNode에서 문자열 형식으로 데이터를 가져오려고 할 때는 보통 asText를 사용하지만 textValue를 사용해야 합니다.

asText: 컨테이너 값의 유효한 String 표현을 반환하는 메서드. 노드가 값 노드(method isValueNode()가 true를 반환함)이면 string이 비어 있습니다.

textValue : String 값에 액세스하기 위해 사용하는 메서드.비String 값 노드에 대해서는 변환을 수행하지 않습니다.비String 값(isTextual()이 false를 반환하는 값)의 경우 늘이 반환됩니다.String 값의 경우 null은 반환되지 않습니다(단, 빈 문자열이 반환될 수 있습니다).

예를 들어보자.

JsonNode getJsonData(){
    ObjectMapper mapper = new ObjectMapper();
    ObjectNode node = mapper.createObjectNode(); 
    node.put("anyParameter",null);
    return node;
}
JsonNode node = getJsonData();
json.get("anyParameter").asText() // this will give output as "null"
json.get("").textValue() // this will give output as null

키 값 쌍에 따라 지도의 데이터를 얻을 수 있습니다.

Map<String, Object> mp = mapper.readValue(new File("xyz.txt"),new TypeReference<Map<String, Object>>() {});

이제 맵에서 값을 가져옵니다.

mp.get("data");

파서가 이미 있고 "데이터" 토큰(예: 사용자 지정 역직렬화기에서)을 가리킨다고 가정하면 다음을 수행할 수 있습니다.

ObjectMapper mapper = new ObjectMapper();
JsonNode treeNode = mapper.readTree(parser);
return treeNode.toString();

그러면 "data" 값을 포함하는 String이 나타납니다.

JSON 결과에 대한 엔티티 클래스를 가질 수 있습니다.

String json = "your_json";
ObjectMapper mapper = new ObjectMapper();
Entity entity = mapper .readValue(json, Entity.class);
// here you can do everything with entity as you wish

// to write Entity value as String when you wish
String text = mapper.writeValueAsString(object);
// to write Entity child's value as String when you wish (let's data contain data part)
String data = mapper.writeValueAsString(object.getData());

예를 들어 사용자라는 POJO java 클래스가 있다고 가정합니다(이 클래스에서 취득).

public class User {
public enum Gender { MALE, FEMALE };

public class Name {
    private String _first, _last;

    public String getFirst() { return _first; }
    public String getLast() { return _last; }

    public void setFirst(String s) { _first = s; }
    public void setLast(String s) { _last = s; }
}

private Gender _gender;
private Name _name;
private boolean _isVerified;
private byte[] _userImage;

public Name getName() { return _name; }
public boolean isVerified() { return _isVerified; }
public Gender getGender() { return _gender; }
public byte[] getUserImage() { return _userImage; }

public void setName(Name n) { _name = n; }
public void setVerified(boolean b) { _isVerified = b; }
public void setGender(Gender g) { _gender = g; }
public void setUserImage(byte[] b) { _userImage = b; }

}

이제 JSON 문자열이 웹 소켓이나 다른 곳에서 전송됩니다.예를 들어, 이 문자열이 취득되고 있다고 가정합니다.

String json = "{\n" +
            "  \"name\" : { \"first\" : \"Joe\", \"last\" : \"Sixpack\" },\n" +
            "  \"gender\" : \"MALE\",\n" +
            "  \"verified\" : false,\n" +
            "  \"userImage\" : \"Rm9vYmFyIQ==\"\n" +
            "}";

이제 이 코드를 사용하는 것만으로 이 JSON 문자열을 POJO 개체로 변환할 수 있습니다.

ObjectMapper mapper = new ObjectMapper();
User user = mapper .readValue(json, User.class);

Streaming API를 사용하여 입력된 서브트리를 읽고 싶을 뿐이지만, 결국 DB(또는 변수)에 저장하기 위해서는 서브트리 전체를 하나로 만들어야 합니다.

그래서 아마 사용하고 싶은 것은JsonParser.readValueAs(MyType.class)-- 호출합니다.ObjectMapper(이 기능을 하려면 , 다음의 방법으로 파서를 작성할 필요가 있습니다).JsonFactory에서 액세스 하다ObjectMapper; 또는 전화해야 합니다.JsonFactory.setCodec(mapper)).

내용이 임의인 경우 다음과 같이 읽을 수 있습니다.Map또는JsonNode:

Map<String,Object> map = parser.readValueAs(Map.class);
// or
JsonNode root = parser.readValueAsTree();

하자마자JsonParser는 데이터베이스 바인드하는 JSON 객체의 START_ELEment를 가리키고 있습니다.

「 」를 하고 있는 String datacreateParser(data)스트리밍 API를 사용하여 문자열 콘텐츠를 수집하려면 다음 방법을 사용합니다.

if ("data".equals(fieldname))
     String strData = getValueAsString(jp);

그리고.

    private static String getValueAsString(JsonParser jp)
        throws com.fasterxml.jackson.core.JsonParseException, IOException {
    JsonToken token = jp.getCurrentToken();
    int counter = 0;

    long startIndex = jp.getCurrentLocation().getCharOffset();
    long endIndex = 0;

    if (token == JsonToken.START_OBJECT) {
        // JsonLocation location = jp.getCurrentLocation();
        // startIndex = location.getCharOffset();
        // System.out.println(",location=" + new Gson().toJson(location) +
        // ", start=" + startIndex);

        counter++;
        while (counter > 0) {
            token = jp.nextToken();
            if (token == JsonToken.START_OBJECT)
                counter++;
            if (token == JsonToken.END_OBJECT) {
                counter--;
                endIndex = jp.getCurrentLocation().getCharOffset();
            }
        }

        return data.substring((int) startIndex - 1, (int) endIndex);

    } else if (token == JsonToken.START_ARRAY) {
        counter++;
        while (counter > 0) {
            token = jp.nextToken();
            if (token == JsonToken.START_ARRAY)
                counter++;
            if (token == JsonToken.END_ARRAY) {
                counter--;
                endIndex = jp.getCurrentLocation().getCharOffset();
            }
        }
        return data.substring((int) startIndex - 1, (int) endIndex);

    } else {
        return jp.getText();
    }
}

등의 "String"사용합니다.JsonLocation.getByteOffset()JsonLocation.getCharOffset()

튜토리얼 페이지를 읽고 드디어 해결 방법을 알아냈다.

다른 사람에게 포인터를 주기 위해:

  1. MappingJ를 사용하여 전환합니다.파서를 작성할 때 SONFactory:

        HttpResponse response = client.execute(request);
        JsonFactory jfactory = new MappingJsonFactory();
        JsonParser parser=jfactory.createJsonParser(response.getEntity().getContent());
    
  2. 그럼 그냥 하면 되겠네

        parser.readValueAsTree().toString();
    

원하는 대로 해석할 수도 있습니다.

언급URL : https://stackoverflow.com/questions/14702918/jackson-read-value-as-string

반응형