Ответ WildFly против Payara JSON - что такое стандартное поведение?

В небольшом демонстрационном приложении JAX-RS у меня было следующее POJO:

public class Book {
    private String title;
    private String author;
    private int year;

    // only this constructor, no default
    public Book(String title, String author, int year) {
        this.title = title;
        this.author = author;
        this.year = year;
    }

    // getters for members, no setters
    ...
}

Я использовал это как ответ в операции REST:

@GET
@Path("books")
@Produces(MediaType.APPLICATION_JSON)
public List<Book> getBooks() {
    List<Book> books = new ArrayList<>();
    // add some books via Book constructor
    ...
    return books;
}

Приложение отлично работало на WildFly 10, создавая JSON-вывод объектов book.

Та же самая война, развернутая на недавней Payara, дала мне исключение в журнале сервера:

MessageBodyWriter not found for media type=application/json

После добавления конструктора по умолчанию и @XmlAccessorType(XmlAccessType.FIELD) (или сеттеры, которые я опускал по причинам функционального дизайна), это работало.

Все это привело меня к 2 вопросам:

  • Почему поведение отличается и какой контейнер делает что-то нестандартное или дополнительно?
  • Есть ли рекомендуемый способ использования объектов данных, таких как мой класс Book, в качестве ответов, и позволить ему автоматически преобразовывать в JSON (с, конечно, дополнительным http-кодом ответа) или как это показано во многих примерах вместо создания объекта ответа JSON вручную?

1 ответ

Решение

К сожалению, отображение Java-объектов в / из JSON еще не определено в Java EE, поэтому поведение WildFly и Payara Server по определению не является стандартным. Его планируется определить с помощью JSON-Binding JSR, который будет включен в Java EE 8. Большинство реализаций сейчас используют JAX-B для отображения, но оно было разработано для отображения между Java и XML и не работает без проблем для JSON.

По умолчанию Payara Server использует Moxy для сопоставления с JSON. Например, вы можете принудительно использовать Джексона, если добавите Джексона в свое приложение и добавите JacksonFeature в классы JAX-RS: заставьте Glassfish4 использовать Джексона вместо Мокси

Если вы хотите, чтобы ваше приложение все время работало стандартно, вам нужно настроить JAX-RS на использование вашего собственного MessageBodyWriter/Reader,

Другие вопросы по тегам