Ответ 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
,