2016-11-15 5 views
2

私はSpring 4 MVCを使用してREST APIを作成しています。 無効なエンドポイントが要求されたときに、デフォルトのJSONエラーオブジェクトを配信できるようにしたいと思います。 私は適切に使用してみました@ControllerAdviceと@ExceptionHandler、について読んだ:@ControllerAdviceはResponseEntityの返信に失敗します<T>(TはPOJOです)

package com.yopyop.wackend.controller; 

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

import org.springframework.http.HttpHeaders; 
import org.springframework.http.HttpStatus; 
import org.springframework.http.MediaType; 
import org.springframework.http.ResponseEntity; 
import org.springframework.web.bind.annotation.ControllerAdvice; 
import org.springframework.web.bind.annotation.ExceptionHandler; 

import org.springframework.web.context.request.WebRequest; 
import org.springframework.web.servlet.NoHandlerFoundException; 

import com.yopyop.wackend.controller.ErrorResponse; 
import com.yopyop.wackend.service.NotFoundException; 


@ControllerAdvice 
public class ExceptionControllerAdvice { 

    @ExceptionHandler(Exception.class) 
    public ResponseEntity<ErrorResponse> exceptionHandler(Exception ex) { 

     ErrorResponse error = new ErrorResponse(); 
     error.setErrorCode(HttpStatus.INTERNAL_SERVER_ERROR.value()); 

     if (ex.getClass()==NotFoundException.class) { 
      error.setMessage("ExceptionControllerAdvice() Not found"); 
      error.setErrorCode(HttpStatus.NOT_FOUND.value()); 
      return new ResponseEntity<ErrorResponse>(error, HttpStatus.NOT_FOUND); 
     } 
     else { 
      error.setMessage("ExceptionControllerAdvice() " + ex.getClass() + "(" + ex.getMessage() + ")"); 
      error.setErrorCode(HttpStatus.INTERNAL_SERVER_ERROR.value()); 
     } 

     return new ResponseEntity<ErrorResponse>(error, HttpStatus.INTERNAL_SERVER_ERROR); 
    } 

    @ExceptionHandler({NoHandlerFoundException.class}) 
    ResponseEntity<ErrorResponse> handleNoHandlerFoundException(NoHandlerFoundException ex, 
      WebRequest request) { 

     HttpHeaders headers = new HttpHeaders(); 
     headers.setContentType(MediaType.APPLICATION_JSON); 

     ErrorResponse error = new ErrorResponse(); 
     error.setErrorCode(HttpStatus.INTERNAL_SERVER_ERROR.value()); 
     error.setMessage("ExceptionControllerAdvice() " + ex.getClass() + "(" + ex.getMessage() + ")"); 

     return new ResponseEntity<ErrorResponse>(error, HttpStatus.INTERNAL_SERVER_ERROR); 
    } 
} 

私はErrorResponseクラスは以下の通りである:

package com.yopyop.wackend.controller; 

public class ErrorResponse { 
    private int errorCode; 
    private String message; 

    public int getErrorCode() { 
     return errorCode; 
    } 
    public void setErrorCode(int errorCode) { 
     this.errorCode = errorCode; 
    } 
    public String getMessage() { 
     return message; 
    } 
    public void setMessage(String message) { 
     this.message = message; 
    } 
} 

NoHandlerFoundように、私はweb.xmlのを修正例外がスローされます。マップされていないエンドポイントへの要求が受信された

<!DOCTYPE web-app PUBLIC 
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" 
"http://java.sun.com/dtd/web-app_2_3.dtd" > 

<web-app> 
    <display-name>Wackend WebApp</display-name> 
    <servlet> 
<servlet-name>wackend</servlet-name> 
<servlet-class> 
    org.springframework.web.servlet.DispatcherServlet 
</servlet-class> 
<init-param> 
    <param-name>throwExceptionIfNoHandlerFound</param-name> 
    <param-value>true</param-value> 
</init-param> 

<load-on-startup>1</load-on-startup> 
</servlet> 

<servlet-mapping> 
<servlet-name>wackend</servlet-name> 
<url-pattern>/</url-pattern> 
</servlet-mapping> 
</web-app> 

Nevethelessを、私が取得:

> 22:47:28.545 [http-nio-8080-exec-15] DEBUG 
> o.s.web.servlet.DispatcherServlet - DispatcherServlet with name 
> 'wackend' processing GET request for [/wackend/swagger-ui.html] 
> 22:47:28.548 [http-nio-8080-exec-15] DEBUG 
> o.s.w.s.m.m.a.RequestMappingHandlerMapping - Looking up handler method 
> for path /swagger-ui.html 22:47:28.552 [http-nio-8080-exec-15] DEBUG 
> o.s.w.s.m.m.a.RequestMappingHandlerMapping - Returning handler method 
> [public void 
> com.yopyop.wackend.controller.DefaultController.unmappedRequest(javax.servlet.http.HttpServletRequest) 
> throws org.springframework.web.servlet.NoHandlerFoundException] 
> 22:47:28.552 [http-nio-8080-exec-15] DEBUG 
> o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of 
> singleton bean 'defaultController' 22:47:28.553 
> [http-nio-8080-exec-15] DEBUG o.s.web.servlet.DispatcherServlet - 
> Last-Modified value for [/wackend/swagger-ui.html] is: -1 22:47:28.566 
> [http-nio-8080-exec-15] DEBUG 
> o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Resolving exception 
> from handler [public void 
> com.yopyop.wackend.controller.DefaultController.unmappedRequest(javax.servlet.http.HttpServletRequest) 
> throws org.springframework.web.servlet.NoHandlerFoundException]: 
> org.springframework.web.servlet.NoHandlerFoundException: No handler 
> found for GET /wackend/swagger-ui.html, headers={} 22:47:28.567 
> [http-nio-8080-exec-15] DEBUG o.s.b.f.s.DefaultListableBeanFactory - 
> Returning cached instance of singleton bean 
> 'exceptionControllerAdvice' 22:47:28.567 [http-nio-8080-exec-15] DEBUG 
> o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Invoking 
> @ExceptionHandler method: 
> org.springframework.http.ResponseEntity<com.yopyop.wackend.controller.ErrorResponse> 
> com.yopyop.wackend.controller.ExceptionControllerAdvice.handleNoHandlerFoundException(org.springframework.web.servlet.NoHandlerFoundException,org.springframework.web.context.request.WebRequest) 
> 22:47:28.603 [http-nio-8080-exec-15] ERROR 
> o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Failed to invoke 
> @ExceptionHandler method: 
> org.springframework.http.ResponseEntity<com.yopyop.wackend.controller.ErrorResponse> 
> com.yopyop.wackend.controller.ExceptionControllerAdvice.handleNoHandlerFoundException(org.springframework.web.servlet.NoHandlerFoundException,org.springframework.web.context.request.WebRequest) 
> org.springframework.web.HttpMediaTypeNotAcceptableException: Could not 
> find acceptable representation at 
> org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:134) 
> ~[spring-webmvc-4.1.6.RELEASE.jar:4.1.6.RELEASE] at 
> org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:146) 
> ~[spring-webmvc-4.1.6.RELEASE.jar:4.1.6.RELEASE] at 
> org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:71) 
> ~[spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE] [...] at 
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
> [na:1.8.0_101] at 
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
> [na:1.8.0_101] at 
> org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
> [tomcat-util.jar:8.0.36] at java.lang.Thread.run(Thread.java:745) 
> [na:1.8.0_101] 22:47:28.603 [http-nio-8080-exec-15] DEBUG 
> o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Resolving exception 
> from handler [public void 
> com.yopyop.wackend.controller.DefaultController.unmappedRequest(javax.servlet.http.HttpServletRequest) 
> throws org.springframework.web.servlet.NoHandlerFoundException]: 
> org.springframework.web.servlet.NoHandlerFoundException: No handler 
> found for GET /wackend/swagger-ui.html, headers={} 22:47:28.603 
> [http-nio-8080-exec-15] DEBUG o.s.b.f.s.DefaultListableBeanFactory - 
> Returning cached instance of singleton bean 
> 'exceptionControllerAdvice' 22:47:28.603 [http-nio-8080-exec-15] DEBUG 
> o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Invoking 
> @ExceptionHandler method: 
> org.springframework.http.ResponseEntity<com.yopyop.wackend.controller.ErrorResponse> 
> com.yopyop.wackend.controller.ExceptionControllerAdvice.handleNoHandlerFoundException(org.springframework.web.servlet.NoHandlerFoundException,org.springframework.web.context.request.WebRequest) 
> 22:47:28.604 [http-nio-8080-exec-15] ERROR 
> o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Failed to invoke 
> @ExceptionHandler method: 
> org.springframework.http.ResponseEntity<com.yopyop.wackend.controller.ErrorResponse> 
> com.yopyop.wackend.controller.ExceptionControllerAdvice.handleNoHandlerFoundException(org.springframework.web.servlet.NoHandlerFoundException,org.springframework.web.context.request.WebRequest) 
> org.springframework.web.HttpMediaTypeNotAcceptableException: Could not 
> find acceptable representation at 
> org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:134) 
> ~[spring-webmvc-4.1.6.RELEASE.jar:4.1.6.RELEASE] at 
> org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:146) 
> ~[spring-webmvc-4.1.6.RELEASE.jar:4.1.6.RELEASE] at 
> org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:71) 
> ~[spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]  at 
> org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:126) 
> ~[spring-webmvc-4.1.6.RELEASE.jar:4.1.6.RELEASE] [...] at 
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
> [na:1.8.0_101] at 
> org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
> [tomcat-util.jar:8.0.36] at java.lang.Thread.run(Thread.java:745) 
> [na:1.8.0_101] 22:47:28.604 [http-nio-8080-exec-15] DEBUG 
> o.s.w.s.m.a.ResponseStatusExceptionResolver - Resolving exception from 
> handler [public void 
> com.yopyop.wackend.controller.DefaultController.unmappedRequest(javax.servlet.http.HttpServletRequest) 
> throws org.springframework.web.servlet.NoHandlerFoundException]: 
> org.springframework.web.servlet.NoHandlerFoundException: No handler 
> found for GET /wackend/swagger-ui.html, headers={} 22:47:28.604 
> [http-nio-8080-exec-15] DEBUG 
> o.s.w.s.m.s.DefaultHandlerExceptionResolver - Resolving exception from 
> handler [public void 
> com.yopyop.wackend.controller.DefaultController.unmappedRequest(javax.servlet.http.HttpServletRequest) 
> throws org.springframework.web.servlet.NoHandlerFoundException]: 
> org.springframework.web.servlet.NoHandlerFoundException: No handler 
> found for GET /wackend/swagger-ui.html, headers={} 22:47:28.604 
> [http-nio-8080-exec-15] DEBUG o.s.web.servlet.DispatcherServlet - Null 
> ModelAndView returned to DispatcherServlet with name 'wackend': 
> assuming HandlerAdapter completed request handling 22:47:28.604 
> [http-nio-8080-exec-15] DEBUG o.s.web.servlet.DispatcherServlet - 
> Successfully completed request 

標準のTomcat 404ページが返されます。 してくださいではないこと:

  1. リターン新しいResponseEntity(エラー、 HttpStatus.INTERNAL_SERVER_ERROR)。

    (Tomcatの デフォルトのページよりも良い)、空のボディ

  2. リターン新しいResponseEntity( "woot"、 HttpStatus.INTERNAL_SERVER_ERROR)とHTTP 500が返されます。 wootを本体としてHTTP 500を返します。

ErrorResponseクラスでJSONマッピングを実行できないようです。

私はデフォルトコントローラーを使用していますが、@ControllerAdviceを使用しているので、これは役に立たないと思います。私は情報のためにここに貼り付け:

package com.yopyop.wackend.controller; 

import javax.servlet.http.HttpServletRequest; 

import org.springframework.http.HttpHeaders; 
import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.servlet.NoHandlerFoundException; 

/** 
* Default controller that exists to return a proper REST response for unmapped requests. 
*/ 
@Controller 
public class DefaultController { 

    @RequestMapping("/**") 
    public void unmappedRequest(HttpServletRequest request) throws NoHandlerFoundException { 
     String uri = request.getRequestURI(); 
     String method = request.getMethod(); 
     HttpHeaders h = new HttpHeaders(); 

     throw new NoHandlerFoundException(method, uri, h); 
    } 
} 

私のRESTのAPIもResponseEntity>リターン<を使用し、適切なJSONペイロードを返すことに成功しました。

答えて

0

答えが正確か分かりませんが、問題はJSON構成にあります。あなたの@Controllerは@RestControllerではなく、生成されたものを明示的に指定していません。私はあなたの要求でこれを行うことを望むので、春は何をすべきかを知っています。 @ControllerのMIMEタイプは継承され、変換に使用されていると思います。

httpメッセージコンバータにブレークポイントを追加しようとする場合があります。すべてのコンバーターには、supportsのコードがここにあります。どのコンバータが真を返すかチェックしてください。複数の条件を満たす場合、最初のものが使用されます。 stacktraceを参照すると、要求に応じて使用できるコンバータと、必要なコンバータの種類がわかります。

http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/converter/AbstractHttpMessageConverter.html#supports-java.lang.Class-

関連する問題