java - 无法反序列化从 Springboot POST 映射函数上的 Angular http post 请求发送的 POJO
问题描述
就上下文而言,我的应用程序是一家咖啡店,我想将一系列项目发送到我的 springboot 后端。然而杰克逊给出了例外:
Cannot construct instance of `me.andrewq.coffeeshop.menu_items.Menu`
(no Creators, like default constructor, exist): cannot deserialize from Object value
(no delegate- or property-based Creator)
at [Source: (PushbackInputStream); line: 1, column: 3] (through reference chain:
java.util.ArrayList[0])] with root cause
com.fasterxml.jackson.databind.exc.InvalidDefinitionException:
Cannot construct instance of `me.andrewq.coffeeshop.menu_items.Menu`
(no Creators, like default constructor, exist): cannot deserialize from Object value
(no delegate- or property-based Creator)
at [Source: (PushbackInputStream); line: 1, column: 3] (through reference chain:
java.util.ArrayList[0]).
这是项目的类的样子(省略了 setter 和 getter 之后):
public class Menu {
private int productId;
private String name;
private double price;
private String[][] productOptions;
private String type;
// These 3 variables belong to drinks. The creams and sugars more so for coffees
private String currentSize;
private Integer creams;
private Integer sugars;
public Menu(int productId, String name, double price, String productOptions, String type){
this.productId = productId;
this.name = name;
this.price = price;
this.productOptions = convertOptions(productOptions);
this.type = type;
}
/**
* Used for converting the product options which is a key-value pair seperated by a ',' in the DB, into a 2D array in this class.
* @param options
* @return
*/
private String[][] convertOptions(String options) {
String[] optionPairs = options.split(",");
//hard coded b/c I know that these are pairs
String retVal[][] = new String[optionPairs.length][2];
for(int i = 0; i < optionPairs.length; ++i){
String[] temp = optionPairs[i].split(":");
retVal[i] = temp;
}
return retVal;
}
@Override
public String toString(){
return String.format("{productId: %i, name: %s}", this.productId, this.name);
}
}
请求在控制器类中接收为:
@RestController
public class OrderController {
@CrossOrigin(origins = "http://localhost:4200")
@PostMapping(path = "/guestOrder")
public String order(@RequestBody List<Menu> order){
for(Menu item: order){
System.out.println(item.toString());
}
return "Sending order worked";
}
}
在 Angular 中,该项目定义为:
export interface Menu {
productId: number;
name: string;
price: number;
productOptions: string[][];
type: string;
// additional field for drinks and coffees
currentSize: string;
creams: number;
sugars: number;
}
而http请求调用是: this.http.post<string>(`${this.url}/guestOrder`, this.orderItems);
wherehttp: HttpClient
和orderItems: Menu[]
.
如果不格式化 JSON,JSON 字符串的第 65 列会出现错误:
[{"productId":1,"name":"Iced Coffee","price":2,"productOptions":[["S","2.00"],["M","2.50"],["L","3.00"]],"type":"IC","currentSize":"S","creams":0,"sugars":0}]
这是在第一个括号productOptions
解决方案
这个异常实际上说得很好——你需要为你的 POJO 类添加一个默认构造函数。
JSON 解析器首先创建一个空实例,然后为 JSON 文本中遇到的每个属性调用 setter 方法。JSON 中未包含的属性保持不变,因此具有默认构造函数分配给它的值(通常null
除非您将其设置为其他值)。
我希望为了清楚起见省略了你所说的 getter 和 setter,确实存在,否则它不会工作。
推荐阅读
- java - Mapreduce 标记 3 列
- reactjs - JSX 元素类型“按钮”没有任何构造或调用签名
- typescript - Mock-fs 无效目录测试不会导致 promise 被拒绝
- node.js - apollo-server-testing:如何键入 createTestClient() 返回?(eslint 未绑定方法错误)
- python - 如何从显示在屏幕上的函数获取返回值(pyqt5)
- java - 检查列表
包含值失败 - ruby - Ruby - 如何将数据添加到嵌套数组中?
- vue.js - Vue CLI 使用相对路径部署到子文件夹
- electron - 无法在 win32 上运行 ElectronJS 捆绑应用程序
- java - PowerMock whenNew 不返回模拟对象