繁体   English   中英

使用JAX-RS和Jackson将JPA实体转换为REST表示的最佳方法

[英]Best way to convert a JPA entity to REST representations using JAX-RS and Jackson

我正在寻找一种方法将一些JPA实体导出到REST API,但是每次我想根据入口点分享一些特定的字段时,不是发送整个实体。 这是一个小例子:

假设我们有一个包含很少字段的Author类:

@Entity
public class Author implements Serializable{

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = SEQUENCE)
    private Long id;

    @NotNull
    @Size(min = 1, message = "{required.field}")
    private String name;

    @NotNull
    @Size(min = 1, message = "{required.field}")
    private String country;

    private LocalDate birthDate;

    // getters and setters
}

并说我们有这个REST服务(只有两种方法):

@Path("authors")
public class AuthorREST {

    @Inject
    private AuthorBC bc;

    @GET
    @Produces("application/json")
    public List<Author> find(@QueryParam("q") String query) throws Exception {

        List<Author> result;

        if (Strings.isEmpty(query)) {
            result = bc.findAll();
        } else {
            result =  bc.find(query);
        }
        return result;
    }

    @GET
    @Path("{id}")
    @Produces("application/json")
    public Author load(@PathParam("id") Long id) throws Exception {

        Author result = bc.load(id);

        if (result == null) {
            throw new NotFoundException();
        }

        return result;
    }
}

现在,通过这种方式,调用API时,我将始终拥有4个字段。

我知道如果我使用Jackson,我可以将@JsonIgnore设置为我想忽略的字段,并且它们将始终被忽略。

但是如果我想要这样,在某些情况下,我的整个实体由一个服务返回,而在其他服务(或同一服务中的其他方法)中,只返回2或3个字段?

有办法吗?

@JsonView和混合

您已经知道可以使用@JsonIgnore@JsonIgnoreProperties等注释来使Jackson忽略某些属性。

您还可以检查@JsonView注释。 有关如何将@JsonView与JAX-RS一起使用的一些细节,请查看此处

如果不能修改JPA实体,请考虑本答案中描述的混合注释。

数据传输对象

D ata T ransfer O bject (DTO)是一种用非常明确的目的创建的模式: 将数据传输到远程接口 ,就像webservices一样。 这种模式非常适合REST API和使用DTO,从长远来看,您将拥有更大的灵活性 一旦REST资源表示不需要与持久性对象具有相同的属性,您就可以根据需要定制类。

为避免样板代码,您可以使用映射框架(如MapStruct)将REST API DTO映射到/到持久性对象。

有关使用DTO的好处的详细信息,请检查以下答案:

要为您的DTO提供更好的名称,请检查以下答案:

如果要将解析与JPA实体分离并仅返回某些属性,则可以始终将Mixins用于此目的。 http://www.cowtowncoder.com/blog/archives/2009/08/entry_305.html https://github.com/FasterXML/jackson-docs/wiki/JacksonMixInAnnotations

还有一件事。 如果您希望事物在一个服务中是动态的,则在另一个服务中返回一个表示以返回另一个表示。 您的选择是编写自定义JSON序列化程序! 查看此帖子了解如何创建客户序列化程序: 如何在Jackson中使用自定义Serializer?

对于我自己,我发现它非常适合使用@JsonView注释。 因此,您可以定义要在特定视图中呈现的字段。 您可以在http://wiki.fasterxml.com/JacksonJsonViews找到更多信息

我认为您可以使用Jersey框架编写自定义MessageBodyWriter,您可以按照自己的方式控制响应有效负载。 在这里,您必须编写几行代码才能管理响应有效负载。 欲了解更多信息,请访问https://jersey.java.net/documentation/latest/message-body-workers.html#d0e6826

我将使用Spring Data REST,然后使用ApiModel注释来隐藏您不想暴露的属性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM