J'utilise l'implémentation Jersey de JAX-RS. Je souhaite POST un objet JSON associé à ce service, mais le code d'erreur 415 correspondant au type de support non pris en charge est atteint. Que me manque-t-il?
Voici mon code:
@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;
}
}
Voici l'objet Order:
public class Order {
public int id;
public String side;
public String symbol;
public int quantity;
...
}
Une requête GET comme celle-ci fonctionne parfaitement et renvoie une commande au format JSON:
GET http://localhost:8080/jaxrs-oms/rest/orders/123 HTTP/1.1
Cependant, une demande POST) retourne un 415:
POST http://localhost:8080/jaxrs-oms/rest/orders HTTP/1.1
{
"id": "123",
"symbol": "AAPL",
"side": "Buy",
"quantity": "1000"
}
La réponse était étonnamment simple. J'ai dû ajouter un en-tête Content-Type
Dans la demande POST
avec une valeur de application/json
. Sans cet en-tête, Jersey ne savait pas quoi faire avec le corps de la requête (malgré l'annotation @Consumes(MediaType.APPLICATION_JSON)
)!
Jersey rend le processus très facile, ma classe de service a bien fonctionné avec JSON, tout ce que je devais faire était d’ajouter les dépendances dans le fichier 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;
}
}
Et dans le 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>
J'ai fait face au même 415
_ Erreur http lors de l'envoi d'objets sérialisés en JSON via des requêtes PUT/Push à mes services JAX-rs, autrement dit, mon serveur n'a pas été en mesure de désérialiser les objets à partir de JSON. Dans mon cas, le serveur a réussi à sérialiser les mêmes objets en JSON lors de leur envoi dans ses réponses.
Comme indiqué dans les autres réponses, j'ai correctement défini les paramètres Accept
et Content-Type
en-têtes à application/json
, mais cela ne suffit pas.
Solution
J'ai simplement oublié un constructeur par défaut sans paramètre pour mes objets DTO. Oui, c'est le même raisonnement derrière les objets @Entity, vous avez besoin d'un constructeur sans paramètre pour que l'ORM instancie les objets et remplisse les champs ultérieurement.
L'ajout du constructeur sans paramètre à mes objets DTO a résolu mon problème. Voici un exemple qui ressemble à mon code:
mauvais
@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;
}
}
Droite
@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;
}
}
J'ai perdu des heures, j'espère que cela sauvera le vôtre ;-)