我正在寻找一种可以自定义MethodArgumentNotValidException和ConstraintViolationException中给出的字段/对象名称的方法。
以下是上下文:我正在服务器上执行验证,但我想将服务器验证错误映射回客户端上的输入字段(直接在UI中的输入上显示服务器错误)。我正在使用一个角度指令,只要我有一个指令从服务器识别的id就可以实现这一点。
我目前正在使用几乎所有的注释来进行服务器端验证,我希望保持这种方式。以编程方式(通过javax.validation.Validator)进行验证将允许我自定义在异常中抛出的内容,因为我控制了如何填充和抛出异常。
到目前为止,我提出的唯一解决方案是创建自己的验证器来替换@Valid注释,以便将客户端ID与服务器端字段映射到我自己的逻辑中。
但......这感觉不对,尝试这样做可能存在隐患。我也不希望这是第一次有人需要这样做。那么,堆栈流的聪明人说什么呢?
答案 0 :(得分:2)
您可以将映射放在处理@ExceptionHandler
和MethodArgumentNotValidException
的{{1}}中。这是前者的一个例子。
假设一个对象ConstraintViolationException
:
Foo
import javax.validation.constraints.Min;
public class Foo {
private int bar;
@Min(0)
public int getBar() {
return bar;
}
public void setBar(int bar) {
this.bar = bar;
}
}
必须是非负面的。这是控制器。
bar
发送包含数据import internal.sandbox.domain.Foo;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
@Controller
public class SomeController {
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public Map<String,String> handleValidationFailure(MethodArgumentNotValidException e) {
Map<String, String> errors = new HashMap<>();
for (FieldError fieldError : e.getBindingResult().getFieldErrors()) {
errors.put(fieldError.getObjectName() + fieldError.getField(),
fieldError.getDefaultMessage());
}
return errors;
}
@RequestMapping(value = "/", method = RequestMethod.POST, consumes = "application/json")
public ResponseEntity<?> post(@Valid @RequestBody Foo foo) {
return new ResponseEntity<>(HttpStatus.OK);
}
}
的POST会引发由{ "bar":"-1" }
处理的MethodArgumentNotValidException
,从而产生具有以下响应正文的404:
@ExceptionHandler
我假设你有一个更聪明的{"foobar":"must be greater than or equal to 0"}
可以更好地映射你的东西,但异常包含你需要的一切,@ExceptionHandler
中的Set<ConstraintViolations>
字段也是如此。此时,您的AngularJS服务可以检查对发出POST的ConstraintViolationException
承诺的拒绝,并让字段日处理错误信息。
你可以写一个类似的$http
来处理Hibernate抛出的@ExceptionHandler
。