Ich bin selbst auf dieses Problem gestoßen und habe die folgenden Schritte ausgeführt, um mein ExceptionController
mit Anmerkungen versehenes Problem @ControllerAdvise
für Exceptions
die Verwendung in einem registrierten Filter wiederzuverwenden .
Es gibt offensichtlich viele Möglichkeiten, Ausnahmen zu behandeln, aber in meinem Fall wollte ich, dass die Ausnahme von meinem behandelt wird, ExceptionController
weil ich hartnäckig bin und auch nicht den gleichen Code kopieren / einfügen möchte (dh ich habe etwas Verarbeitung / Protokollierung Code in ExceptionController
). Ich möchte die schöne JSON
Antwort zurückgeben, genau wie die restlichen Ausnahmen, die nicht von einem Filter ausgelöst wurden.
{
"status": 400,
"message": "some exception thrown when executing the request"
}
Wie auch immer, ich habe es geschafft, meine zu nutzen, ExceptionHandler
und ich musste ein bisschen mehr tun, wie unten in Schritten gezeigt:
Schritte
- Sie haben einen benutzerdefinierten Filter, der möglicherweise eine Ausnahme auslöst oder nicht
- Sie haben einen Spring-Controller, der Ausnahmen mit
@ControllerAdvise
MyExceptionController behandelt
Beispielcode
//sample Filter, to be added in web.xml
public MyFilterThatThrowException implements Filter {
//Spring Controller annotated with @ControllerAdvise which has handlers
//for exceptions
private MyExceptionController myExceptionController;
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void init(FilterConfig arg0) throws ServletException {
//Manually get an instance of MyExceptionController
ApplicationContext ctx = WebApplicationContextUtils
.getRequiredWebApplicationContext(arg0.getServletContext());
//MyExceptionHanlder is now accessible because I loaded it manually
this.myExceptionController = ctx.getBean(MyExceptionController.class);
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
try {
//code that throws exception
} catch(Exception ex) {
//MyObject is whatever the output of the below method
MyObject errorDTO = myExceptionController.handleMyException(req, ex);
//set the response object
res.setStatus(errorDTO .getStatus());
res.setContentType("application/json");
//pass down the actual obj that exception handler normally send
ObjectMapper mapper = new ObjectMapper();
PrintWriter out = res.getWriter();
out.print(mapper.writeValueAsString(errorDTO ));
out.flush();
return;
}
//proceed normally otherwise
chain.doFilter(request, response);
}
}
Und jetzt der Beispiel-Spring-Controller, der Exception
in normalen Fällen behandelt wird (dh Ausnahmen, die normalerweise nicht in der Filterebene ausgelöst werden, die wir für Ausnahmen verwenden möchten, die in einem Filter ausgelöst werden).
//sample SpringController
@ControllerAdvice
public class ExceptionController extends ResponseEntityExceptionHandler {
//sample handler
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
@ExceptionHandler(SQLException.class)
public @ResponseBody MyObject handleSQLException(HttpServletRequest request,
Exception ex){
ErrorDTO response = new ErrorDTO (400, "some exception thrown when "
+ "executing the request.");
return response;
}
//other handlers
}
Teilen Sie die Lösung mit denen, die sie ExceptionController
für Exceptions
einen Filter verwenden möchten .