有没有办法使用注释验证原始(int,String等)GET参数?
@RequestMapping(value = "/api/{someInt}",
method = RequestMethod.GET,
produces = MediaType.TEXT_PLAIN_VALUE)
public ResponseEntity<String> someRestApiMethod(
@PathVariable
@Valid @Min(0) @Digits(integer=10, fraction=0)
int someInt) {
//...
return new ResponseEntity<String>("sample:"+someInt, HttpStatus.OK);
}
Run Code Online (Sandbox Code Playgroud)
如你所见,我已经放了一堆注释来验证someInt是一个10位数的正整数,但它仍接受各种整数.
我有一个java bean用于向弹簧发送JSON消息@RestController,我有bean验证设置并运行正常使用@Valid.但我想转向Protobuf/Thrift并远离REST.它是一个内部API,许多大公司已经在内部废除了REST.这真正意味着我不再控制消息对象 - 它们是在外部生成的.我不能再给它们加注释了.
所以现在我的验证必须是程序化的.我该怎么做呢?我编写了一个Validator,它的功能非常好.但它没有使用漂亮的@Valid注释.我必须做以下事情:
@Service
public StuffEndpoint implements StuffThriftDef.Iface {
@Autowired
private MyValidator myValidator;
public void things(MyMessage msg) throws BindException {
BindingResult errors = new BeanPropertyBindingResult(msg, msg.getClass().getName());
errors = myValidator.validate(msg);
if (errors.hasErrors()) {
throw new BindException(errors);
} else {
doRealWork();
}
}
}
Run Code Online (Sandbox Code Playgroud)
这很臭.我必须在每一种方法中都这样做.现在,我可以将很多内容放入一个抛出的方法中BindException,这样就可以将一行代码添加到每个方法中.但那仍然不是很好.
我想要的是看起来像这样:
@Service
@Validated
public StuffEndpoint implements StuffThriftDef.Iface {
public void things(@Valid MyMessage msg) {
doRealWork();
}
}
Run Code Online (Sandbox Code Playgroud)
并且仍然得到相同的结果.记住,我的bean没有注释.是的,我知道我可以@InitBinder在方法上使用注释.但这仅适用于Web请求.
我不介意将正确的Validator注入到这个类中,但我更喜欢我的ValidatorFactory可以根据supports()方法提取正确的一个. …
我正在检查 spring-validation Errors( BindingResult) 接口。它提到了与现场错误相对照的全局错误。什么是全局错误?
我正在验证我的数据访问对象类的字段。在一次尝试中,我开始向属性(@NotNull、@NotBlank、@Min、@Max 等)添加 Bean 验证注释。我还有更多注释 Jackson (JsonProperty (..)) 用于 swagger 库和文档(@Api (...))。在我看来,这个类非常“脏”,有很多注释(每个属性至少有三个注释)。一个字段的示例:
@JsonProperty("ownName")
@Api(description="it is my own name" required=true)
@Valid
@NotNull
private SomeObject object;
Run Code Online (Sandbox Code Playgroud)
在另一次尝试中,我使用 SpringValidator接口执行了我自己的验证。如果使用自定义验证器,例如 Spring 接口,它似乎更清晰,并且还允许您自由地为不同情况生成多个验证器。此外,该类似乎没有过多的注释和验证独立于该类。示例Validator:
public class UserValidator implements Validator {
@Override
public boolean supports(Class<?> arg0) {
return User.class.isAssignableFrom(arg0);
}
@Override
public void validate(Object obj, Errors error) {
User user = (User) obj;
if(user.getPassword().length() < 10)
{
error.reject("Password must be lesser than 10");
}
//more validations....
}
}
Run Code Online (Sandbox Code Playgroud)
当我使用BindingResult同@Validated一个方法的注释,验证无法正常工作。如果我BindingResult从方法参数中删除,它工作正常。我用过@ControllerAdvice。
知道为什么它不起作用吗?
我的代码如下:
public ResponseEntity<?> dologin(
@Validated({ Group.Login.class }) @RequestBody User user,
BindingResult errors)
{
// somecode
}
Run Code Online (Sandbox Code Playgroud)
根据验证、数据绑定和类型转换文档,任何验证消息都将自动添加到绑定器的BindingResult.
去掉不会有影响吧?
我正在使用 Spring Boot 来运行 API。我想在反序列化之前验证用户请求参数,以防止 Jackson 抛出反序列化异常。我的想法是最好在没有异常处理的情况下进行验证,但如果您认为我错了,请告诉我。
现在,我制作了一个带有@ControllerAdvice注释的异常处理程序控制器,用于在异常冒泡给用户之前捕获异常,但是有没有办法在杰克逊反序列化之前验证用户输入以检查错误?
我开始尝试使用 spring 验证,但是如果我编写一个自定义验证器并注释请求参数,@Validate验证是否会在反序列化之前进行?春季验证是正确的选择吗?
我研究了使用注释进行验证(JSR 380),但我认为我需要对验证进行更多控制,因此这就是我编写自己的自定义验证器的原因。
我想我可以编写一个自定义反序列化器来调用我的自定义验证器,但这是最好的方法。我正在寻找最佳实践和良好的验证策略。
在此先感谢您的帮助。
我正在使用 spring 来验证表单。表单的模型类似于:
public class FormModel {
@NotBlank
private String name;
@NotNull
@ImageSizeConstraint
private MultipartFile image;
}
Run Code Online (Sandbox Code Playgroud)
'@ImageSizeConstraint' 是一个自定义约束。我想要的是首先评估@NotNull,如果评估结果为false,则不评估@ImageSizeConstraint。
如果这是不可能的,我还必须检查自定义约束中的 null。这不是问题,但我想分开关注(不是空/图像大小/图像/纵横比/等)。
我想在 Spring Rest api 的控制器级别验证实体。这是我的代码:
@RestController
@RequestMapping("/orgs")
public class OrganizationController {
@PostMapping("/")
public ResponseEntity<ValidationResponse> addOrganization(@Valid @RequestBody Organization organization){
//code here
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ValidationResponse> invalidInput(MethodArgumentNotValidException ex) {
ValidationResponse response = new ValidationResponse();
response.setSuccess(false);
response.setMessage(ex.getMessage());
return new ResponseEntity<ValidationResponse>(response, HttpStatus.BAD_REQUEST);
}
}
Run Code Online (Sandbox Code Playgroud)
如果我在控制器类中包含 ExceptionHandler ,它就可以正常工作。但是,如果我将这个异常处理程序移动到 @ControllerAdvice 中,如下所示,它不起作用。
@ControllerAdvice
public class ExceptionHandlingController {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ValidationResponse> invalidInput(MethodArgumentNotValidException ex) {
ValidationResponse response = new ValidationResponse();
response.setSuccess(false);
response.setMessage(ex.getMessage());
return new ResponseEntity<ValidationResponse>(response, HttpStatus.BAD_REQUEST);
}
}
Run Code Online (Sandbox Code Playgroud)
从控制台日志我发现它被扫描了:
ExceptionHandlerExceptionResolver - Detected @ExceptionHandler methods in defaultExceptionHandler
ExceptionHandlerExceptionResolver - Detected …Run Code Online (Sandbox Code Playgroud) 我用 @Validated 注释了 RestController 以验证路径变量/请求参数:
@RestController
@Validated
public class MainController implements ApplicationListener<ApplicationReadyEvent> {
@Autowired
private CarsService carsService;
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
public void handleException(ConstraintViolationException ex) {}
@GetMapping(
value = "/",
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> getCars(
@RequestParam(value = "offset", defaultValue = "0") @PositiveOrZero
Integer offset,
@RequestParam(value = "limit", defaultValue = paginationLimitDefault)
@Positive @Max(paginationLimitMax)
Integer limit) {
...
...
Map responseBody = new HashMap<String, Object>();
responseBody.put("offset", offset);
responseBody.put("limit", limit);
return ResponseEntity.status(HttpStatus.OK).body(responseBody);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我想使用独立的 mockMvc 对控制器级别进行单元测试:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@ActiveProfiles("test")
public class TestMainController { …Run Code Online (Sandbox Code Playgroud) 我正在使用spring-boot-starter-parent版本2.4.4.
我正在尝试使用和不使用类型化配置进行验证@ConstructorBinding。
这是一个经过验证并正确停止应用程序运行的类型化配置。它不使用@ConstructorBinding,而是使用 getter/setter 样式:
@ConfigurationProperties("app")
@Validated
@Getter
@Setter
public static class AppProperties implements org.springframework.validation.Validator {
private int someProp = 10;
@Override
public boolean supports(Class<?> aClass) {
return aClass.isAssignableFrom(getClass());
}
@Override
public void validate(Object o, Errors errors) {
AppProperties appProperties = (AppProperties) o;
if (appProperties.getSomeProp() < 100) {
errors.rejectValue("someProp", "code", "Number should be greater than 100!");
}
}
}
Run Code Online (Sandbox Code Playgroud)
网络应用程序已设置,@ConfigurationPropertiesScan因此一切正常。运行时,正如预期的那样,我得到了这个:
Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'app' …Run Code Online (Sandbox Code Playgroud) spring-validator ×10
java ×6
spring ×6
spring-boot ×4
validation ×3
binding ×1
jackson2 ×1
spring-mvc ×1
spring-rest ×1
spring-web ×1