2014-11-17 6 views
3

@ExceptionHandler에 대한 JSON 응답을 보내 주시면 도와 드리겠습니다. 아득히 내가이 방법에 대한 응답을 처리하는보기 해결 프로그램을 구성해야합니다 이해합니다. 제 코드를 살펴보십시오. 컨트롤러 조언 :Spring 3.2 @ExceptionHandler @ResponseBody Jackson을 통한 JSON 응답

import java.util.List; 
import java.util.Locale; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.MessageSource; 
import org.springframework.context.i18n.LocaleContextHolder; 
import org.springframework.http.HttpStatus; 
import org.springframework.validation.BindingResult; 
import org.springframework.validation.FieldError; 
import org.springframework.web.bind.MethodArgumentNotValidException; 
import org.springframework.web.bind.annotation.ControllerAdvice; 
import org.springframework.web.bind.annotation.ExceptionHandler; 
import org.springframework.web.bind.annotation.ResponseBody; 
import org.springframework.web.bind.annotation.ResponseStatus; 

import com.models.ValidationErrorDTO; 

@ControllerAdvice 
public class RestErrorHandler { 

    private MessageSource messageSource; 

    @Autowired 
    public RestErrorHandler(MessageSource messageSource) { 
     this.messageSource = messageSource; 
    } 

    @ExceptionHandler(MethodArgumentNotValidException.class) 
    @ResponseStatus(HttpStatus.BAD_REQUEST) 
    @ResponseBody 
    public ValidationErrorDTO processValidationError(
      MethodArgumentNotValidException ex) { 
     System.out.println("IN THE EXCEPTION HANDLER !!!!"); 
     BindingResult result = ex.getBindingResult(); 
     List<FieldError> fieldErrors = result.getFieldErrors(); 

     return processFieldErrors(fieldErrors); 
    } 

    private ValidationErrorDTO processFieldErrors(List<FieldError> fieldErrors) { 
     ValidationErrorDTO dto = new ValidationErrorDTO(); 

     for (FieldError fieldError : fieldErrors) { 
      String localizedErrorMessage = resolveLocalizedErrorMessage(fieldError); 
      dto.addFieldError(fieldError.getField(), localizedErrorMessage); 
     } 

     return dto; 
    } 

    private String resolveLocalizedErrorMessage(FieldError fieldError) { 
     Locale currentLocale = LocaleContextHolder.getLocale(); 
     String localizedErrorMessage = messageSource.getMessage(fieldError, 
       currentLocale); 

     // If the message was not found, return the most accurate field error 
     // code instead. 
     // You can remove this check if you prefer to get the default error 
     // message. 
     if (localizedErrorMessage.equals(fieldError.getDefaultMessage())) { 
      String[] fieldErrorCodes = fieldError.getCodes(); 
      localizedErrorMessage = fieldErrorCodes[0]; 
     } 
     System.out.println("THE MESSAGE IS :: " + localizedErrorMessage); 
     return localizedErrorMessage; 
    } 
} 

내 응용 프로그램에있는 Jackson View Resolver.

<bean id="jacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper" /> 
<bean id="jacksonSerializationConfig" class="org.codehaus.jackson.map.SerializationConfig" 
    factory-bean="jacksonObjectMapper" factory-method="getSerializationConfig" /> 
<bean 
    class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> 
    <property name="targetObject" ref="jacksonSerializationConfig" /> 
    <property name="targetMethod" value="setSerializationInclusion" /> 
    <property name="arguments"> 
     <list> 
      <value type="org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion">NON_DEFAULT</value> 
     </list> 
    </property> 
</bean> 

지금 나는 내가 @ExceptionHandler 방법에 대한 @ResponseBody 작업을 얻기 위해이 같은 것을 추가해야 같아요.

<!-- JSON format support for Exception --> 
    <bean id="methodHandlerExceptionResolver" 
     class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver"> 
     <property name="messageConverters"> 
      <list> 
       <ref bean="jacksonMessageConverter" /> 
      </list> 
     </property> 
    </bean> 
    <bean id="jacksonMessageConverter" 
     class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean> 

하지만 내부적으로 어떻게 작동하는지 잘 모릅니다.

02:09:28,030 ERROR [org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver] (http--127.0.0.1-8080-1) Failed to invoke @ExceptionHandler method: public com.models.ValidationErrorDTO com.RestErrorHandler.processValidationError(org.springframework.web.bind.MethodArgumentNotValidException): org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation 
    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:126) [spring-webmvc-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:90) [spring-webmvc-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:189) [spring-webmvc-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:69) [spring-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:122) [spring-webmvc-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.doResolveHandlerMethodException(ExceptionHandlerExceptionResolver.java:321) [spring-webmvc-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionResolver.doResolveException(AbstractHandlerMethodExceptionResolver.java:60) [spring-webmvc-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:136) [spring-webmvc-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.web.servlet.DispatcherServlet.processHandlerException(DispatcherServlet.java:1148) [spring-webmvc-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:985) [spring-webmvc-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:939) [spring-webmvc-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856) [spring-webmvc-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:920) [spring-webmvc-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:827) [spring-webmvc-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:754) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final] 
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:801) [spring-webmvc-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final] 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.13.Final.jar:] 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118) [spring-security-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84) [spring-security-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) [spring-security-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103) [spring-security-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113) [spring-security-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154) [spring-security-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45) [spring-security-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150) [spring-security-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199) [spring-security-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110) [spring-security-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50) [spring-security-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) [spring-security-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) [spring-security-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) [spring-security-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) [spring-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259) [spring-web-3.2.1.RELEASE.jar:3.2.1.RELEASE] 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.13.Final.jar:] 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:] 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.13.Final.jar:] 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.13.Final.jar:] 
    at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final] 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.13.Final.jar:] 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.13.Final.jar:] 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.13.Final.jar:] 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.13.Final.jar:] 
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.13.Final.jar:] 
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) [jbossweb-7.0.13.Final.jar:] 
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) [jbossweb-7.0.13.Final.jar:] 
    at java.lang.Thread.run(Thread.java:745) [rt.jar:1.7.0_65] 

참고 : http://www.petrikainulainen.net/programming/spring-framework/spring-from-the-trenches-adding-validation-to-a-rest-api/

Spring @ExceptionHandler does not work with @ResponseBody

http://www.waheedtechblog.in/2013/01/how-exceptionhandler-return-json-in.html

+0

[this] (http://ankursinghal86.blogspot.jp/2014/07/exception-handling-in-spring-mvc.html) 도움이 –

+0

어떻게 테스트하나요? 컬을 사용하고 있습니까? 그렇다면, 사용하고있는 컬 명령은 무엇입니까? – Jigish

+0

@ Alind Billore, 나는 Spring 3.2와 비슷한 문제에 직면 해있다. 이 문제를 해결할 수 있었습니까? – Lihini

답변

3

은 단순히 당신이 가고있는 객체에 대한 getter와 setter를 추가

내가 점점 오전 오류입니다 돌려 주다.

내가했던 튜토리얼은 게터를 생략하고이 모든 것이 작동하지 않았다.

그래서 나에게 이것은 그 것이었다!

+0

비슷한 문제가 있습니다. 어떤 물체를 반환하는지 물어볼 수 있습니까? 게터를 어디에 두었습니까? – osmingo

+0

반환 방식이 무엇이든, JSON으로 실제로 반환되기를 원하는 클래스에는 getter와 setter가 있어야합니다. 따라서 Jackson은 해당 필드를 가져 와서 JSON 문자열로 변환 할 수 있습니다. –

1

나는이 일을 시도 : 컨트롤러

@ExceptionHandler(DataException.class) 
@ResponseBody 
public ResponseEntity<String> handleException(DataException e, HttpServletResponse response) { 
    log.error(e); 
    response.setContentType("application/json;charset=UTF-8"); 
    response.setHeader("Content-Type", "application/json; charset=utf-8"); 
    response.setCharacterEncoding("UTF-8"); 
    if (e.getRootCause() instanceof SQLException) { 
     SQLException s = (SQLException) e.getRootCause(); 
     return CommonUtil.getErrorResponse(ErrorToResponse.getJsonSqlError(s.getMessage(), s.getSQLState())); 
    } else { 
     log.error(e); 
     return CommonUtil.getErrorResponse(ErrorToResponse.getJsonError(e.getMessage())); 
    } 
} 
이 새로운 ResponseEntity 및 getJsonSqlError() 반환 JSON 문자열을 반환 getErrorResponse

그런

<bean class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver"> 
    <property name="messageConverters"> 
     <array> 
      <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> 
       <property name="supportedMediaTypes"> 
        <list> 
         <value>text/plain;charset=UTF-8</value> 
         <value>text/html;charset=UTF-8</value> 
         <value>application/json;charset=UTF-8</value> 
         <value>application/x-www-form-urlencoded;charset=UTF-8</value> 
        </list> 
       </property> 
      </bean> 
     </array> 
    </property> 
</bean> 

과 받는다는 dependencie를 추가 :

<dependency> 
     <groupId>com.fasterxml.jackson.core</groupId> 
     <artifactId>jackson-databind</artifactId> 
     <version>2.8.3</version> 
    </dependency> 

저의 작품입니다.