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

rfs*_*bsb 5 java rest jpa jax-rs 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
}
Run Code Online (Sandbox Code Playgroud)

并说我们有这个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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

我明白,如果我使用杰克逊,我可以设置一个@JsonIgnore我想忽略的字段,它们将永远被忽略.

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

有办法吗?

cas*_*lin 5

@JsonView和混合

你已经知道你可以使用诸如@JsonIgnore和之类的注释@JsonIgnoreProperties来让杰克逊忽略一些属性.

您还可以检查 @JsonView注释.有关如何使用@JsonViewJAX-RS的一些细节,请看这里.

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

数据传输对象

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

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

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

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


Ale*_*rov 3

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

还有一件事。如果您希望一项服务中的事物是动态的,则在另一项服务中返回一种表示形式以返回另一种表示形式。您的选择是编写自定义 JSON 序列化器!查看这篇文章,了解如何创建客户序列化器: How do I use a custom Serializer with Jackson?