如何将 JSON 对象 POST 到 JAX-RS 服务

发布于 2024-12-09 04:00:15 字数 1174 浏览 1 评论 0原文

我正在使用 JAX-RS 的 Jersey 实现。我想将 JSON 对象发布到此服务,但收到错误代码 415 不支持的媒体类型。我缺少什么?

这是我的代码:

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

I am using the Jersey implementation of JAX-RS. I would like to POST a JSON object to this service but I am getting an error code 415 Unsupported Media Type. What am I missing?

Here's my 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;
    }
}

Here's the Order object:

public class Order {
    public int id;
    public String side;
    public String symbol;
    public int quantity;
    ...
}

A GET request like this works perfectly and returns an order in JSON format:

GET http://localhost:8080/jaxrs-oms/rest/orders/123 HTTP/1.1

However a POST request like this returns a 415:

POST http://localhost:8080/jaxrs-oms/rest/orders HTTP/1.1

{
    "id": "123",
    "symbol": "AAPL",
    "side": "Buy",
    "quantity": "1000"
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

彼岸花ソ最美的依靠 2024-12-16 04:00:15

答案出奇的简单。我必须在 POST 请求中添加一个 Content-Type 标头,其值为 application/json。如果没有这个标头,Jersey 不知道如何处理请求正文(尽管有 @Consumes(MediaType.APPLICATION_JSON) 注释)!

The answer was surprisingly simple. I had to add a Content-Type header in the POST request with a value of application/json. Without this header Jersey did not know what to do with the request body (in spite of the @Consumes(MediaType.APPLICATION_JSON) annotation)!

与酒说心事 2024-12-16 04:00:15

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>

Jersey makes the process very easy, my service class worked well with JSON, all I had to do is to add the dependencies in the 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;
    }
}

And in the 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>
晨光如昨 2024-12-16 04:00:15

通过对 JAX-rs 服务的 PUT/PUSH 请求发送序列化为 JSON 的对象时,我遇到了相同的 415 http 错误,换句话说,我的服务器无法从 JSON 反序列化对象。
就我而言,服务器在将相同对象发送到其响应中时能够成功序列化 JSON 中的相同对象。

正如其他响应中提到的,我已将 AcceptContent-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;
    }
}

我损失了几个小时,我希望这会节省您的时间;-)

I faced the same 415 http error when sending objects, serialized into JSON, via PUT/PUSH requests to my JAX-rs services, in other words my server was not able to de-serialize the objects from JSON.
In my case, the server was able to serialize successfully the same objects in JSON when sending them into its responses.

As mentioned in the other responses I have correctly set the Accept and Content-Type headers to application/json, but it doesn't suffice.

Solution

I simply forgot a default constructor with no parameters for my DTO objects. Yes this is the same reasoning behind @Entity objects, you need a constructor with no parameters for the ORM to instantiate objects and populate the fields later.

Adding the constructor with no parameters to my DTO objects solved my issue.
Here follows an example that resembles my code:

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

I lost hours, I hope this'll save yours ;-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文