新しい答え(2016-04-20)
Spring Boot 1.3.1.RELEASEの使用
新しいステップ1-次のプロパティをapplication.propertiesに追加するのは簡単で、煩わしさはありません。
spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false
既存のDispatcherServletインスタンスを変更するよりもはるかに簡単です(以下を参照)。-JO '
完全なRESTfulアプリケーションを使用する場合は、静的リソースの処理にSpring Bootのデフォルト構成を使用している場合、リソースハンドラーがリクエストを処理するため、静的リソースの自動マッピングを無効にすることが非常に重要です(最後に順序付けされ、/にマップされます) **これは、アプリケーション内の他のハンドラーによって処理されていないリクエストをすべてピックアップすることを意味します。そのため、ディスパッチャーサーブレットは例外をスローする機会を得ません。
新しい回答(2015-12-04)
Spring Boot 1.2.7.RELEASEの使用
新しいステップ1-「throExceptionIfNoHandlerFound」フラグを設定する、それほど煩わしくない方法を見つけました。以下のDispatcherServlet置換コード(ステップ1)を、アプリケーション初期化クラスのこれに置き換えます。
@ComponentScan()
@EnableAutoConfiguration
public class MyApplication extends SpringBootServletInitializer {
private static Logger LOG = LoggerFactory.getLogger(MyApplication.class);
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(MyApplication.class, args);
DispatcherServlet dispatcherServlet = (DispatcherServlet)ctx.getBean("dispatcherServlet");
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
}
この場合、既存のDispatcherServletにフラグを設定します。これにより、Spring Bootフレームワークによる自動構成が保持されます。
私が見つけたもう1つのこと-@EnableWebMvcアノテーションはSpring Bootにとって致命的です。はい、その注釈により、以下で説明するようにすべてのコントローラー例外をキャッチできるなどのことが可能になりますが、Spring Bootが通常提供する便利な自動構成の多くを殺します。Spring Bootを使用するときは、その注釈を細心の注意を払って使用してください。
元の回答:
ここに投稿された解決策についてさらに多くの調査とフォローアップを行った後(助けてくれてありがとう!)、Springコードへの実行時トレースが少なからずありましたが、最終的にすべての例外を処理する構成を見つけました(エラーではなく、読み続けます)。 404を含む。
ステップ1-「ハンドラーが見つからない」状況でMVCの使用を停止するようにSpringBootに指示します。「/ error」へのビューリダイレクトをクライアントに返すのではなく、Springに例外をスローさせたい。これを行うには、構成クラスの1つにエントリが必要です。
// NEW CODE ABOVE REPLACES THIS! (2015-12-04)
@Configuration
public class MyAppConfig {
@Bean // Magic entry
public DispatcherServlet dispatcherServlet() {
DispatcherServlet ds = new DispatcherServlet();
ds.setThrowExceptionIfNoHandlerFound(true);
return ds;
}
}
これの欠点は、デフォルトのディスパッチャーサーブレットを置き換えることです。これはまだ問題ではなく、副作用や実行の問題はありません。他の理由でディスパッチャーサーブレットを使用して何か他のことを行う場合は、ここでそれらを実行します。
ステップ2-ハンドラーが見つからない場合、スプリングブートが例外をスローするようになりました。その例外は、統合された例外ハンドラーで他のユーザーと一緒に処理できます。
@EnableWebMvc
@ControllerAdvice
public class ServiceExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(Throwable.class)
@ResponseBody
ResponseEntity<Object> handleControllerException(HttpServletRequest req, Throwable ex) {
ErrorResponse errorResponse = new ErrorResponse(ex);
if(ex instanceof ServiceException) {
errorResponse.setDetails(((ServiceException)ex).getDetails());
}
if(ex instanceof ServiceHttpException) {
return new ResponseEntity<Object>(errorResponse,((ServiceHttpException)ex).getStatus());
} else {
return new ResponseEntity<Object>(errorResponse,HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Override
protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
Map<String,String> responseBody = new HashMap<>();
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);
}
...
}
ここでは「@EnableWebMvc」アノテーションが重要だと思います。これなしではこれは機能しないようです。以上で、Springブートアプリは上記のハンドラクラスで404を含むすべての例外をキャッチし、好きなように例外を処理できます。
最後にもう1つ、スローされたエラーをキャッチする方法がないようです。私はアスペクトを使用してエラーをキャッチし、それらを上記のコードが処理できる例外に変換するという奇妙なアイデアを持っていますが、実際にそれを実装してみる時間はまだありません。これが誰かを助けることを願っています。
コメント/修正/機能強化は高く評価されます。