Маршалинг JSON и обобщений в Java с помощью Spring MVC - PullRequest
11 голосов
/ 21 июля 2011

Я пытаюсь маршалировать объект JSON в класс-оболочку, который содержит универсальный объект, а также дополнительную информацию о сигнатуре объекта.

public class Signable<T> {

    private T object;
    private String signature;

    public class Signable() {
       generateSignature();
    }

    /* Getters and setters  */
}

Класс-оболочка работает нормально, пока ясоздайте его с уже созданным объектом, и он сможет создать желаемый json

@RequestMapping(value="/test/json/return",method=RequestMethod.GET)
public @ResponseBody Signable<Cart> getTest()
{
    Cart cart = new Cart();
    // populate cart with OrderItems ...
    Signable<Cart> sign = new Signable<Cart>();
    sign.setObject(cart);
    return sign;
}

, способный генерировать ожидаемый вывод

{
   "object":{
        "orderItems":[
              {
                  "id": "****",
                  "desc": "asdlfj",
                  "price": 25.53
              }
        ]
   },
   "signature":"s9d94f9f9gdfg67d8678g6s87d6f7g6";
}

Какой формат мне нужен.Однако при попытке маршалировать тот же самый json, сгенерированный из Signable, обратно в Signable, я получаю следующую ошибку:

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to Cart

По какой-то причине невозможно определить, что «объект» в json должен отображаться натип Cart (по умолчанию это LinkedHashMap), даже если он указан в заголовке метода.

@RequestMapping(value="/test/json/post",method=RequestMethod.POST)
public @ResponseBody Signable<Cart> postTest(@RequestBody Signable<Cart> sign)

Есть ли способ явно указать, какие типы объектов вы хотите сгенерировать из JSON, чтобы вставить вместо универсального?

Любая помощь будет принята с благодарностью.

Спасибо.

Ответы [ 3 ]

10 голосов
/ 22 июля 2011

Проблема здесь в том, что передается правильная информация о типе, чтобы заполнить недостающую информацию (что происходит из-за стирания типа Java).

Но часто проще всего просто выбрать нужный тип подкласса,иметь что-то вроде:

class CartSignable extends Signable<Cart>  { }

и использовать это вместо создания общего экземпляра;и если да, информация о типе включена правильно (поскольку она хранится в определении класса CartSignable; тогда как Signable имеет только переменную типа!).

Джексон может принимать информацию о типе также во время сериализации, но проблема здесьэто то, как Spring будет передавать такую ​​информацию.Поэтому обычно проще использовать стиль подклассов.Обратите внимание, что вы также можете использовать анонимные внутренние классы для подклассов.

4 голосов
/ 20 октября 2011

Я закончил расширение

class ListMyObject extends ArrayList<MyObject>  { }

спасибо StaxMan - отличная помощь
PS: формат JSON> [{"id": "1", "mountain": 2}, {"id": "3", "mountain": 7}]

0 голосов
/ 12 августа 2012

Я закончил тем, что создал другой класс:

public class JobUpdateList extends ArrayList<JobUpdate> implements Serializable {
  //---- Members
  private static final long serialVersionUID = 1L;
}

Поэтому в контроллере вместо:

public @ResponseBody String setJobStatus(@RequestBody List<JobUpdate> jobUpdates) {

я сделал это:

public @ResponseBody String setJobStatus(@RequestBody JobUpdateList jobUpdates) {
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...