fin*_*elp 10 java validation rest json spring-mvc
我有一个REST服务,它接受JSON请求.我想验证即将发布的JSON请求值.我该怎么做?
在Spring 3.1.0 RELEASE中,我知道有人想确保他们使用3.1.13新的基于HandlerMethod的支持类列出的最新支持类,用于带注释的控制器处理
旧的是像:AnnotationMethodHandlerAdapter.我想确保我使用最新的如RequestMappingHandlerAdapter.
这是因为我希望它能解决我看到的问题:
java.lang.IllegalStateException:在没有先前模型属性的情况下声明的Errors/BindingResult参数.检查处理程序方法签名!
我的@Controller处理程序方法和相关代码是这样的:
@Autowired FooValidator fooValidator;
@RequestMapping(value="/somepath/foo", method=RequestMethod.POST)
public @ResponseBody Map<String, String> fooBar(
@Valid @RequestBody Map<String, String> specificRequest,
BindingResult results) {
out("fooBar called");
// get vin from JSON (reportRequest)
return null;
}
@InitBinder("specificRequest") // possible to leave off for global behavior
protected void initBinder(WebDataBinder binder){
binder.setValidator(fooValidator);
}
Run Code Online (Sandbox Code Playgroud)
FooValidator 看起来像这样:
@Component
public class FooValidator implements Validator {
public boolean supports(Class<?> clazz) {
out("supports called ");
return Map.class.equals(clazz);
}
public void validate(Object target, Errors errors) {
out("validate called ");
}
private void out(String msg) {
System.out.println("****** " + getClass().getName() + ": " + msg);
}
}
Run Code Online (Sandbox Code Playgroud)
如果我删除了BindingResult,一切正常,除非我无法判断JSON是否经过验证.
我并不强烈依赖于使用a Map<String, String>作为JSON请求或使用单独的验证器而不是使用验证注释的自定义Bean的概念(如何为JSON请求执行此操作?).无论什么都可以验证JSON请求.
ska*_*man 15
3.1.17 @Valid On @RequestBody控制器方法参数说:
一种
@RequestBody方法参数可以与注释@Valid以调用类似于用于支持自动验证@ModelAttribute方法的参数.所得MethodArgumentNotValidException在处理DefaultHandlerExceptionResolver中和结果400响应代码.
换句话说,如果你使用@Valid @RequestBody那么Spring会在调用你的方法之前拒绝一个无效的请求.如果你的方法被调用,然后你可以假设请求体是有效的.
BindingResult用于验证表单/命令对象,而不是@RequestBody.
我不得不做一次类似的事情.我刚刚通过创建一个JSON可以转换成并用于转换的Java对象来简化我的生活GSON.
老实说,这很简单:
@Autowired
private Gson gson;
@RequestMapping(value = "/path/info", method = RequestMethod.POST)
public String myMethod(@RequestParam(value = "data") String data,
Model model,
@Valid MyCustomObject myObj,
BindingResult result) {
//myObj does not contain any validation information.
//we are just using it as as bean to take advantage of the spring mvc framework.
//data contains the json string.
myObj = gson.fromJson(data, MyCustomObject.class);
//validate the object any way you want.
//Simplest approach would be to create your own custom validator
//to do this in Spring or even simpler would be just to do it manually here.
new MyCustomObjValidator().validate(myObj, result);
if (result.hasErrors()) {
return myErrorView;
}
return mySuccessView;
}
Run Code Online (Sandbox Code Playgroud)
在自定义Validator类中进行所有验证:
public class MyCustomObjValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return MyCustomObj.class.equals(clazz);
}
@Override
public void validate(Object target, Errors errors) {
MyCustomObj c = (MyCustomObj) target;
Date startDate = c.getStartDate();
Date endDate = c.getEndDate();
if (startDate == null) {
errors.rejectValue("startDate", "validation.required");
}
if (endDate == null) {
errors.rejectValue("endDate", "validation.required");
}
if(startDate != null && endDate != null && endDate.before(startDate)){
errors.rejectValue("endDate", "validation.notbefore.startdate");
}
}
}
Run Code Online (Sandbox Code Playgroud)
MyCustomObject 不包含任何用于验证的注释,这是因为否则Spring将尝试验证此对象中当前为空的这些字段,因为所有数据都在JSON字符串中,例如可以是:
public class MyCustomObject implements Serializable {
private Date startDate;
private Date endDate;
public Date getStartDate() {
return startDate;
}
public Date getEndDate() {
return endDate;
}
public void setStartDate(Date theDate) {
this.startDate = theDate;
}
public void setEndDate(Date theDate) {
this.endDate = theDate;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16860 次 |
| 最近记录: |