Java.util.Map для JSON Object с Джерси / JAXB / Джексон - PullRequest
25 голосов
/ 26 апреля 2011

Я пытался создать веб-сервис 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"
        }]
    }
}

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

Ответы [ 4 ]

24 голосов
/ 12 мая 2011

Я не знаю, почему это не настройка по умолчанию, и мне потребовалось некоторое время, чтобы выяснить это, но если вы хотите работать с преобразованием JSON с Джерси, добавьте

    <init-param>
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>

на ваш web.xml и все ваши проблемы должны быть решены.

PS: вам также нужно избавиться от @XmlRootElement аннотаций, чтобы он работал

7 голосов
/ 26 апреля 2011

Вы можете использовать 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"}}

4 голосов
/ 25 мая 2016

Я знаю, что об этом уже давно спрашивали, но все изменилось со временем, поэтому для последней версии Jersey 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)
0 голосов
/ 11 мая 2011
@POST
@Consumes("application/json")
public void createBook(Book book)
{
 .....
 .....
}

Конечно, вам нужно иметь getter / setter для каждого свойства в Book.

Кроме того, причина, по которой рекомендуется использовать класс-оболочку (обычно это карта), состоит в том, чтобы избежать создания нескольких DTO для каждого типа данных, которые вы хотите отправить. Проще всего сериализовать / десериализовать, используя карту, и, как часть бизнес-логики, преобразовать ее в соответствующий POJO для внутренней обработки, особенно если вы используете этот POJO для реляционного отображения объектов.

...