首页 > 解决方案 > springboot中@NonNull注解的http请求对象字段能否在setter方法中访问,并对其进行操作,而不抛出空指针

问题描述

下面是一个 HTTP 请求对象,它捕获从用户到 SpringBoot 应用程序的 json 输入。

package com.bablo.google.request;

import java.io.Serializable;
import java.util.Set;

import javax.validation.constraints.NotNull;

public class SomeRequest implements Serializable {

    /**
     *
     */
    private static final long serialVersionUID = 1L;

    @NotNull
    private Long userId;

    private String resNote; //this is not annotated with @NotNull
    @NotNull
    private String revTag;

    public Long getUserId() {
        return userId;
    }

    public void setUserId(final Long userId) {
        this.userId = userId;
    }

    public String getResNote() {
        return responseNote;
    }

    public void setResNote(final String resNote) {
        this.resNote = resNote.trim();    //Call to trim() method of the String object.
    }

    public String getRevTag() {
        return revTag;
    }

    public void setRevTag(final String revTag) {
        this.revTag = revTag.trim();     //Call to the trim() method of the String object.
    }

}

可以在 setter 方法中修剪带有 @NotNull 验证注释的类的字符串字段吗?

这里的 revTag 字段是用@NotNull 注释的,并且在 setter 方法中被修剪,在这种情况下,如果传入的请求对象有 null 作为 revTag 值,它会抛出 NullPointerException 吗?在这种情况下会发生什么?

resNote 字段没有使用@NotNull 注解,如果 resNote 出现 null 值,肯定会抛出 NullPointerException。

标签: javaspringhibernatespring-bootvalidation

解决方案


我们可以安全地在 setter 方法中进行修剪,因为如果请求中不存在 revTag 值,绑定到对象本身将会失败。

注意: @Valid 注释应该添加到控制器的请求处理方法中,以启用数据绑定验证。

下面的 Controller & JUnit 证明是一样的。

@RestController
public class DemoController {

    @GetMapping("/demo/req")
    public ResponseEntity handleSomeGetRequest(@Valid SomeRequest someRequest){
        return ResponseEntity.ok("success");
    }
}


@WebMvcTest(value = DemoController.class)
class DemoControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void testNotNullValidation() throws Exception {

        //invoking the endpoint without any request param and this throws BadRequest
        mockMvc.perform(MockMvcRequestBuilders.get("/demo/req"))
                .andExpect(MockMvcResultMatchers.status().isBadRequest());
    }

}

Error in the log trace. 
2020-05-19 22:34:18.509  WARN 9276 --- [    Test worker] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 2 errors
Field error in object 'someRequest' on field 'userId': rejected value [null]; codes [NotNull.someRequest.userId,NotNull.userId,NotNull.java.lang.Long,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [someRequest.userId,userId]; arguments []; default message [userId]]; default message [must not be null]
Field error in object 'someRequest' on field 'revTag': rejected value [null]; codes [NotNull.someRequest.revTag,NotNull.revTag,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [someRequest.revTag,revTag]; arguments []; default message [revTag]]; default message [must not be null]]

推荐阅读