Подтвердить что ты не робот

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

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

@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();
    }
}

Thing:

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"}

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

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

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

4b9b3361

Ответ 1

Вам нужен конструктор и сеттеры 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

Ответ 2

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

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