[英]Preventing infinite recursion in JAX-RS on JPA Entity Serialization (JSON) (without using Jackson annotations)
[英]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个字段?
有办法吗?
您已经知道可以使用@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.