spring mvc 출력 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 과 이상 처 리 를 인 코딩 하지 않 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
콘텐츠 SaaS | JSON 스키마 양식 빌더Bloomreach Content를 위한 JSON Form Builder 맞춤형 통합을 개발합니다. 최근 Bloomreach Content SaaS는 내장 앱 프레임워크를 사용하여 혁신적인 콘텐츠 유형 필드를 구축할...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.