Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring Boot 2和方法参数验证_Java_Spring_Spring Boot_Spring Validator - Fatal编程技术网

Java Spring Boot 2和方法参数验证

Java Spring Boot 2和方法参数验证,java,spring,spring-boot,spring-validator,Java,Spring,Spring Boot,Spring Validator,我创建了以下服务接口: import javax.validation.constraints.NotBlank; import org.springframework.lang.NonNull; import org.springframework.validation.annotation.Validated; @Validated public interface UserService { User create(@NonNull Long telegramId, @Not

我创建了以下服务接口:

import javax.validation.constraints.NotBlank;

import org.springframework.lang.NonNull;
import org.springframework.validation.annotation.Validated;

@Validated
public interface UserService {

    User create(@NonNull Long telegramId, @NotBlank String name, @NonNull Boolean isBot);

}
但是下面的调用:

userService.create(telegramId, "Mike", null);

通过
isBot
参数的
@NotNull
验证。如何正确配置Spring Boot和my service,以便考虑
@NonNull
注释,并防止在
null
参数的情况下执行方法?

在实现类中使用相同的东西,而不是在接口中使用。 还可以编写一个全局异常,如:

@Order(Ordered.HIGHEST_PRECEDENCE)
@RestControllerAdvice
public class GlobalRestException extends ResponseEntityExceptionHandler {
...
...

/**
     * Handle MethodArgumentNotValidException. Triggered when an object fails @Valid
     * validation.
     *
     * @param ex      the MethodArgumentNotValidException that is thrown when @Valid
     *                validation fails
     * @param headers HttpHeaders
     * @param status  HttpStatus
     * @param request WebRequest
     * @return the ApiException object
     */
    @Override
    protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
            HttpHeaders headers, HttpStatus status, WebRequest request) {
        Error apiError = new Error(BAD_REQUEST);
        apiError.setMessage("Validation error");
        apiError.addValidationErrors(ex.getBindingResult().getFieldErrors());
        apiError.addValidationError(ex.getBindingResult().getGlobalErrors());
        return buildResponseEntity(apiError);
    }
}
@顺序(有序。最高优先级)
@再控制建议
公共类GlobalRestException扩展了ResponseEntityExceptionHandler{
...
...
/**
*Handle MethodArgumentNotValidException。当对象失败@Valid时触发
*验证。
*
*@param ex在@Valid时引发的MethodArgumentNotValidException
*验证失败
*@param headers-HttpHeaders
*@param status HttpStatus
*@param request WebRequest
*@返回ApiException对象
*/
@凌驾
受保护响应handleMethodArgumentNotValid无效(MethodArgumentNotValidException ex,
HttpHeaders标头、HttpStatus状态、WebRequest请求){
Error APIRROR=新错误(错误请求);
setMessage(“验证错误”);
addValidationErrors(例如getBindingResult().getFieldErrors());
apiError.addValidationError(例如getBindingResult().getGlobalErrors());
返回buildResponseEntity(apiError);
}
}
可以重写更多方法来处理不同类型的异常,如:

/**
 * Handles javax.validation.ConstraintViolationException. Thrown when @Validated
 * fails.
 *
 * @param ex the ConstraintViolationException
 * @return the ApiException object
 */
@ExceptionHandler(javax.validation.ConstraintViolationException.class)
protected ResponseEntity<Object> handleConstraintViolation(javax.validation.ConstraintViolationException ex) {
    Error apiError = new Error(BAD_REQUEST);
    apiError.setMessage("Validation error");
    apiError.addValidationErrors(ex.getConstraintViolations());
    return buildResponseEntity(apiError);
}
/**
*处理javax.validation.ConstraintViolationException。当@Validated时抛出
*失败了。
*
*@param exconstraintviolationexception
*@返回ApiException对象
*/
@ExceptionHandler(javax.validation.ConstraintViolationException.class)
受保护的响应handleConstraintViolation(javax.validation.ConstraintViolationException ex){
Error APIRROR=新错误(错误请求);
setMessage(“验证错误”);
apierro.addValidationErrors(例如getConstraintViolations());
返回buildResponseEntity(apiError);
}

我把这个问题处理了一会儿

您的代码在我看来很好:请确保
UserService
的实现也包含验证注释

确保允许Spring创建Bean;它应该像你期望的那样工作

实例 服务定义 服务实现 测试向量 测试用例对我来说是绿色的

Github:

资料来源:


您是否尝试将
@Validated
注释放在服务的实际实现上?是的,不幸的是,在这种情况下,我得到了相同的结果只是在这些注释上打一下就不起作用了。这仅适用于控制器,因为它已备份到
RequestMappingHandlerAdapter
。要为其他bean启用它,您还需要添加
MethodValidationPostProcessor
以注册AOP部件。我认为它对我不起作用,因为现在没有抛出
MethodArgumentNotValidException
。这就是问题所在-在这种情况下如何获得抛出的
MethodArgumentNotValidException
?您永远不会在这里得到该异常,因为它是服务层的一部分。
MethodArgumentNotValidException
是一个特定的web绑定异常。因此,服务上的验证错误永远不会出现后者。非常感谢您提供的解决方案!是否可以使其与
@Service
注释一起工作?可以。我真傻。只需在实现(在我的例子中)上添加
@Service
注释
HelloGreetingService
并删除bean。做了这些之后,我的测试用例仍然是绿色的。更新了我的代码,如果需要,请查看github上的更新帖子和更新代码。
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

@Validated
public interface GreetingService {
    String greet(@NotNull @NotBlank String greeting);
}
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

@Service
public class HelloGreetingService implements GreetingService {

    public String greet(@NotNull @NotBlank String greeting) {
        return "hello " + greeting;
    }
}
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;

import javax.validation.ConstraintViolationException;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

@SpringBootTest
class HelloGreetingServiceTest {

    @Autowired
    private GreetingService helloGreetingService;

    @Test
    void whenGreetWithStringInput_shouldDisplayGreeting() {
        String input = "john doe";
        assertEquals("hello john doe", helloGreetingService.greet(input));
    }

    @Test
    void whenGreetWithNullInput_shouldThrowException() {
        assertThrows(ConstraintViolationException.class, () -> helloGreetingService.greet(null));
    }

    @Test
    void whenGreetWithBlankInput_shouldThrowException() {
        assertThrows(ConstraintViolationException.class, () -> helloGreetingService.greet(""));
    }

}