Подтвердить что ты не робот

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"
        }]
    }
}

Есть ли предлагаемые решения для этого?

4b9b3361

Ответ 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 для реляционного сопоставления объектов.