Neue Antwort (20.04.2016)
Verwenden von Spring Boot 1.3.1.RELEASE
Neuer Schritt 1 - Es ist einfach und weniger aufdringlich, der application.properties die folgenden Eigenschaften hinzuzufügen:
spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false
Viel einfacher als das Ändern der vorhandenen DispatcherServlet-Instanz (wie unten)! - JO '
Wenn Sie mit einer vollständigen RESTful-Anwendung arbeiten, ist es sehr wichtig, die automatische Zuordnung statischer Ressourcen zu deaktivieren. Wenn Sie die Standardkonfiguration von Spring Boot für die Verarbeitung statischer Ressourcen verwenden, verarbeitet der Ressourcenhandler die Anforderung (sie wird zuletzt bestellt und / zugeordnet) ** Dies bedeutet, dass alle Anforderungen erfasst werden, die von keinem anderen Handler in der Anwendung verarbeitet wurden. Das Dispatcher-Servlet hat also keine Möglichkeit, eine Ausnahme auszulösen.
Neue Antwort (04.12.2015)
Verwenden von Spring Boot 1.2.7.RELEASE
Neuer Schritt 1 - Ich habe eine viel weniger aufdringliche Möglichkeit gefunden, das Flag "throExceptionIfNoHandlerFound" zu setzen. Ersetzen Sie den DispatcherServlet-Ersetzungscode unten (Schritt 1) durch diesen in Ihrer Anwendungsinitialisierungsklasse:
@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);
}
In diesem Fall setzen wir das Flag für das vorhandene DispatcherServlet, wodurch die automatische Konfiguration durch das Spring Boot-Framework beibehalten wird.
Eine weitere Sache, die ich gefunden habe - die Annotation @EnableWebMvc ist für Spring Boot tödlich. Ja, diese Annotation ermöglicht es beispielsweise, alle Controller-Ausnahmen wie unten beschrieben abzufangen, aber sie beendet auch eine Menge der hilfreichen Autokonfiguration, die Spring Boot normalerweise bereitstellen würde. Verwenden Sie diese Anmerkung mit äußerster Vorsicht, wenn Sie Spring Boot verwenden.
Ursprüngliche Antwort:
Nach viel mehr Recherche und Nachverfolgung der hier veröffentlichten Lösungen (danke für die Hilfe!) Und nicht geringer Laufzeitverfolgung im Spring-Code habe ich endlich eine Konfiguration gefunden, die alle Ausnahmen behandelt (keine Fehler, aber weiterlesen). einschließlich 404s.
Schritt 1 - Weisen Sie SpringBoot an, MVC nicht mehr für Situationen zu verwenden, in denen der Handler nicht gefunden wurde. Wir möchten, dass Spring eine Ausnahme auslöst, anstatt eine auf "/ error" umgeleitete Ansicht an den Client zurückzugeben. Dazu benötigen Sie einen Eintrag in einer Ihrer Konfigurationsklassen:
// 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;
}
}
Der Nachteil dabei ist, dass es das Standard-Dispatcher-Servlet ersetzt. Dies war noch kein Problem für uns, da keine Nebenwirkungen oder Ausführungsprobleme auftraten. Wenn Sie aus anderen Gründen etwas anderes mit dem Dispatcher-Servlet tun, ist dies der richtige Ort, um dies zu tun.
Schritt 2 - Nachdem Spring Boot nun eine Ausnahme auslöst, wenn kein Handler gefunden wird, kann diese Ausnahme mit allen anderen in einem einheitlichen Ausnahmebehandler behandelt werden:
@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);
}
...
}
Denken Sie daran, dass ich denke, dass die Annotation "@EnableWebMvc" hier von Bedeutung ist. Es scheint, dass nichts davon ohne es funktioniert. Und das war's - Ihre Spring-Boot-App erkennt jetzt alle Ausnahmen, einschließlich 404s, in der oben genannten Handler-Klasse, und Sie können sie nach Belieben verwenden.
Ein letzter Punkt - es scheint keine Möglichkeit zu geben, dies dazu zu bringen, geworfene Fehler zu fangen. Ich habe eine verrückte Idee, Aspekte zu verwenden, um Fehler zu erkennen und sie in Ausnahmen umzuwandeln, mit denen der obige Code dann umgehen kann, aber ich hatte noch keine Zeit, dies tatsächlich zu implementieren. Hoffe das hilft jemandem.
Alle Kommentare / Korrekturen / Verbesserungen werden geschätzt.