指定服务返回的字段的最佳方法 [英] Best way to specify fields returned by a Service

查看:184
本文介绍了指定服务返回的字段的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在使用Java EE 7和WildFly 9来开发移动/ Web应用程序的自定义后端。后端是一个经典的3层系统,具有通信逻辑(JAX-RS),业务逻辑(会话EJB)和持久层(Hibernate)。

We're using Java EE 7 with WildFly 9 to develop the custom backend for a mobile/web application. The backend is a classic 3-tier system, with communication logic (JAX-RS), business logic (Session EJBs) and persistence layer (Hibernate).

业务逻辑layer由一组服务组成,每个服务由接口和EJB实现定义。我们假设

The business logic layer is composed by a set of services, each defined by an interface and an EJB implementation. Let's suppose

public interface IPostService {
    List<PostDTO> getAllPosts();
}

@Stateless
public class PostService implements IPostService {
    List<PostDTO> getAllPosts(){
    // retrieving my Posts through Hibernate
    }

public class PostDTO {

    private Long id;
    private String title;
    // UserDTO is a VEEERY big object
    private UserDTO author;

    // getters and setters
}

我们假设有时,客户只对帖子 id title 感兴趣。 API端点将接收一个查询参数,其中包含要获取的字段列表。因此,JSON序列化的DTO应仅包含post id title 。目标是避免不必要的处理,以便在不需要时加载非常大的 UserDTO 对象。

Let's suppose that, sometimes, the clients are interested only in post id and title. The API endpoint will receive a query parameter with the list of fields to be fetched. So, the JSON-serialized DTO should contains only post id and title. The goal is to avoid unnecessary processing in order to load the very big UserDTO object when it is not required.

一个天真的解决方案是添加自定义 List< String> desiredFields 参数到 getAllPosts()。这并不能说服我,因为我们需要将此参数添加到几乎每个服务方法。

A naive solution is to add a custom List<String> desiredFields parameter to getAllPosts(). This doesn't quite convince me, since we need to add this parameter to almost every service method.

要做的最佳做法是什么那?是否有用于此目的的Java EE对象?

What is the best practices to do that? Are there Java EE object intended to this purpose?

推荐答案

通过直接返回一个唯一的模型类实例,让我们说 Post 而不是PostDTO,结合JPA和JAXB注释,您可以从 @ XmlTransient 和默认延迟加载,以避免在不需要时在持久层中查询用户实体,并从RESTful Web服务层隐藏此属性。

By returning directly a unique model class instance, let's say Post instead of PostDTO, combining JPA and JAXB annotations, you could benefit from @XmlTransient and default lazy loading to avoid to query User entity in persistence layer when not necessary, and to hide this property from RESTful web service layer.

我个人用它来做很多事情,因为它通过减少层和映射(entity / dto)简化了应用程序代码。有关详细信息,请参见这些幻灯片

I personnaly use to do that a lot as it simplifies application code by reducing layers and mappings (entity / dto). See these slides for details.

我认为它非常适合CRUD操作,它是一个纯Java EE 7解决方案。不需要使用额外的库。

I think it's perfectly suited for CRUD operations and it's a pure Java EE 7 solution. No need to use extra libs.

Post.java看起来像这样:

Post.java would look like this:

import javax.persistence.*;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

@Entity
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Post {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String title;

    @XmlTransient
    @ManyToOne
    private User persistedAuthor;

    @Transient
    private User author;

    // + Getters and Setters ...

}

PROS:


  • 没有DTO /实体映射来测试,编码和维护

  • 只有一个模型层可以放置持久性/业务/验证规则

  • Java EE 7解决方案,无需使用额外的库

缺点:


  • 您的模型与JPA联系在一起。因此,如果您更改持久性解决方案并且不允许管理多个不同的持久层,则需要对其进行修改

编辑

有时您想要获取作者,假设您在REST操作中将示例的QueryParam fetchAuthor设置为true / false,则需要在该模型中添加额外的JPA @Transient 属性诸如 author 之类的对象,并在需要时对其进行初始化。所以它是Post java类中的额外映射,但是你保持了上面提到的优点的好处。要初始化author属性,您只需使用getPersistedAuthor()返回的值设置它(这将触发查询以获取延迟加载的持久作者)。

As sometimes you want to get the author, assuming you have a QueryParam fetchAuthor set to true/false for sample in your REST operation, you would need to add an extra JPA @Transient property in that model objet such as author and initialize it when needed. So it's an extra mapping in Post java class, but you keep however the benefit of advantages mentioned above. To initialize author property, you just have to set it with the getPersistedAuthor() returned value (which will trigger a query to get the persisted author with lazy loading).

这篇关于指定服务返回的字段的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆