JAX-RSのJersey実装を使用しています。このサービスへの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"
}
答えは驚くほど簡単でした。 Content-Type
の値を持つPOST
リクエストにapplication/json
ヘッダーを追加する必要がありました。このヘッダーがないと、Jerseyは(@Consumes(MediaType.APPLICATION_JSON)
アノテーションにもかかわらず)リクエスト本文をどうするかを知りませんでした!
Jerseyはプロセスを非常に簡単にします。私のサービスクラスは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>
JSONにシリアル化されたオブジェクトをPUT/Pushリクエストを介してJAX-rsサービスに送信するときに、同じ415
httpエラーに直面しました。つまり、サーバーはJSONからオブジェクトを逆シリアル化できませんでした。私の場合、サーバーはJSON内の同じオブジェクトを応答に正常にシリアル化できました。
他の応答で述べたように、Accept
およびContent-Type
ヘッダーをapplication/json
に正しく設定しましたが、十分ではありません。
ソリューション
DTOオブジェクトのパラメーターがないデフォルトのコンストラクターを忘れてしまいました。はい、これは@Entityオブジェクトの背後にある同じ理由です。オブジェクトをインスタンス化し、後でフィールドにデータを入力するには、ORMのパラメーターのないコンストラクターが必要です。
パラメーターなしのコンストラクターをDTOオブジェクトに追加すると、問題が解決しました。次に、私のコードに似た例を示します。
間違った
@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;
}
}
右
@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;
}
}
私は時間を失いました、これがあなたのものを救うことを望みます;-)