JAXB - @XMLTransient поля исчезают при возврате в пользовательский интерфейс - PullRequest
0 голосов
/ 21 апреля 2020

Мое приложение использует несколько POJO в бэкэнде для маршалинга данных из бэкэнда в пользовательский интерфейс. Данные поступают из БД в виде строки, они сопоставляются с помощью Джексона в наши POJO, а затем мы возвращаем объект в вызове API, используя @Produces(MediaType.APPLICATION_JSON). При переносе приложения в JBoss 7 EAP мы заметили, что любое поле, помеченное @XmlTransient, не переносилось в JSON, когда оно возвращалось в пользовательский интерфейс. В объекте POJO были заполнены все поля, но в конце пользовательского интерфейса они вообще не будут отображаться в строке 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 со всеми правильными полями. Однако, когда мы вызываем его в нашем пользовательском интерфейсе, мы видим ответ:

{"name":null}

Другие поля даже не отображаются. Как я уже упоминал, это произошло только после перехода на версию 3.0 от Jackson из-за обновления JBoss.

1 Ответ

1 голос
/ 25 апреля 2020

Джексон способен распознавать аннотации JAXB для настройки сериализации / десериализации.

К сожалению, в какой-то момент реализация WildE / JBoss JAX-RS, RestEasy, включила эту функцию по умолчанию. Таким образом, если ваш компонент помечен @XmlRootElement, Джексон будет учитывать аннотации @XmlTransient и, следовательно, игнорировать поле.

В качестве обходного пути, чтобы отключить его, вы можете использовать JAX-RS ContextResolver для настройки Джексон 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;
    }

}
...