jakarta-ee - 除了@JsonbIgnore,是否可以要求在 jax-rs (jersey+moxy) JSON 序列化上显式包含对象的字段?

标签 jakarta-ee jersey jax-rs moxy jsonb-api

我有一个实现接口(interface)的 JPA 实体,我想通过 jax-rs 端点仅公开该接口(interface)定义的字段。看起来像的东西:

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方法返回 ConnectedAppExternal响应,Moxy 将序列化整个 JPA 实体及其所有属性,所以我最终要么不得不添加 @JsonbIgnore对于我不想公开的每个新的内部实体字段;或者定义一个只包含暴露的接口(interface)字段的 DTO,这意味着大量的映射和对齐开销(更多代码 => 更多错误/意外泄漏)。
  • 所以:有没有一种简单的方法可以让 Moxy 只序列化这些 ConnectedAppExternal接口(interface)定义的属性 ? (也许我在研究 https://www.eclipse.org/eclipselink/documentation/3.0/moxy/json.htm#sthref204 上的文档并遵循序列化流程时错过了 Moxy marshaller/unmarshaller 配置设置?)

  • (我很确定没有,因为我已经看到了序列化程序代码,但只是要求一个像这样工作的替代方案;)
    ... 也许至少避免要求显式 @JsonbIgnore/@JsonbTransient由于 Moxy 默认使用 getter/setter 序列化每个字段,因此排除未公开的字段,以及 而是需要一个明确的 @JsonbProperty包含要 JSON 序列化/公开的字段 ?

    最佳答案

    作为一种方法,您可以使用所需的数据声明 JPA 投影查询,并从您的资源中返回 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-traffichttps://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

    关于jakarta-ee - 除了@JsonbIgnore,是否可以要求在 jax-rs (jersey+moxy) JSON 序列化上显式包含对象的字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69256293/

    相关文章:

    java - 接受 header 为空或未知时的内容类型

    java - 使用 JAXRS 指定最大深度?

    java - Struts2设置cookie值的正确方法

    java - 如何在 REST Web 服务中使用 json 生成 http 响应?

    eclipse - Jersey :找不到 Java 类和 MIME 媒体类型应用程序/json 的消息正文编写器

    java - 具有 RESTFul API 和静态 Web 的独立 Java 应用程序

    java - Jersey 不遵守@Produces 的响应媒体类型规则

    oracle - 对于 Oracle 应用程序使用哪个 Web 服务器

    java - 错误 404 : css page can't load in JSP

    java - response.sendredirect 在外部应用程序中不起作用