Сопоставитель объектов Джексона возвращает 0 для целого числа и ноль для строки - PullRequest
1 голос
/ 18 апреля 2020

У меня есть список структур, которые я буду получать из restEndpoint, и мне нужно сопоставить его со списком Java Object. Но в этом проекте я только что дал строку в формате json в качестве входных данных. Я всегда получаю нулевое значение, когда пытаюсь извлечь строковые данные в моем объекте, и 0, когда получаю целое число.

Я думаю, что objectMapper не может отобразить строку json на объект. Но я не получаю никакой ошибки.

results = mapper.readValue (json, new TypeReference> () {}); Никто не работал. Может быть, какая-то проблема конфигурации или версии?>

Мой объект

public class myObject {

    @JsonProperty("userID")
    private int userID;
    @JsonProperty("id")
    private int id;
    @JsonProperty("title")
    private String title;
    @JsonProperty("body")
    private String body;
    @JsonCreator
    public myObject() {
    }
    @JsonProperty("userID")
    public int getUserId() {
        return userID;
    }
    @JsonProperty("userID")
    public void setUserId(int userId) {
        this.userID = userId;
    }
    @JsonProperty("id")
    public int getId() {
        return id;
    }
    @JsonProperty("id")
    public void setId(int id) {
        this.id = id;
    }
    @JsonProperty("title")
    public String getTitle() {
        return title;
    }
    @JsonProperty("title")
    public void setTitle(String title) {
        this.title = title;
    }
    @JsonProperty("body")
    public String getBody() {
        return body;
    }
    @JsonProperty("body")
    public void setBody(String body) {
        this.body = body;
    } 

Моя функция сопоставления выглядит примерно так

ObjectMapper mapper = new ObjectMapper();
          mapper.setVisibilityChecker(mapper.getSerializationConfig().getDefaultVisibilityChecker()
                .withFieldVisibility(JsonAutoDetect.Visibility.ANY)
                .withGetterVisibility(JsonAutoDetect.Visibility.NONE)
                .withSetterVisibility(JsonAutoDetect.Visibility.NONE)
                .withCreatorVisibility(JsonAutoDetect.Visibility.NONE));
 try {
            //List<myObject> mstCodes = null;
            String json = "[{\"userID\":1,\"id\":\"1\",\"title\":\"IT\",\"body\":\"123234\"},{\"userID\":0,\"id\":\"2\",\"title\":\"Accounting\",\"body\":\"adsfnsdf\"}]";
            List<myObject> mstCodes = mapper.readValue(json, mapper.getTypeFactory().constructCollectionType(List.class, myObject.class));
            System.out.println(mstCodes.size());
            System.out.println(mstCodes.get(0));
            System.out.println(mstCodes.get(0).getUserId());
            System.out.println(mstCodes.get(0).getBody());
        } catch (IOException e) {
            System.out.println("Failed serializing response" + e.getMessage());
        }

Выводы, которые я получаю для приведенных выше операторов печати являются:

2
com.example.varun.testProject$myObject@4e7dc304
0
null

Это может быть простой ошибкой, но любая помощь приветствуется. Спасибо.

Ответы [ 3 ]

1 голос
/ 18 апреля 2020

Я просто упростил ваш myObject класс с Lombok для демонстрационных целей.
Я также просто использовал простой ObjectMapper.
Хитрость заключается в использовании TypeReference, который требует универсальный тип c, который может быть любым, что вам нужно (List<MyObject> в вашем случае).

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.io.IOException;
import java.util.List;

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
class MyObject {

    @JsonProperty("userID")
    private int userID;

    @JsonProperty("id")
    private int id;

    @JsonProperty("title")
    private String title;

    @JsonProperty("body")
    private String body;

}

public class Demo {

    public static void main(String[] args) {
        final String json = "[{\"userID\":1,\"id\":\"1\",\"title\":\"IT\",\"body\":\"123234\"},{\"userID\":0,\"id\":\"2\",\"title\":\"Accounting\",\"body\":\"adsfnsdf\"}]";
        final ObjectMapper objectMapper = new ObjectMapper();

        try {
            final List<MyObject> results = objectMapper.readValue(json, new TypeReference<List<MyObject>>() {});
            System.out.println(results.size());
            System.out.println(results.get(0).getUserID());
            System.out.println(results.get(0).getBody());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

Вывод:

2
1
123234

РЕДАКТИРОВАТЬ: для устранения ошибки No suitable constructor found for type, вот как должен выглядеть ваш объект без Lombok (но он делает то же самое). Вы должны предоставить пустой конструктор и конструктор all args.

@Getter
class MyObject {

    @JsonProperty("userID")
    private int userID;

    @JsonProperty("id")
    private int id;

    @JsonProperty("title")
    private String title;

    @JsonProperty("body")
    private String body;

    public MyObject() {}

    public MyObject(int userID, int id, String title, String body) {}

}
1 голос
/ 18 апреля 2020

Вот как это работает, используя обычный ObjectMapper без избыточных аннотаций на MyObject (Джексон 2.10):

public class MyObject {

    private int userID;
    private int id;
    private String title;
    private String body;

    public int  getUserID()           { return userID; }
    public void setUserID(int userID) { this.userID = userID; }

    public int  getId()       { return id; }
    public void setId(int id) { this.id = id; }

    public String getTitle()             { return title; }
    public void   setTitle(String title) { this.title = title; }

    public String getBody()            { return body; }
    public void   setBody(String body) { this.body = body; }

    @Override
    public String toString() {
        return "MyObject [userID=" + userID + ", id=" + id + ", title=" + title + ", body=" + body + "]";
    }
}

public class MyObjectJsonTest {
    public static void main(String...args) throws JsonMappingException, JsonProcessingException {
        String json = "[{\"userID\":1,\"id\":\"1\",\"title\":\"IT\",\"body\":\"123234\"},{\"userID\":0,\"id\":\"2\",\"title\":\"Accounting\",\"body\":\"adsfnsdf\"}]";
        ObjectMapper mapper = new ObjectMapper();
        List<MyObject> list = mapper.readValue(json, new TypeReference<List<MyObject>>(){});
        System.out.println(list);
    }
}

Вывод:

[MyObject [userID=1, id=1, title=IT, body=123234], MyObject [userID=0, id=2, title=Accounting, body=adsfnsdf]]

1 голос
/ 18 апреля 2020

Вы должны использовать отображаемый объект по умолчанию ниже:

ObjectMapper objectMapper = new ObjectMapper();

, а затем использовать этот объектMapper для достижения желаемого.

Для одного объекта вы можете использовать следующий фрагмент кода для отображение JSON на ваш объект с помощью JACKSON.

YourObject yourObject = (YourObject) mapper.readValue(json, YourObject.class);

Наконец, из-за этого вы спросили: ObjectMapper может отображать JSON для объектов с JACKSON без ошибок.

...