【问题标题】:Java EE 7 Restful Webservice POST method require ID type AutoincrementJava EE 7 Restful Webservice POST 方法需要 ID 类型 Autoincrement
【发布时间】:2013-08-21 14:09:33
【问题描述】:

我正在使用this Tutorial 使用 Netbean 7.3.1 创建简单的 Java EE 7 Web 服务。

它运行成功,我正在使用 GET、PUT、POST、DELETE 进行测试。除了 POST,这三个都工作正常。

我正在发布这个带有 ID 的 json 数据,效果很好。

{"id":"2","address1":"pe3","address2":"address line1","address3":"Address line3","city":"City Name","town":"Town Name","country":"uk","postcode":"123123"}

但是因为我的 ID 是自动递增的,所以当我 POST 跟随没有 id 的 json 时,它会失败并出现以下错误

{"address1":"pe3","address2":"address line1","address3":"Address line3","city":"City Name","town":"Town Name","country":"uk","postcode":"123123"}

错误是

HTTP Status 400 - Bad Request

type Status report

messageBad Request

descriptionThe request sent by the client was syntactically incorrect.
GlassFish Server Open Source Edition 4.0

谁能解释为什么我需要在发送 POST 时发送数据库中自动递增类型的 ID?有什么解决办法吗?

实体类中的代码是

.......
        @Id
        @Basic(optional = false)
        @NotNull
        @Column(name = "id")
        private Integer id;

        @Size(max = 45)
        @Column(name = "address1")
        private String address1;

        @Size(max = 45)
        @Column(name = "address2")
........

AddressFacadeREST.java 类看起来像这样。

package entities.service;

import entities.Address;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;


@Stateless
@Path("entities.address")
public class AddressFacadeREST extends AbstractFacade<Address> {
    @PersistenceContext(unitName = "CustomerDBPU")
    private EntityManager em;

    public AddressFacadeREST() {
        super(Address.class);
    }

    @POST
    @Override
    @Consumes({"application/xml", "application/json"})
    public void create(Address entity) {
        super.create(entity);
    }

    @PUT
    @Override
    @Consumes({"application/xml", "application/json"})
    public void edit(Address entity) {
        super.edit(entity);
    }

    @DELETE
    @Path("{id}")
    public void remove(@PathParam("id") Integer id) {
        super.remove(super.find(id));
    }

    @GET
    @Path("{id}")
    @Produces({"application/xml", "application/json"})
    public Address find(@PathParam("id") Integer id) {
        return super.find(id);
    }

    @GET
    @Override
    @Produces({"application/xml", "application/json"})
    public List<Address> findAll() {
        return super.findAll();
    }

    @GET
    @Path("{from}/{to}")
    @Produces({"application/xml", "application/json"})
    public List<Address> findRange(@PathParam("from") Integer from, @PathParam("to") Integer to) {
        return super.findRange(new int[]{from, to});
    }

    @GET
    @Path("count")
    @Produces("text/plain")
    public String countREST() {
        return String.valueOf(super.count());
    }

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

}

【问题讨论】:

  • 贴出实体id属性的相关代码,以及实体本身的构造函数。

标签: web-services rest jakarta-ee java-ee-7


【解决方案1】:

该错误是由于 jax-rs 服务无法将提供的 json 转换为实体类的实例而产生的。根据 NetBeans 如何创建实体类和服务外观,您的实体类只有一个非空构造函数,并且它需要 id 作为输入参数。此外,@Id 类中有一个 @NotNull 注释。如果是这样:

  • 创建一个构造函数,该构造函数接受除@Id 属性之外的所有实体属性。这样,服务将能够将传入的 json 转换为您的实体类的实例。
  • 删除@NotNull 注释以避免JavaBeans Validator 在持久化新实体时引发错误。

【讨论】:

  • 一旦我删除了 '@NotNull' 和 '@Basic' 注释,没有 POST 的 ID 就可以正常工作。但在进行此更改后,它也接受不带 ID 的 PUT,而不是更新现有记录,而是创建新记录。这是正确的行为吗?
  • PUT 方法创建一个新记录,因为AbstractFacade#edit() 方法使用EntityManager#merge(),如果它不存在,它会创建一个新的对象副本,如here 所述。如果您愿意,您显然可以根据需要修改此行为,即检查是否提供了 ID 并相应地采取行动。
猜你喜欢
  • 2013-08-24
  • 2014-03-29
  • 1970-01-01
  • 2014-12-02
  • 2013-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多