Java.util.Map к объекту JSON с Джерси/JAXB/Jackson
Я пытаюсь создать веб-сервис службы REST на Джерси. Я хочу получать и выделять объекты JSON из классов Java, например:
@XmlRootElement
public class Book {
public String code;
public HashMap<String, String> names;
}
Это должно быть преобразовано в JSON следующим образом:
{
"code": "ABC123",
"names": {
"de": "Die fabelhafte Welt der Amelie",
"fr": "Le fabuleux destin d'Amelie Poulain"
}
}
Однако я не могу найти стандартное решение для этого. Кажется, что все реализуют свою собственную обертку решение. Это требование для меня кажется чрезвычайно основным; Я не могу поверить, что это общепринятое решение для этого, тем более, что Джерси - действительно одна из наиболее интересных частей Java.
Я также попробовал обновить до Jackson 1.8, который только дает мне это, что крайне неудобно JSON:
{
"code": "ABC123",
"names": {
"entry": [{
"key": "de",
"value": "Die fabelhafte Welt der Amelie"
},
{
"key": "fr",
"value": "Le fabuleux destin d'Amelie Poulain"
}]
}
}
Есть ли предлагаемые решения для этого?
Ответы
Ответ 1
Я не знаю, почему это не значение по умолчанию, и мне потребовалось некоторое время выяснить это, но если вы хотите работать с JSON-конверсией с Джерси, добавьте
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
в ваш web.xml, и все ваши проблемы должны быть решены.
PS: вам также нужно избавиться от аннотаций @XmlRootElement
, чтобы заставить его работать
Ответ 2
Вы можете использовать google-gson. Вот пример кода:
@Test
public void testGson(){
Book book = new Book();
book.code = "1234";
book.names = new HashMap<String,String>();
book.names.put("Manish", "Pandit");
book.names.put("Some","Name");
String json = new Gson().toJson(book);
System.out.println(json);
}
Выходной сигнал {"code":"1234","names":{"Some":"Name","Manish":"Pandit"}}
Ответ 3
Я знаю, что это было спрошено давно, но все изменилось в среднем, поэтому для последнего Джерси v2.22, у которого больше нет пакета com.sun.jersey, эти две зависимости добавлены в проект pom.xml решил ту же проблему:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.22</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.5.4</version> <!-- jackson version used by jersey v2.22 -->
</dependency>
Не нужно ничего добавлять в web.xml.
Первая зависимость будет давать указание джерси использовать джексон для преобразования POJO в JSON.
Вторая зависимость будет регистрировать Джексона в качестве поставщика JSON в Джерси.
Также для нулевой задачи в POJO добавьте эту аннотацию в класс POJO:
@JsonInclude(JsonInclude.Include.NON_NULL)
Ответ 4
@POST
@Consumes("application/json")
public void createBook(Book book)
{
.....
.....
}
Конечно, вам нужно иметь getter/setter для каждого свойства в книге.
Также причина, по которой рекомендуется использовать класс-оболочку (обычно это карта), заключается в том, чтобы избежать создания нескольких DTO для всех типов данных, которые вы хотите отправить. Легче просто сериализовать/десериализовать с помощью карты и как часть бизнес-логики преобразовать ее в соответствующий POJO для внутренней обработки, особенно если вы используете это POJO для реляционного сопоставления объектов.