본문 바로가기

카테고리 없음

Spring - ajax return success on sevlet error

ajax로 통신하는 도중 sevlet에서 에러가 발생했는데 어처구니없게 ajax success fucntion이 실행 되었다.

왜 그런지 알아보고자 구글링 했으니 영단어의 조합실패인지 찾지 못했고 직접 원인을 찾아보기로 했다.

결론 부터 알고 싶다면 스크롤을 맨 밑으로 향하면 되겠다.

일단 내가 잘못알고 있었던 것인지 확인해보기로 했다.

(코드는 티스토리 에디터에서 직접 작성했기에 에러가 있을수있음)


클라이언트

function testAjax(){
	$.ajax({
		url : "/test/ajax",
		dataType : "html",
		success : function(data, textStatus, jqXHR){
			console.log(data);
			console.log(textStatus);
			console.log(jqXHR);
		},error : function(jqXHR, textStatus, errorThrown){
			console.log(jqXHR);
			console.log(textStatus);
			console.log(errorThrown);
		}
	});
}


서버

@RequestMapping("/test/ajax.do")
public void testAjax() throws Exception{
	throw new Exception();
}


콘솔에서 testAjax()를 호출하니 success function이 호출되며 성공을 자축하는 콘솔로그가 대대적으로 찍힌다.

콘솔로그로 이미 원인을 짐작할 수 있었으나 좀더 테스트해보기로 한다.


서버

@RequestMapping("/test/ajax.do")
public String testAjax() throws Exception{
	return "noPage"
}


결과값이 없을 경우에는 분명 에러가 났었던것 같아 위와 같이 작성하였다. 실제로 리턴되는 noPage라는 jsp는 존재하지 않는다.

실행해 보니 error function이 실행된다. ajax는 거짓말을 하지 않는다.


가장먼저 했던 테스트를 보자면 콘솔 로그에 에러페이지 처리를 했던 jsp 코드가 그대로 찍혀나왔다. 실제로 화면은 변경되어 출력되었다. 서블릿상에서는 에러지만 클라이언트에게 response 해줄 때 서블릿설정에서 별도의 Exception 처리로 인하여 성공코드 200을 주기 때문이 아닐까 싶다. 그래서 찾아봤다. Spring HandlerExceptionResolver.


찾아보니 SimpleMappingExceptionResolver 클래스로 exception 처리해줄 수 있었고 실제로 서버에도 이런 처리가 되어있었다.

<property name="defaultStatusCode" value="500"/>

코드를 추가해주니 기대하던 error function이 실행되었다.


좀 더 구글링 해보니

http://stackoverflow.com/questions/14488281/how-can-i-return-an-error-message-and-http-status-code-that-calls-jquery-ajax-er

나와 같은 경우가 발생된 개발자의 내용을 볼 수 있다. 질문자의 처리 방법또한 한가지 방법이 될 수 있겠다. 하지만 근본적인 문제는 HandlerExceptionResolver에서 처리해줘야 하지 않을까싶다. 논지에서 벗어나지만 요새 구글번역이 인공신경망을 통해 상당히 자연스러운 어휘를 구사한다. 세상 참 좋아졌다. 미래는 생각보다 멀리있지 않은 것 같다.


좀 더 찾아보니..

역시 도큐멘트가 답이다.

setDefaultStatusCode

public void setDefaultStatusCode(int defaultStatusCode)
Set the default HTTP status code that this exception resolver will apply if it resolves an error view and if there is no status code mapping defined.

Note that this error code will only get applied in case of a top-level request. It will not be set for an include request, since the HTTP status cannot be modified from within an include.

If not specified, no status code will be applied, either leaving this to the controller or view, or keeping the servlet engine's default of 200 (OK).

Parameters:
defaultStatusCode - HTTP status code value, for example 500 (HttpServletResponse.SC_INTERNAL_SERVER_ERROR) or 404 (HttpServletResponse.SC_NOT_FOUND)
See Also:
setStatusCodes(Properties)

defaultStatusCode 디폴트값은 200 이다.


결론적으로 HandlerExceptionResolver 코드를 찾아서 defaultStatusCode를 알맞게 처리해주면된다.