Я сам стикався з цією проблемою, і я виконав наведені нижче дії, щоб повторно використовувати моє ExceptionController
описуване @ControllerAdvise
для Exceptions
кинутого в зареєстрований фільтр.
Очевидно, що існує багато способів обробки винятку, але, в моєму випадку, я хотів, щоб виняток оброблявся моїм, ExceptionController
тому що я впертий, а також тому, що я не хочу копіювати / вставляти один і той же код (тобто у мене є обробка / реєстрація код в ExceptionController
). Я хотів би повернути прекрасну JSON
відповідь так само, як і інші винятки, викинуті не з фільтра.
{
"status": 400,
"message": "some exception thrown when executing the request"
}
У будь-якому випадку, мені вдалося скористатися своїм, ExceptionHandler
і мені довелося зробити трохи додаткового, як показано нижче в кроках:
Кроки
- У вас є спеціальний фільтр, який може або не може викидати виняток
- У вас є контролер Spring, який обробляє винятки, використовуючи,
@ControllerAdvise
наприклад, MyExceptionController
Зразок коду
//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);
}
}
А тепер зразок Spring Controller, який обробляє Exception
в звичайних випадках (тобто винятки, які зазвичай не кидаються на рівні Filter, той, який ми хочемо використовувати для виключень, викинутих у Filter)
//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
}
Спільний доступ до рішення з тими, хто бажає використовувати ExceptionController
для Exceptions
кинутого у фільтр.