私はSpring3フレームワーク、休止状態バリデータ、およびジャクソンを使用しています。
サーバーにjsondataをリクエストしたとき。400 Bad Request エラーを返しました。
私のデータは不一致タイプです。
マッチタイプをリクエストするとうまくいきます。
私のコントローラーコード:
@RequestMapping(consumes = MediaType.ALL_VALUE, produces = MediaType.ALL_VALUE,value =
"doAdd", method = RequestMethod.POST)
@ResponseBody
public Customer doAdd(@RequestBody @Valid Customer inData){
this.customerService.addData(inData);
return inData;
}
エラーハンドルメソッドは次のとおりです。
@ExceptionHandler
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
@ResponseBody
public void ajaxValidationErrorHandle(MethodArgumentNotValidException errors ,
HttpServletResponse response) throws BusinessException {
List<String> resErrors = new ArrayList<String>();
for(ObjectError error : errors.getBindingResult().getAllErrors()){
resErrors.add(error.getCode());
}
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
throw new BusinessException("E000001", "VALIDATION");
}
Customer.java(モデル) :
package test.business.model;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.Range;
public class Customer {
@Size(min = 0, max = 3)
public String id;
@NotNull
@Size(min = 1)
public String name;
@NotNull
@Range(min = 10, max = 99)
public Integer age;
public String updateTime;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getUpdateTime() {
return updateTime;
}
public void setUpdateTime(String updateTime) {
this.updateTime = updateTime;
}
}
json データ:
1.{"name":"ken","age":11,"updateTime":"2013-06-18"}
2.{"name":"ken","age":"","updateTime":""}
3.{"name":"ken","age":"joe","updateTime":""}
json data 1 が正常に返ってきます。
json データ 2 が正常に返されます (MethodArgumentNotValidException customer.age,NotNull をキャッチしました)。
json データ 2 が返されます 400 Bad Request エラー。しかし、サーバーが typeMismatch.int エラーを返したことを願っています。
@Pavel Horalどうもありがとうございました!
HttpMessageNotReadableException をキャッチして処理できました。
変更されたエラー ハンドル メソッド。
@ExceptionHandler
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
@ResponseBody
public void ajaxValidationErrorHandle(Exception errors , HttpServletResponse response) throws BusinessException {
if(errors instanceof MethodArgumentNotValidException){
MethodArgumentNotValidException mane = (MethodArgumentNotValidException)errors;
for(ObjectError error : mane.getBindingResult().getAllErrors()){
resErrors.add(error.getCode());
}
}
if(errors instanceof HttpMessageNotReadableException){
JsonMappingException jme = (JsonMappingException)errors.getCause();
List<Reference> errorObj = jme.getPath();
for(Reference r : errorObj){
System.out.println(r.getFieldName());
}
}
・・・
ただ、全てのコントローラーにこのコードを書いたり、基底クラスを継承したりというのは、Springの設計思想を見たことがないような気がするので、そこを処理してExceptionResolverを新しくすることにした。
私の新しい ExceptionResolver は次のとおりです。
public class OriginalExceptionHandler extends SimpleMappingExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) {
ModelAndView m = null;
StringBuilder exceptionMessage = new StringBuilder(ajaxDefaultErrorMessage) ;
if(e instanceof BusinessException){
・・・
}else if(e instanceof HttpMessageNotReadableException){
Throwable t = e.getCause();
if(t instanceof JsonMappingException){
JsonMappingException jme = (JsonMappingException)t;
List<Reference> errorObj = jme.getPath();
for(Reference r : errorObj){
exceptionMessage.append("VE9999:Unmatched Type Error!!("+r.getFieldName()+")");
}
}else{
exceptionMessage.append(e+"\n"+o.toString());
}
}else if(e instanceof MethodArgumentNotValidException){
MethodArgumentNotValidException mane = (MethodArgumentNotValidException)e;
for(ObjectError error : mane.getBindingResult().getAllErrors()){
if(error instanceof FieldError){
FieldError fe = (FieldError) error;
exceptionMessage.append("VE0001:Validation Error!!"+fe.getField()+"-"+fe.getDefaultMessage());
}else{
exceptionMessage.append("VE0001:Validation Error!!"+error.getDefaultMessage());
}
}
}else{
・・・
そして、お香を application-context.xml に追加しました。
<bean class="test.core.OriginalExceptionHandler" p:order="1">
<property name="exceptionMappings">
<props>
<prop key="sample.core.BusinessException">
ExceptionPage
</prop>
<prop key="test.core.LoginSessionException">
LoginSessionException
</prop>
</props>
</property>
<property name="defaultErrorView" value="error" />
</bean>
この考え方は正しいでしょうか?
ありがとうございました、