jakarta-ee - JAX-RS/实体最佳实践

标签 jakarta-ee jpa jaxb jax-rs

在我的项目中,我使用 JAX-RS 将一些实体公开给 JavaScript 前端框架 (AngularJS)。

我不想急切地加载我的实体关系,而我宁愿有多种方法来获取客户端需要的任何关系。

为了将我的实体序列化为 JSON/XML,我使用 JAXB 并将关系的 id 添加到类中。现在,我的实体既是实体又是 DTO。

在每个 POST 中,我需要重新设置实体的引用。

我想知道这是否是公开实体的适当方法或者是否有更好的方法?

一个总是比长文本更清晰的示例,如下:

@XmlRootElement
@Entity
public class Country {
    @Id
    @GeneratedValue
    private Integer id;

    private String countryName;

    @ManyToOne
    private Region region;

    @Transient
    private Integer regionId;

    // getters & setters

    // AVOID SERIALIZING REGION
    @XmlTransient
    public Region getRegion ...

    // SERIALIZE REGION ID INSTEAD
    public Integer getRegionId() {
        if (region != null)
            return region.getId();
        else
            return null;
    }

    ...

}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@Entity
public class Region {
    @Id
    @GeneratedValue
    private Integer id;

    private String regionName;

    // getters & setters

    ...

}

@Stateless
@Path("countries")
public class CountryResource {

    @PersistenceContext
    private EntityManager em;

    @GET
    public List<Country> getAll() {
        return em.createNamedQuery("Country.findAll", Country.class).getResultList();
    }

    @PUT
    public void saveCountry saveCountry(Country country) {
        // UPDATE REFERENCES
        country.setRegion(em.getReference(Region.class, country.getRegionId()));
        em.persist(country);
    }

}

你还有其他建议吗?

谢谢

FD

最佳答案

我发现使用 DTO pattern 通常是个好主意作为“反腐败层”和一种用于 Web 请求/响应主体的已发布 API。

例如,让我们来学习乡村类(class)。如果您的 Web API 直接发送 Country 类(直接序列化为 JSON),则您会公开 Web API 的使用者可能不应该知道的部分应用程序代码,以防止他们编写与容易出现问题的点相关的代码。改变。

因此,您构建了一个“属性包”类,它作为 Web API 使用者和协作者应使用的通用“语言”的表示而存在。

例如:

public class CountryDTO {
    public final Integer id;
    public final String countryName;
    public final Integer regionId;

    public CountryDTO(Country countryToSerialize){
        this.id = countryToSerialize.getId();
        this.countryName = countryToSerialize.getCountryName();
        this.regionId = countryToSerialize.getRegion().getId();
    }
}

这样,如果将来您更改 Country 类的结构,您的 API 使用者仍然会看到相同的一致数据“形状”(直到您弃用/升级/根据您的版本控制实践进行选择)。

您还可以对域对象的序列化方式进行细粒度、与库无关的控制,因为您可以选择使用哪些字段。

最后,您不必担心从请求中提取实体对象,也不必担心 ORM 在您将它们传递到应用程序代码时是否认为它们是附加的/未附加的/ transient 的/任何东西。然后,您可以在实例化域实体之前根据严格 transient DTO 自由添加验证步骤。

关于jakarta-ee - JAX-RS/实体最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25608871/

相关文章:

java - getResourceAsStream 没有在 webapp 中加载资源

jakarta-ee - 如何在 EJB/MDB 调用期间更改用户主体?

java - JSP EL/Apache Tiles --- 返回对象具有组合键

java - JPA调用存储过程从2 db中选择数据

java - 由JBoss Wildfly和JPA注入(inject)中的: java. lang.NullPointerException引起

java - SOAP消息无法解析为java对象

java - 在 JAXB 中编码时如何避免根元素注释?

java - GWT 和 Hibernate - 使用 Hibernate 时出现 NoClassDefFoundError

Playframework 中的日期

java - 根据对象属性动态定义XML标签