我正在创建一个简单的 Spring Data JPA 项目来测试 HTTP 请求,发现当字段类型为
Map<Object, ...>
时,@RequestBody 会出错。在这种情况下是private Map<Account, Integer> test = new LinkedHashMap<>();
我有一个猫课:
@Component
public class Cat {
private String name;
private int age;
private Map<Account, Integer> test = new LinkedHashMap<>();
public Cat() {
System.out.println("Constructor");
}
public Cat(String name, int age){
this.name = name;
this.age = age;
}
// getters and setters
还有一个 Account 类:
@Component
public class Account {
private String username;
private String password;
public Account() {
}
public Account(String username, String password) {
this.username = username;
this.password = password;
}
// getters and setters
这是我的 POST 请求控制器:
@RestController
@RequestMapping(value = "/api/post")
public class PostController {
@PostMapping()
public ResponseEntity<?> postCat(@RequestBody Cat cat) {
System.out.println("Post cat: " + cat);
return ResponseEntity.ok(cat);
}
}
我使用 POSTMAN 创建 POST 请求并将 JSON 文件作为正文发送。这是文件:
{
"name": "abc",
"age": 1000
}
(我没有将地图包含在 JSON 文件中) 虽然代码很简单,但我遇到了这个错误:
Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content-Type 'application/json;charset=UTF-8' is not supported]
测试了一些东西后,我注意到有两种方法可以解决问题(问题可能是因为 Map 字段):
将
@JsonIgnore
添加到 private Map<Account, Integer> test = new LinkedHashMap<>();
将地图更改为
private Map<Integer, Account> test = new LinkedHashMap<>();
(似乎 @RequestBody 无法与以用户定义的对象作为 Key 的 Map 一起使用,与其反序列化过程相关)
谁能给我解释一下为什么吗?
这完全没有意义,就像 @knittl 所说:
JSON 仅支持带有字符串键的地图
那么,为什么您的解决方案有效?我们每次解释一下:
@JsonIgnore
添加到地图字段:通过将
@JsonIgnore
添加到 private Map<Account, Integer> test
类中的 Cat
字段,您可以指示 Jackson
在序列化和反序列化期间忽略此字段。这有效地告诉 Jackson
在将 JSON 转换为 Java 对象时不要考虑此字段,反之亦然。将映射键类型更改为整数:
Integer
,您避免了将自定义对象 (
Account
) 反序列化为映射中的键的问题。