spring mvc 출력 json 이상 처리

지난 편 에 JSON 지원 이 적 혀 있 습 니 다.요청 이 성공 할 때,
AnnotationMethodHandlerAdapter 는 message Converters 를 사용 하여 방법 을 클 라 이언 트 에 되 돌려 줍 니 다.
요청 이 실패 하면?반환 값 이 전혀 없 는데 어떻게 출력 합 니까?
이 경우 spring 의 오류 해석 기(Exception Resolver)를 사용 해 야 합 니 다.Controller 에 이상 이 발생 하면 Exception Resolver 가 호출 되 어 위의 상황 을 처리 할 수 있 습 니 다.
저희 가 쓰 려 고 했 는데.
spring 의 org.spring from work.web.servlet.mvc.annotation.annotation MethodHandler Exception Resolver,유 감 스 럽 지만 이 오류 해석 기 는 bug 가 있 고 기능 에 결함 이 있 기 때문에 우리 스스로 Exception Resolver 를 실현 해 야 합 니 다.
이 bug 는 묘사 하기 어렵 고 관심 있 는 것 은 bug 를 찾 을 수 있 습 니 다.WIKI 에 가서 본인 은 영어 가 너무 못 해서 쓸 줄 모 릅 니 다.
Exception Resolver 의 사고방식 실현:
현재 이상 처리:대부분의 방법 은 Controller 에서 try..catch,try 에서 정상 적 인 요청 을 처리 하고 catch 에서 이상 요청 을 처리 합 니 다.단점:
1.모든 방법 은 이렇게 쓰 고 코드 는 반복 합 니 다.
2.컨트롤 러 외부의 오 류 를 포착 하지 못 합 니 다.예 를 들 어 어떤 차단기 의 오 류 는 고객 에 게 좋 은 힌트 를 줄 수 없습니다.
3.catch 구문 블록 에 로 그 를 기록 하고 코드 가 중복 되 어야 합 니 다.
이 오류 해석 기 는 다음 과 같은 기능 이 있어 야 합 니 다.
1.이상 해석 기 를 사용 하 는 이상 Controller 에서 이상 을 처리 하지 않 고 던 지면 됩 니 다.개발 을 간소화 하고 이상 통일 통 제 를 할 수 있 습 니 다.
2.ajax 요청(@Response Body 의 Controller)에 오류 가 발생 하여 JSON 을 출력 합 니 다.
3.페이지 요청(@ResponseBody 가 없 는 Controller)에 오류 가 발생 하여 오류 페이지 를 출력 합 니 다.
4.AnnotationMethodHandlerAdapter 와 같은 message Converters 를 사용 해 야 합 니 다.
5.이상 처리 디 테 일 을 제어 할 수 있 습 니 다.
Annotation Handler MethodException Resolver 를 보십시오.이것 은 제 가 쓴 실현 클래스 입 니 다.사용법:
/**
 *    Controller        ,    ,           。
* ajax ( @ResponseBody Controller) , JSON。
* ( @ResponseBody Controller) , 。
* AnnotationMethodHandlerAdapter messageConverters
* Controller 。 * * @author dongjian * * */ public class AnnotationHandlerMethodExceptionResolver extends ExceptionHandlerExceptionResolver { private String defaultErrorView; public String getDefaultErrorView() { return defaultErrorView; } public void setDefaultErrorView(String defaultErrorView) { this.defaultErrorView = defaultErrorView; } protected ModelAndView doResolveHandlerMethodException(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod, Exception exception) { if (handlerMethod == null) { return null; } Method method = handlerMethod.getMethod(); if (method == null) { return null; } ModelAndView returnValue = super.doResolveHandlerMethodException(request, response, handlerMethod, exception); ResponseBody responseBodyAnn = AnnotationUtils.findAnnotation(method, ResponseBody.class); if (responseBodyAnn != null) { try { ResponseStatus responseStatusAnn = AnnotationUtils.findAnnotation(method, ResponseStatus.class); if (responseStatusAnn != null) { HttpStatus responseStatus = responseStatusAnn.value(); String reason = responseStatusAnn.reason(); if (!StringUtils.hasText(reason)) { response.setStatus(responseStatus.value()); } else { try { response.sendError(responseStatus.value(), reason); } catch (IOException e) { } } } return handleResponseBody(returnValue, request, response); } catch (Exception e) { return null; } } if(returnValue.getViewName() == null){ returnValue.setViewName(defaultErrorView); } return returnValue; } @SuppressWarnings({ "unchecked", "rawtypes" }) private ModelAndView handleResponseBody(ModelAndView returnValue, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Map value = returnValue.getModelMap(); HttpInputMessage inputMessage = new ServletServerHttpRequest(request); List acceptedMediaTypes = inputMessage.getHeaders().getAccept(); if (acceptedMediaTypes.isEmpty()) { acceptedMediaTypes = Collections.singletonList(MediaType.ALL); } MediaType.sortByQualityValue(acceptedMediaTypes); HttpOutputMessage outputMessage = new ServletServerHttpResponse(response); Class> returnValueType = value.getClass(); List> messageConverters = super.getMessageConverters(); if (messageConverters != null) { for (MediaType acceptedMediaType : acceptedMediaTypes) { for (HttpMessageConverter messageConverter : messageConverters) { if (messageConverter.canWrite(returnValueType, acceptedMediaType)) { messageConverter.write(value, acceptedMediaType, outputMessage); return new ModelAndView(); } } } } if (logger.isWarnEnabled()) { logger.warn("Could not find HttpMessageConverter that supports return type [" + returnValueType + "] and " + acceptedMediaTypes); } return null; } }

------------------------web.xml-------------------------------------
spring mvc 는 당연히 이상 해석 기 를 자동 으로 등록 합 니 다.사용자 정의 클래스 를 사용 할 수 있 도록 자동 등록 을 금지 해 야 합 니 다.
dispatcher
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:dispatcher-servlet.xml
detectAllHandlerExceptionResolvers
false
1
스프링 화면 음악 설정
-----------------------------------------------------------------------------
모든 컨트롤 러 계승 BaseController
/**
*이상 제어,이것 은 이상 한 세부 사항 을 제어 할 수 있 습 니 다.앞으로 국제 화(이상 정보 국제 화)를 지원 할 수 있 습 니 다.
* */
@ExceptionHandler(Exception.class)
@ResponseStatus(value=HttpStatus.INTERNAL_SERVER_ERROR)
public ModelAndView handleException(Exception ex, HttpServletRequest request) {
return new ModelAndrView().addObject("error","오류 정보");
}
오류 vm 코드
$!{error}
OK,이제 됐 습 니 다.다음은 예상 기능 을 테스트 해 보 겠 습 니 다.
테스트 코드 DemoController extends BaseController
@RequestMapping("/demoAjax")
@ResponseBody
public Map demoAjax(String name) {
if(StringUtils.isEmpty(name) ) throw new RuntimeException();
return Collections.singletonMap("name", name);
}
@RequestMapping("/demoPage")
public ModelAndView demoPage(String name) {
if(StringUtils.isEmpty(name) ) throw new RuntimeException();
ModelAndView mav = new ModelAndView();
mav.setViewName("demo.vm");
return mav;
}
테스트 코드 의 전단
$.ajaxSetup({//ajax 설정 전역 기본 설정 요청
async : true,
error : function(jqXHR, textStatus, errorThrown){
var msg = $.parseJSON(jqXHR.responseText).error;
alert(msg);
},
traditional : true,
dataType : "json",
type : "POST"
});
$.ajax({//요청 이 성공 합 니 다.
url: "demoAjax.action",
data: {name: "you param"},
dataType : "json",
type : "POST",
success: function(data){
alert("전송 요청 성공,데이터 반환:"+data.name);
}
});
$.ajax({//요청 이 실 패 했 습 니 다.인성 화 된 오류 메 시 지 를 팝 업 합 니 다.
url: "demoAjax.action",
dataType : "json",
type : "POST",
success: function(data){
alert("전송 요청 성공,데이터 반환:"+data.name);
}
});
데모 페이지 로 돌아 갑 니 다.
오류 페이지 로 돌아 가기
이상 처리 완료.
우 리 는 프로그램 에서 이상 을 처리 할 필요 가 없다.무작정 모두 던 지면 되 고 코드 가 크게 간소화 된다.
요청 처리 상황 은 다음 과 같 습 니 다.
ajax 요청:정상 일 때@ResponseBody 출력 을 사용 합 니 다.오류 가 발생 했 을 때 잘못된 JSON 문자열 을 되 돌려 줍 니 다.
페이지 요청:정상 적 인 경우 이 페이지 에 들 어가 서 요청 이 이상 할 때 오류 페이지 로 돌아 갑 니 다.
JSON 과 이상 처 리 를 인 코딩 하지 않 습 니 다.

좋은 웹페이지 즐겨찾기