web-dev-qa-db-ja.com

スプリングレスト空のリクエストボディの処理(400 Bad Request)

Spring4を使用してRESTfulアプリを開発しています。 POSTリクエストでボディが渡されなかった場合のケースを処理したい。カスタム例外ハンドラを記述した:

@ControllerAdvice
public class MyRestExceptionHandler {

  @ExceptionHandler
  @ResponseStatus(HttpStatus.BAD_REQUEST)
  public ResponseEntity<MyErrorResponse> handleJsonMappingException(JsonMappingException ex) {
      MyErrorResponse errorResponse = new MyErrorResponse("request has empty body");
      return new ResponseEntity<MyErrorResponse>(errorResponse, HttpStatus.BAD_REQUEST);
  }   
  @ExceptionHandler(Throwable.class)
  public ResponseEntity<MyErrorResponse> handleDefaultException(Throwable ex) {
    MyErrorResponse errorResponse = new MyErrorResponse(ex);
    return new ResponseEntity<MyErrorResponse>(errorResponse, HttpStatus.BAD_REQUEST);
  }

}
 @RestController
 public class ContactRestController{
    @RequestMapping(path="/contact", method=RequestMethod.POST)
    public void save(@RequestBody ContactDTO contactDto) {...}
 } 

しかし、それが発生した場合、これらのメソッドは呼び出されません。 400 BAD REQUEST httpステータスと空のボディで応答を受け取りました。誰かがそれを処理する方法を知っていますか?

7
rvit34

捕まえる方法を見つけました。私の解決策は:

    @ControllerAdvice
    public class RestExceptionHandler extends ResponseEntityExceptionHandler {

        @Override
        protected ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
            // paste custom hadling here
        }
    }
15
rvit34

@ControllerAdviceで注釈されたクラスがすでにあり、新しいクラスを作成したくない場合は、次のコードを使用できます。

@ExceptionHandler(HttpMessageNotReadableException.class)
public ResponseEntity<?> handleMissingRequestBody(Exception ex) {
    return handle(BAD_REQUEST, ex);
}

rvit34のソリューションと同じ動作になります。

2
www

私は同様の問題に直面しましたが、提供されたcomponent-scanpackageに、私の@ControllerAdviceが提供されたパッケージが含まれていなかったため、うまくいきませんでした。

私のXMLは:

<context:component-scan base-package="com.bandi.rest" />

パッケージにタイプミスcom.bandi.test.spring.exceptionがありました。 com.bandi.rest.spring.exceptionに変更した後、機能し始めました。

@ControllerAdvice
public class SpringRestExceptionHandler {

    @ExceptionHandler(NoHandlerFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public @ResponseBody ResponseEntity<ErrorResponse> handleNoMethodException(HttpServletRequest request,
            NoHandlerFoundException ex) {
        ErrorResponse errorResponse = new ErrorResponse(ex);
        errorResponse.setErrorMessage("resource not found with exception");
        return new ResponseEntity<ErrorResponse>(errorResponse, HttpStatus.NOT_FOUND);
    }

    @ExceptionHandler(Throwable.class)
    public @ResponseBody ResponseEntity<ErrorResponse> handleDefaultException(Throwable ex) {
        ErrorResponse errorResponse = new ErrorResponse(ex);
        errorResponse.setErrorMessage("request has empty body  or exception occured");
        return new ResponseEntity<ErrorResponse>(errorResponse, HttpStatus.BAD_REQUEST);
    }
}

また、要求されたリソースが見つからなかった(悪いURL)シナリオを処理する必要がある場合は、ディスパッチャーサーブレットに別の構成を追加する必要があります。

<servlet>
    <servlet-name>dispatcher</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>2</load-on-startup>
</servlet>

完全な動作コードが利用可能 ここ

1
Bandi Kishore

私の場合、無効なパラメーターを持つすべての要求を処理する必要があります。そこで、クラスをResponseEntityExceptionHandlerで拡張し、メソッドhandleMissingServletRequestParameterをオーバーライドします。クラス内で定義された独自のハンドラーを見つけることができますResponseEntityExceptionHandler

@ControllerAdvice 
public class YourExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(Exception.class)
    public final ResponseEntity handleAllExceptions(Exception ex) {
        // Log and return
    }

    @Override
    public ResponseEntity<Object> handleMissingServletRequestParameter(MissingServletRequestParameterException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
        // Do your code here
        return new ResponseEntity<>("YOUR REQUEST PARAMS NOT MATCH!");
    } 
}
1