Как POST объект JSON для службы JAX-RS
Я использую реализацию JAX-RS в Джерси. Я хотел бы POST объект JSON для этой службы, но я получаю код ошибки 415 Unsupported Media Type. Что мне не хватает?
Здесь мой код:
@Path("/orders")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class OrderResource {
private static Map<Integer, Order> orders = new HashMap<Integer, Order>();
@POST
public void createOrder(Order order) {
orders.put(order.id, order);
}
@GET
@Path("/{id}")
public Order getOrder(@PathParam("id") int id) {
Order order = orders.get(id);
if (order == null) {
order = new Order(0, "Buy", "Unknown", 0);
}
return order;
}
}
Здесь объект Order:
public class Order {
public int id;
public String side;
public String symbol;
public int quantity;
...
}
Запрос GET, подобный этому, отлично работает и возвращает порядок в формате JSON:
GET http://localhost:8080/jaxrs-oms/rest/orders/123 HTTP/1.1
Однако такой запрос POST возвращает 415:
POST http://localhost:8080/jaxrs-oms/rest/orders HTTP/1.1
{
"id": "123",
"symbol": "AAPL",
"side": "Buy",
"quantity": "1000"
}
Ответы
Ответ 1
Ответ был на удивление прост. Мне пришлось добавить заголовок Content-Type
в запрос POST
со значением application/json
. Без этого заголовка Джерси не знал, что делать с телом запроса (несмотря на аннотацию @Consumes(MediaType.APPLICATION_JSON)
)!
Ответ 2
Джерси делает процесс очень простым, мой класс обслуживания хорошо работал с JSON, все, что мне нужно было сделать, это добавить зависимости в pom.xml
@Path("/customer")
public class CustomerService {
private static Map<Integer, Customer> customers = new HashMap<Integer, Customer>();
@POST
@Path("save")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public SaveResult save(Customer c) {
customers.put(c.getId(), c);
SaveResult sr = new SaveResult();
sr.sucess = true;
return sr;
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("{id}")
public Customer getCustomer(@PathParam("id") int id) {
Customer c = customers.get(id);
if (c == null) {
c = new Customer();
c.setId(id * 3);
c.setName("unknow " + id);
}
return c;
}
}
И в pom.xml
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.7</version>
</dependency>
Ответ 3
Я столкнулся с той же ошибкой 415
http при отправке объектов, сериализованных в JSON, через PUT/PUSH-запросы к моим службам JAX-rs, другими словами, мой сервер не смог де-сериализовать объекты из JSON.
В моем случае серверу удалось успешно сериализовать те же объекты в JSON при отправке их в свои ответы.
Как упоминалось в других ответах, я правильно установил заголовки Accept
и Content-Type
в application/json
, но этого недостаточно.
Решение
Я просто забыл конструктор по умолчанию без параметров для моих объектов DTO. Да, это та же самая причина для объектов @Entity, вам нужен конструктор без параметров для ORM для создания объектов и заполнения полей позже.
Добавление конструктора без параметров к моим объектам DTO решило мою проблему.
Ниже приведен пример, похожий на мой код:
Wrong
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class NumberDTO {
public NumberDTO(Number number) {
this.number = number;
}
private Number number;
public Number getNumber() {
return number;
}
public void setNumber(Number string) {
this.number = string;
}
}
Right
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class NumberDTO {
public NumberDTO() {
}
public NumberDTO(Number number) {
this.number = number;
}
private Number number;
public Number getNumber() {
return number;
}
public void setNumber(Number string) {
this.number = string;
}
}
Я потерял часы, надеюсь, это спасет вас, -)