java - Джерси: Не найдено подходящего конструктора для типа[простой тип, класс Thing]: невозможно создать экземпляр из объекта JSON




jersey jackson (2)

У меня есть ресурс с таким методом, как:

@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("/add")
public Response putThing(Thing thing) {
    try {
        //Do something with Thing object
        return Response.status(HttpStatus.SC_OK).build();
    } catch (Exception e) {
        log.error("Request failed", e);
        return Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).build();
    }
}

Вещь:

public class Thing {
    private final String symbol;
    private final String name;

    public Stock(String symbol, String name) {
        this.symbol = symbol;
        this.name = name;
    }

    public String getSymbol() {
        return this.symbol;
    }

    public String getName() {
        return this.name;
    }
}

Когда я делаю запрос PUT, например:

PUT /rest/add HTTP/1.1
Host: localhost:8135
Content-Type: application/json
Cache-Control: no-cache

{"symbol":"some symbol","name":"some name"}

Я получаю следующий ответ:

Не найдено подходящего конструктора для типа [simple type, class Thing]: невозможно создать экземпляр из объекта JSON (отсутствующий конструктор или создатель по умолчанию или, возможно, нужно добавить / включить информацию о типе?)

Почему Джерси / Джексон не десериализует мой объект JSON в мой POJO?


Вам нужен конструктор и сеттеры no-arg или используйте @JsonCreator . Легче всего было бы просто добавить no-arg с сеттерами. Джексон нуждается в сеттерах при десериализации. Для сериализации все, что нужно, - это геттеры.

РЕДАКТИРОВАТЬ

Чтобы сохранить его неизменным, вы можете использовать @JsonCreator для конструктора. Например

@JsonCreator
public Thing(@JsonProperty("symbol") String symbol, 
             @JsonProperty("name") String name) {

    this.symbol = symbol;
    this.name = name;
}

Подробнее Джексон Аннотации: @JsonCreator demystified


Я не совсем уверен, но я думаю, что так оно и есть.

То, как Джексон хочет работать, заключается в следующем: он создает объект, используя конструктор по умолчанию (без аргумента). Затем он использует сеттеры для установки каждой из переменных экземпляра. Это может показаться длинным, но это действительно единственный способ, потому что Джексон не может быть достаточно умным, чтобы выяснить, какой порядок передать параметры конструктора. Таким образом, ваш код имеет две основные проблемы (ну, три, но Я собираюсь предположить, что ваш класс назывался Stock, прежде чем вы в основном очистили его для публикации ;-)).
1. Вам нужен конструктор без аргументов. Из того, что я знаю, java предоставляет конструктор по умолчанию, если вы его не пишете, но как только вы создаете какой-либо конструктор, конструктор no-argument по умолчанию уходит.
2. Вам нужны сеттеры для ваших переменных экземпляра (и сделать их общедоступными недостаточно, они должны иметь фактические сеттеры). О, похоже, что ваши переменные экземпляра являются окончательными, это не сработает. Мой любимый способ управлять всеми скопированными / вставленными сеттерами - использовать библиотеку под названием lombok. Во всяком случае, на данный момент вам просто нужны эти сеттеры.





jersey-2.0