除了@JsonbIgnore,是否可以要求在 jax-rs (jersey+moxy) JSON 序列化中显式包含对象的字段?
Instead of @JsonbIgnore, is it possible to require explicit inclusion of an object's fields on jax-rs (jersey+moxy) JSON serialization?
我有一个实现接口的 JPA 实体,我想通过 jax-rs 端点仅公开该接口定义的字段。看起来像的东西:
public interface ConnectedAppExternal {
String getId();
String getName();
}
@Entity(name="connected_application")
public class ConnectedApp implements ConnectedAppExternal {
@Id
@Column(name="id")
private id;
@Column(name="name")
private String name;
@Column(name="internal_status")
private String internalStatus;
...
@Override
public String getId(){
return this.id;
}
@Override
public String getName(){
return this.name;
}
public String getInternalStatus(){
return this.internalStatus;
}
public void setId(String id){
this.id = id;
}
public void setName(String name){
this.name = name;
}
public void setInternalStatus(String internalStatus){
this.internalStatus= internalStatus;
}
...
}
@Path("/applications")
public class ConnectedAppResource {
@Inject
ConnectedAppService appService;
...
@GET("applications/{id}")
@Produces("application/json")
public ConnectedAppExternal getConnectedApplication(@PathParam("id") String id){
return appService.getAppById(id);
}
...
}
即使我使我的 jax-rs 资源 @GET
方法 return 成为 ConnectedAppExternal
响应,Moxy 也会使用 all[=39 序列化整个 JPA 实体=] 它的属性,所以我最终不得不将 @JsonbIgnore
添加到我不想公开的每个新的内部实体字段;或者定义一个仅包含公开接口字段的 DTO,这意味着大量映射和对齐开销(更多代码 => 更多错误/意外泄漏)。
- 所以:有没有一种简单的方法可以让 Moxy 仅序列化这些
ConnectedAppExternal
接口定义的属性? (也许我在研究 https://www.eclipse.org/eclipselink/documentation/3.0/moxy/json.htm#sthref204 上的文档并遵循序列化程序流程时错过了 Moxy marshaller/unmarshaller 配置设置?)
(我很确定没有,因为我已经看到了序列化程序代码,但只是要求一个像这样工作的替代方案;)
...或 或许至少可以避免要求明确 @JsonbIgnore
/@JsonbTransient
排除非- 由于 Moxy 默认使用 getter/setter 序列化每个字段而暴露字段,而 需要显式 @JsonbProperty
包含字段才能成为 JSON序列化/暴露?
作为一种方法,您可以使用资源中的所需数据和 return Map 类型声明 JPA 投影查询。像这样的东西:
@NamedQueries({
@NamedQuery(name="ConnectedApp.findByName",
query="SELECT c.id, c.internalStatus FROM ConnectedApp c WHERE c.name = :name")
})
参见:https://dzone.com/articles/projection-queries-a-way-to-optimize-data-traffic or https://www.objectdb.com/java/jpa/query/named
另一种方法是使用 Jsonb 仅序列化必需的属性,有点像这样:
@GET
@Path("applications/{id}")
@Produces(MediaType.APPLICATION_JSON)
public String getApp(@PathParam("id") String id) {
JsonbConfig config = new JsonbConfig().withPropertyVisibilityStrategy(
new PropertyVisibilityStrategy(){
@Override
public boolean isVisible(Field field) {
return List.of("id", "name").indexOf(field.getName()) != -1;
}
@Override
public boolean isVisible(Method method) {
return false;
}
});
Jsonb jsonb = JsonbBuilder.newBuilder().withConfig(config).build();
return jsonb.toJson(appService.getAppById(id));
}
请在此处查找示例:https://adambien.blog/roller/abien/entry/private_fields_serialization_with_json
我有一个实现接口的 JPA 实体,我想通过 jax-rs 端点仅公开该接口定义的字段。看起来像的东西:
public interface ConnectedAppExternal {
String getId();
String getName();
}
@Entity(name="connected_application")
public class ConnectedApp implements ConnectedAppExternal {
@Id
@Column(name="id")
private id;
@Column(name="name")
private String name;
@Column(name="internal_status")
private String internalStatus;
...
@Override
public String getId(){
return this.id;
}
@Override
public String getName(){
return this.name;
}
public String getInternalStatus(){
return this.internalStatus;
}
public void setId(String id){
this.id = id;
}
public void setName(String name){
this.name = name;
}
public void setInternalStatus(String internalStatus){
this.internalStatus= internalStatus;
}
...
}
@Path("/applications")
public class ConnectedAppResource {
@Inject
ConnectedAppService appService;
...
@GET("applications/{id}")
@Produces("application/json")
public ConnectedAppExternal getConnectedApplication(@PathParam("id") String id){
return appService.getAppById(id);
}
...
}
即使我使我的 jax-rs 资源 @GET
方法 return 成为 ConnectedAppExternal
响应,Moxy 也会使用 all[=39 序列化整个 JPA 实体=] 它的属性,所以我最终不得不将 @JsonbIgnore
添加到我不想公开的每个新的内部实体字段;或者定义一个仅包含公开接口字段的 DTO,这意味着大量映射和对齐开销(更多代码 => 更多错误/意外泄漏)。
- 所以:有没有一种简单的方法可以让 Moxy 仅序列化这些
ConnectedAppExternal
接口定义的属性? (也许我在研究 https://www.eclipse.org/eclipselink/documentation/3.0/moxy/json.htm#sthref204 上的文档并遵循序列化程序流程时错过了 Moxy marshaller/unmarshaller 配置设置?)
(我很确定没有,因为我已经看到了序列化程序代码,但只是要求一个像这样工作的替代方案;)
...或 或许至少可以避免要求明确 @JsonbIgnore
/@JsonbTransient
排除非- 由于 Moxy 默认使用 getter/setter 序列化每个字段而暴露字段,而 需要显式 @JsonbProperty
包含字段才能成为 JSON序列化/暴露?
作为一种方法,您可以使用资源中的所需数据和 return Map
@NamedQueries({
@NamedQuery(name="ConnectedApp.findByName",
query="SELECT c.id, c.internalStatus FROM ConnectedApp c WHERE c.name = :name")
})
参见:https://dzone.com/articles/projection-queries-a-way-to-optimize-data-traffic or https://www.objectdb.com/java/jpa/query/named
另一种方法是使用 Jsonb 仅序列化必需的属性,有点像这样:
@GET
@Path("applications/{id}")
@Produces(MediaType.APPLICATION_JSON)
public String getApp(@PathParam("id") String id) {
JsonbConfig config = new JsonbConfig().withPropertyVisibilityStrategy(
new PropertyVisibilityStrategy(){
@Override
public boolean isVisible(Field field) {
return List.of("id", "name").indexOf(field.getName()) != -1;
}
@Override
public boolean isVisible(Method method) {
return false;
}
});
Jsonb jsonb = JsonbBuilder.newBuilder().withConfig(config).build();
return jsonb.toJson(appService.getAppById(id));
}
请在此处查找示例:https://adambien.blog/roller/abien/entry/private_fields_serialization_with_json