spring MVC @ExceptionHandler метод получить тот же вид
моя проблема в том, что я хочу создать метод @ExceptionHandler, который будет захватывать все необработанные исключения. После захвата я хотел бы перенаправить на текущую страницу вместо указания отдельной страницы только для отображения ошибки.
в основном, как мне получить значение someview возвращено что-то вроде и установить его динамически в методе unhandledExceptionHandler ниже.
@ExceptionHandler(Exception.class)
protected ModelAndView unhandledExceptionHandler(Exception ex){
System.out.println("unhandle exception here!!!");
ModelAndView mv = new ModelAndView();
mv.setViewName("currentview");
mv.addObject("UNHANDLED_ERROR", "UNHANDLED ERROR. PLEASE CONTACT SUPPORT. "+ex.getMessage());
return mv;
}
@RequestMapping(value = "/somepage", method = RequestMethod.GET)
public String somemethod(HttpSession session) throws Exception {
String abc = null;
abc.length();
return "someview";
}
поэтому в JSP я могу визуализировать это сообщение об ошибке возвращается на текущую страницу что-то вроде этого.
<c:if test="${not empty UNHANDLED_ERROR}">
<div class="messageError"> ${UNHANDLED_ERROR}</div>
</c:if>
5 ответов
Я не думаю, что есть способ сделать то, что вы просите, потому что в методе обработчика исключений unhandledExceptionHandler
нет способа узнать, какое имя представления имеет метод обработчика somemethod
вернули бы.
единственный способ-ввести какую-то схему метаданных, чтобы, когда вы окажетесь в обработчике исключений, вы могли выяснить, к какому виду его сопоставить. Но я думаю, что эта схема метаданных будет довольно сложной. Вы можете реализовать такую схему с помощью чтобы узнать, какой исходный url-адрес был доступен при возникновении исключения, это можно сделать с помощью фрагмента кода ниже.
(ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest()
как только вы узнаете, какой исходный URL-адрес запроса вы можете перенаправить на него, возможно, используя атрибут flash, чтобы сохранить тот факт, что было исключение и какая ошибка.
основная проблема с метаданными будет возникать, когда у вас есть метод обработчика, который выбирает между различными представлениями что-то как.
@RequestMapping(value = "/somepage", method = RequestMethod.GET)
public String somemethod(HttpSession session) throws Exception {
String abc = null;
if(someCondition) {
abc.length();
return "someview";
} else {
// do some stuff here.
return "someOtherView";
}
}
даже зная, что somemethod был источником ошибки, вы не знаете, какая ветвь в операторе if вызвала исключение.
Я не думаю, что вы можете сделать это без изменения всех методов обработчика. Однако вы можете попытаться сделать это "красивым" способом:
1) Вы можете определить свою собственную аннотацию, которая будет принимать имя целевого вида в качестве параметра (например,@ExceptionView
)
2) Следующее, что нужно сделать, это пометить ваши методы обработчика, например:
@ExceptionView("someview")
@RequestMapping(value = "/somepage", method = RequestMethod.GET)
public String somemethod(HttpSession session) throws Exception {
String abc = null;
abc.length();
return "someview";
}
3) После этого вы можете сделать что-то вроде этого в обработчик исключений:
@ExceptionHandler(Exception.class)
protected ModelAndView unhandledExceptionHandler(Exception ex, HandlerMethod hm) {
String targetView;
if (hm != null && hm.hasMethodAnnotation(ExceptionView.class)) {
targetView = hm.getMethodAnnotation(ExceptionView.class).getValue();
} else {
targetView = "someRedirectView"; // kind of a fallback
}
ModelAndView mv = new ModelAndView();
mv.setViewName(targetView);
mv.addObject("UNHANDLED_ERROR", "UNHANDLED ERROR. PLEASE CONTACT SUPPORT. "+ex.getMessage());
return mv;
}
вместо отправки ошибки на отдельной странице вы можете просто поместить ошибку в объект ModelAndView. В вашем случае вы можете просто поместить try/catch в свой метод контроллера и вернуть тот же вид, что и так:
@RequestMapping(value = "/somepage", method = RequestMethod.GET)
public String somemethod(ModelAndView mv,HttpSession session) throws Exception {
mv.setViewName("someview");
try{
String abc = null;
abc.length();
} catch(Exception e) {
mv.addObject("UNHANDLED_ERROR", "UNHANDLED ERROR. PLEASE CONTACT SUPPORT. "+ex.getMessage());
}
return mv;
}
поэтому добавьте ModelAndView в свой метод и верните его.
Я не пробовал это, но на основе документации здесь, мы можем получить объект запроса в обработчик исключений. Возможно, мы не сможем получить представление, связанное с URL-адресом. Получение представления из URL-адреса и состояние/модель представления будут сложной частью.
@ExceptionHandler(Exception.class)
public ModelAndView handleError(HttpServletRequest req, Exception ex) {
logger.error("Request: " + req.getRequestURL() + " raised " + ex);
ModelAndView mav = new ModelAndView();
mav.addObject("exception", ex);
mav.addObject("url", req.getRequestURL());
mav.setViewName("error");
return mav;
}
- создать метод контроллера с аннотацией
@RequestMethod("/server-error")
- создать метод контроллера с аннотацией
@ExceptionHandler
что будетreturn "forward:/server-error";