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ステータスと空のボディで応答を受け取りました。誰かがそれを処理する方法を知っていますか?
捕まえる方法を見つけました。私の解決策は:
@ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
// paste custom hadling here
}
}
@ControllerAdvice
で注釈されたクラスがすでにあり、新しいクラスを作成したくない場合は、次のコードを使用できます。
@ExceptionHandler(HttpMessageNotReadableException.class)
public ResponseEntity<?> handleMissingRequestBody(Exception ex) {
return handle(BAD_REQUEST, ex);
}
rvit34のソリューションと同じ動作になります。
私は同様の問題に直面しましたが、提供されたcomponent-scan
packageに、私の@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>
完全な動作コードが利用可能 ここ
私の場合、無効なパラメーターを持つすべての要求を処理する必要があります。そこで、クラスを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!");
}
}