2016-12-16 23 views
0

Springブートと休止アプリケーションでは、次のように例外ハンドラを構成しました。要求がサービスを休止した後で例外がスローされた場合、正常に動作します。Springboot例外ハンドラが例外をキャッチしない

Rest apiはContent-Typeが "application/json"であると想定しています。コンテンツタイプのヘッダーをapiに送信しないと、例外ハンドラは例外をキャッチしません。これは、ログに次の情報を出力します。

DEBUG [o.s.w.s.DispatcherServlet] DispatcherServlet with name 'dispatcherServlet' processing PUT request for [/app/v1.0/customers/customer/zones/zoneName.] 
DEBUG [o.s.w.s.m.m.a.RequestMappingHandlerMapping] Looking up handler method for path /app/v1.0/customers/customer/zones/zoneName. 
DEBUG [o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver] Resolving exception from handler [null]: org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'text/plain' not supported 
DEBUG [o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver] Invoking @ExceptionHandler method: public final org.springframework.http.ResponseEntity<java.lang.Object> org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler.handleException(java.lang.Exception,org.springframework.web.context.request.WebRequest) 
DEBUG [o.s.w.s.DispatcherServlet] Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling 
DEBUG [o.s.w.s.DispatcherServlet] Successfully completed request 

ここで例外ハンドラクラスです:

@ControllerAdvice 
@RestController 
public class ServiceExceptionHandler extends ResponseEntityExceptionHandler 
{ 

    @ExceptionHandler(Exception.class) 
    public final ResponseEntity<java.lang.Object> handleException(Throwable ex,WebRequest req) 
    { 
     ErrorResponse errorResponse = null; 
     if (ex instanceof ApiException) 
     { 
      errorResponse = new ErrorResponse((ApiException) ex); 
     } 
     else 
     { 
      logger.error(ex); 
      errorResponse = new ErrorResponse(); 
      errorResponse.setCode(HttpCodes.HTTP_CODE_500); 
      errorResponse.setError(ex.getMessage()); 
     } 
     return new ResponseEntity<Object>(errorResponse, 
       HttpStatus.valueOf(errorResponse.getCode())); 

    } 
    protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex, 
      HttpHeaders headers, HttpStatus status, WebRequest request) 
    { 
     Map<String, String> responseBody = new HashMap<String, String>(); 
     responseBody.put("path", request.getContextPath()); 
     responseBody.put("message", 
       "The URL you have reached is not in service at this time (404)."); 
     return new ResponseEntity<Object>(responseBody, HttpStatus.NOT_FOUND); 
    } 
} 

答えて

2

あなたのクラスでは、唯一のコントローラ内から発生するエラーをキャッチします。表示されているエラーは、コントローラが呼び出される前に発生します。これは、Springが要求を処理するコントローラを見つけることができないためです。

DEBUG [o.s.w.s.m.m.a.RequestMappingHandlerMapping] Looking up handler method for path /app/v1.0/customers/customer/zones/zoneName. 
DEBUG [o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver] Resolving exception from handler [null]: org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'text/plain' not supported 

ハンドラがnullであることに注意してください。

また、例外のタイプを処理するためにHandlerExceptionResolverを実装する必要があります:http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/html/mvc.html#mvc-exceptionhandlers

は詳細についてはSpring exception handler outside controllerを参照してください。

+0

アダムありがとうございます。それは実用的な解決法を見つけるのに本当に良い指針を提供しましたが、それを修正するにはしばらく時間がかかりました。春のように見える2つの例外ハンドラーが好きではない。私はExceptionHandlerExceptionResolverとResponseEntityExceptionHandlerを持っていたので、例外は常にResponseEntityExceptionHandlerに行きました。私はResponseEntity 1を削除し、グローバルExceptionHandlerExceptionResolverだけを保持し、魅力的に機能しました。 – Sannu

0

はここで、最終的なソリューションです:

@ControllerAdvice 
public class SpringExceptionHandler extends ExceptionHandlerExceptionResolver 
{ 
    @ExceptionHandler(org.springframework.web.HttpMediaTypeNotSupportedException.class) 
    public ResponseEntity<Object> handleControllerException(HttpMediaTypeNotSupportedException ex, WebRequest req) 
    { 
     ErrorResponse errorResponse = null; 
     ex.printStackTrace(); 
     errorResponse = new ErrorResponse(); 
     errorResponse.setCode(HttpCodes.HTTP_CODE_INTERNAL_ERROR); 
     errorResponse.setError(ex.getMessage()); 
     return new ResponseEntity<Object>(errorResponse, 
      HttpStatus.valueOf(errorResponse.getCode())); 
    } 
} 

は今、私はそれがスローされたコントローラを含むすべての例外のために動作させるためにいくつかの変更を加える必要があるが、それは後であります。 (感謝のアダム)。

重要:グローバルハンドラとエンティティハンドラがさ​​らにある場合、springはグローバルハンドラを無視します。

関連する問題