【问题标题】:Marshaling JSON and Generics in Java with Spring MVC使用 Spring MVC 在 Java 中编组 JSON 和泛型
【发布时间】:2011-10-10 10:26:17
【问题描述】:

我正在尝试将 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";
}

这是我想要的格式。但是,当尝试将 Signable 生成的相同 json 编组回 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 生成哪些类型的对象来插入代替泛型?

任何帮助将不胜感激。

谢谢。

【问题讨论】:

    标签: java json spring-mvc jackson


    【解决方案1】:

    这里的问题是传递正确的类型信息,以填充缺失的信息(由于 Java 类型擦除而发生)。

    但最简单的方法通常是只对您想要的类型进行子类化,例如:

    class CartSignable extends Signable<Cart>  { }
    

    并使用它,而不是构造通用实例;如果是这样,则正确包含类型信息(因为它存储在 CartSignable 的类定义中;而 Signable 只有类型变量!)。

    Jackson 也可以在序列化期间接收类​​型信息,但这里的问题是 Spring 如何传递这些信息。所以通常只使用子分类风格更容易。请注意,您也可以使用匿名内部类进行子类化。

    【讨论】:

    • 这就是我最终不得不做的。谢谢!
    • 这是迄今为止最简单的解决方案
    【解决方案2】:

    我最终扩展了

    class ListMyObject extends ArrayList<MyObject>  { }
    

    感谢 StaxMan -- 帮助很大
    PS:json格式> [{"id":"1", "mountain":2},{"id":"3", "mountain":7}]

    【讨论】:

      【解决方案3】:

      我最终创建了另一个类:

      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) {
      

      【讨论】:

        猜你喜欢
        • 2017-12-16
        • 1970-01-01
        • 2011-05-26
        • 1970-01-01
        • 1970-01-01
        • 2010-10-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多