使用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)
Dishesを静的内部クラスとして設定します
リーリーこのように
インナークラス
リーリー静的内部クラス
リーリーJSON 逆シリアル化が失敗する理由は、シリアル化フレームワークが Dishes が内部クラスであることを認識していないため、オブジェクトの作成が失敗するためです
いいねして採用してください~~
文字列をオブジェクトに変換するとき、オブジェクトにパラメーター化されたコンストラクターがある場合は、パラメーターのないコンストラクターを追加する必要があります。それ以外の場合は、パラメーターが必要であるため、リフレクションを通じてオブジェクトを作成するときにエラーが報告されます。
内部クラスにはパラメータのないコンストラクタはありません。デフォルトで生成されるコンストラクタはパラメータを受け取り、パラメータは外部クラスのオブジェクトです
。