我有一个使用JSON的Sping Boot 控制器:
@PostMapping(
value = "/shipdetails")
public ResponseEntity acceptShip(@RequestBody Ship ship, HttpServletRequest request) {
shipService.checkShip(ship);
return new ResponseEntity<>(HttpStatus.OK);
}
存在对应的发货实体:
public class Ship implements Serializable {
@JsonProperty("Name")
private String name;
@JsonProperty("Owner")
private String owner;
public Ship(String name, String owner) {
this.name = name;
this.owner = owner; }
public Ship() {
}
// Getters and Setters removed for brevity
最后是服务:
@Service
public class ShipService {
Boolean checkShip(Ship ship) {
if (ship.getName().equals("Queen Mary")) {
// do something
}
//edited for brevity
示例无效JSON:
{
"name_wrong":"test name",
"owner":"Lloyds Shipping"
}
目前,如果我发送无效的JSON,我在堆栈跟踪上得到的错误是(服务层):Cannot invoke "String.equals(Object)" because the return value of "com.ships.Ship.getName()" is null
。
Jackson需要no-args构造函数来进行反序列化。
当在调试器中检查时,Ship实体有一个所有者集,但没有名称集,所以它不是整个实体都为空-只有一个字段。
我尝试了我的Ship实体,没有默认的no args构造函数,所以你甚至不能将带有null字段的实体传递给服务,但是即使是有效的JSON也会失败。
如何以及在哪里处理无效JSON的异常?
2条答案
按热度按时间wn9m85ua1#
需要添加一些注解和检查来验证请求体json。
1.在pom.xml中为以下注解添加依赖-
2. @对请求体有效
3. @ Nottune,带必选属性
4. equals方法前增加null检查
输出的json无效:
输入
**输出:**您将得到一个400 Bad请求状态,长错误堆栈跟踪包括如下内容
**注意:一些额外的代码,用于使用我们自定义的exceptionsoftware处理
MethodArgumentNotValidException
**异常,以便验证将在正确的格式响应中,而不是第二次错误stacktrace,并控制状态码,如下图所示:json无效的错误输出:
yiytaume2#
与其将问题视为一个命名错误的字段,不如将其视为两个问题:缺少属性(
name
)和额外属性(name_wrong
)。Sping Boot 默认配置为忽略任何额外的属性。除非你告诉控制器
name
属性是必需的(例如,通过在name
字段上使用@NotNull
bean验证注解),它将很乐意接受此属性的空值。缺少必填属性
由于您试图在
null
name
字段上调用equals
,因此发生了NullPointerException
。有几种不同的解决方法。首先,您可以将bean验证添加到必填字段:
或者,您可以将equals方法更改为null-safe:
额外属性
有几种方法可以让Spring拒绝额外的
name_wrong
属性。如果你希望应用程序总是拒绝未知属性(除非特定的bean选择退出),你可以全局配置它:
application.yml