【问题标题】:JAXB - @XMLTransient fields disappear when returned to UIJAXB - 返回 UI 时 @XMLTransient 字段消失
【发布时间】:2023-03-24 20:58:01
【问题描述】:

我的应用程序在后端使用多个 POJO 将数据从后端编组到 UI。数据以字符串形式来自数据库,使用 Jackson 映射到我们的 POJO,然后我们使用 @Produces(MediaType.APPLICATION_JSON) 在 API 调用中返回对象。在将应用程序迁移到 JBoss 7 EAP 时,我们注意到任何标有 @XmlTransient 的字段在返回 UI 时都没有编组为 JSON。 POJO 对象填充了所有字段,但在 UI 端,它们根本不会显示在 JSON 字符串中。示例:

//class POJO
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class FetchDataVO {
  @XmlTransient
  private String Id;

  private String name;

  @XmlTransient
  private String domain;
}

我们的 API 响应如下所示:

@GET
@Path("/{id}")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "getUserById", nickname = "getUserById")
@ApiResponses(value = {
        @ApiResponse(code = 200, message = "Success", response = FetchDataVO.class),
        @ApiResponse(code = 401, message = "Unauthorized"),
        @ApiResponse(code = 403, message = "Forbidden"),
        @ApiResponse(code = 404, message = "Not Found"),
        @ApiResponse(code = 500, message = "Failure")})

public @ResponseBody
    @Valid fetchDataVO getUserById(
            @PathParam("id") String id){


    FetchDataVO fetchVO = callDataBase.getUserById(id);

    //All the data will be present here, everything is correct so far
    log.info("fetchVO contents - " + fetchVO.printDetails());

    return fetchVO;
}

我们的后端代码会打印出所有字段都正确的 POJO。但是,当我们在 UI 中调用它时,我们会看到响应为:

{"name":null}

其他字段甚至不显示。就像我提到的,这只是在由于 JBoss 升级而迁移到 jackson 3.0+ 版本之后发生的。

【问题讨论】:

    标签: java jackson jaxb jax-rs


    【解决方案1】:

    Jackson 能够识别 JAXB 注释来配置序列化/反序列化。

    不幸的是,Wildfly/JBoss JAX-RS 实现 RestEasy 在某些时候默认启用了此功能。因此,如果您的 bean 使用 @XmlRootElement 注释,Jackson 将遵循 @XmlTransient 注释并因此忽略该字段。

    作为禁用它的解决方法,您可以使用 JAX-RS ContextResolver 来配置没有此功能的 Jackson ObjectMapper

    要获得一个简单的ObjectMapper,只需在您的 REST 模块中添加类似这样的内容:

    @Provider
    public class JacksonObjectMapperContextResolver implements ContextResolver<ObjectMapper> {
    
        private final ObjectMapper mapper;
    
        public JacksonObjectMapperContextResolver() {
            mapper = new ObjectMapper();
            // additional configuration here if needed
        }
    
        @Override
        public ObjectMapper getContext(Class<?> type) {
            return mapper;
        }
    
    }
    

    【讨论】:

    • 你能试试吗?
    猜你喜欢
    • 2014-05-17
    • 2014-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多