Ich verwende die Jersey-Implementierung von JAX-RS. Ich möchte POST ein JSON-Objekt an diesen Dienst senden, erhalte jedoch den Fehlercode 415 Nicht unterstützter Medientyp. Was fehlt mir?
Hier ist mein 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;
}
}
Hier ist das Bestellobjekt:
public class Order {
public int id;
public String side;
public String symbol;
public int quantity;
...
}
Eine solche GET-Anfrage funktioniert einwandfrei und gibt eine Bestellung im JSON-Format zurück:
GET http://localhost:8080/jaxrs-oms/rest/orders/123 HTTP/1.1
Jedoch gibt eine POST Anfrage wie diese eine 415 zurück:
POST http://localhost:8080/jaxrs-oms/rest/orders HTTP/1.1
{
"id": "123",
"symbol": "AAPL",
"side": "Buy",
"quantity": "1000"
}
Die Antwort war überraschend einfach. Ich musste einen Content-Type
- Header in die POST
-Anforderung mit dem Wert application/json
Einfügen. Ohne diesen Header wusste Jersey nicht, was er mit dem Anfragetext tun sollte (trotz der @Consumes(MediaType.APPLICATION_JSON)
Annotation)!
Jersey macht den Prozess sehr einfach, meine Serviceklasse hat gut mit JSON funktioniert, ich musste nur die Abhängigkeiten in die pom.xml einfügen
@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;
}
}
Und in der 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>
Ich stand vor dem gleichen 415
http-Fehler beim Senden von in JSON serialisierten Objekten über PUT/Push-Anforderungen an meine JAX-rs-Dienste. Mit anderen Worten, mein Server konnte die Objekte von JSON nicht de-serialisieren. In meinem Fall konnte der Server dieselben Objekte in JSON erfolgreich serialisieren, als er sie an seine Antworten sendete.
Wie in den anderen Antworten erwähnt, habe ich die Accept
und Content-Type
Header zu application/json
, aber es reicht nicht aus.
Lösung
Ich habe einfach einen Standardkonstruktor ohne Parameter für meine DTO-Objekte vergessen. Ja, dies ist der gleiche Grund für @Entity-Objekte. Sie benötigen einen Konstruktor ohne Parameter, damit der ORM Objekte instanziiert und die Felder später auffüllt.
Das Hinzufügen des Konstruktors ohne Parameter zu meinen DTO-Objekten löste mein Problem. Hier folgt ein Beispiel, das meinem Code ähnelt:
Falsch
@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;
}
}
Rechts
@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;
}
}
Ich habe Stunden verloren, ich hoffe das wird deine retten ;-)