java - 使用spring mvc时,RequestBody中json转换成对象失败,对象中包含list
怪我咯
怪我咯 2017-04-18 10:56:16
0
3
964

使用spring mvc时,RequestBody中json转换成对象失败,因为对象中包含list,如果我去掉list,就能转换成功。

代码:

DTO类代码:

public class OrderDishes {

    // 就餐人数
    private int peopleNum;
    // 单个菜品
    private List<Dishes> variant;
    // 套餐
    private List<Dishes> product;
    // 商品总额
    private BigDecimal totalAmount;
    // 折扣金额
    private BigDecimal discountAmount;
    // 备注
    private String memo;
    // 是否推迟下单
    private boolean isPostpone;

    public OrderDishes(int peopleNum, List<Dishes> variant, List<Dishes> product, BigDecimal totalAmount, BigDecimal discountAmount, String memo, boolean isPostpone) {
        this.peopleNum = peopleNum;
        this.variant = variant;
        this.product = product;
        this.totalAmount = totalAmount;
        this.discountAmount = discountAmount;
        this.memo = memo;
        this.isPostpone = isPostpone;
    }

    public OrderDishes() {
    }

    public int getPeopleNum() {
        return peopleNum;
    }

    public void setPeopleNum(int peopleNum) {
        this.peopleNum = peopleNum;
    }

    public List<Dishes> getVariant() {
        return variant;
    }

    public void setVariant(List<Dishes> variant) {
        this.variant = variant;
    }

    public List<Dishes> getProduct() {
        return product;
    }

    public void setProduct(List<Dishes> product) {
        this.product = product;
    }

    public BigDecimal getTotalAmount() {
        return totalAmount;
    }

    public void setTotalAmount(BigDecimal totalAmount) {
        this.totalAmount = totalAmount;
    }

    public BigDecimal getDiscountAmount() {
        return discountAmount;
    }

    public void setDiscountAmount(BigDecimal discountAmount) {
        this.discountAmount = discountAmount;
    }

    public String getMemo() {
        return memo;
    }

    public void setMemo(String memo) {
        this.memo = memo;
    }

    public boolean isPostpone() {
        return isPostpone;
    }

    public void setPostpone(boolean postpone) {
        isPostpone = postpone;
    }

    public class Dishes {
        private Long productID;
        private int quantity;
        private String memo;
        private BigDecimal addedPrice;

        public BigDecimal getAddedPrice() {
            return addedPrice;
        }

        public void setAddedPrice(BigDecimal addedPrice) {
            this.addedPrice = addedPrice;
        }

        public Long getProductID() {
            return productID;
        }

        public void setProductID(Long productID) {
            this.productID = productID;
        }

        public int getQuantity() {
            return quantity;
        }

        public void setQuantity(int quantity) {
            this.quantity = quantity;
        }

        public String getMemo() {
            return memo;
        }

        public void setMemo(String memo) {
            this.memo = memo;
        }
    }

}

传入json:

{
  "peopleNum": 1,
  "variant": [
    {
      "productID": 269,
      "quantity": 1,
      "memo": "string",
      "addedPrice": 0
    }
  ],
  "product": [
    {
      "productID":469 ,
      "quantity": 1,
      "memo": "string",
      "addedPrice": 0
    }
  ],
  "totalAmount": 1000,
  "discountAmount": 0,
  "memo": "string",
  "postpone": true
}

错误信息:

org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: No suitable constructor found for type [simple type, class cc.toprank.byd.pad.dto.OrderDishes$Dishes]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?)
 at [Source: java.io.PushbackInputStream@5607eee4; line: 5, column: 7] (through reference chain: cc.toprank.byd.pad.dto.OrderDishes["variant"]->java.util.ArrayList[0]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class cc.toprank.byd.pad.dto.OrderDishes$Dishes]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?)
 at [Source: java.io.PushbackInputStream@5607eee4; line: 5, column: 7] (through reference chain: cc.toprank.byd.pad.dto.OrderDishes["variant"]->java.util.ArrayList[0])
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:229)
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:213)
    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:197)
    at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:147)
    at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:125)
    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:99)
    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:832)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:743)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:961)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:895)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:869)
怪我咯
怪我咯

走同样的路,发现不同的人生

Antworte allen(3)
阿神

将Dishes设置成静态内部类
如这样

public static class Dishes{


}

内部类

// 非静态内部类实例会默认有一个上一级类的实例的引用
// 非静态内部类的实例化是这样的
OrderDishes orderDishes = new OrderDishes(); // 外部类
Dishes dish = orderDishes.new Dishes(); // 非静态内部类

静态内部类

// 如果是静态内部类则内部类和外部类没有关联关系
// 他们的关系只是在同一个文件中
OrderDishes orderDishes = new OrderDishes(); // 外部类
Dishes dish = new Dishes(); // 非静态内部类,正常方式的实例化

JSON反序列化失败的原因是序列化框架不知道Dishes是内部类,所以创建对象失败了

求点赞和采纳~~

Ty80

字符串转对象时如果对象带有有参数构造方法,那么必须要增加一个无参数的构造方法,
不然通过反射创建对象时会报错,因为需要参数

洪涛

内部类没有不带参数构造方法,默认生成的构造方法带参数,参数为外层类对象

Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage