How to access the model from a HandlerExceptionResolver in Spring?
AbstractHandlerExceptionResolver
in my project. This handler takes care of all exceptions thrown from controllers. For the most part, this works very well in handling our exceptional cases and translating them into Views/HTTP responses.
However, we have a requirement that something must be written to the response headers in every situation (even errors). This data must be configured/set in the controller actions themselves (as it is tied to whatever the controllers are doing). So, I'm trying to get this data through to my views so that it can be used.
Logically, it makes sense to put this data in the Model... However, it looks like the HandlerExceptionResolver
interface does not persist anything the Controller has set in the Model (whic开发者_如何学运维h would contain the data the controller must set).
Is there a way to access the Controller's model values in a HandlerExceptionResolver
implementation?
Thanks!
Let me first summarize: * you have an MVC controller method * if there is an exception in this controller method, then you want to take the model and do something different (then when there is no exception)
For me it looks like normal exception handling:
public ModelAndView myController() {
Model model = new Model();
model.put(...);
try {
...
return new ModelAndView("success", model);
} catch (SomethingWrongException e) {
return new ModelAndView("failure", model);
}
}
May you have noticed that the try block does not include the model population. - Because if it would be in the try block you should not use it in the catch clause, because may it is not populated.
But this is what you try. What you try is a bit like this (from a conceptual point of view):
try {
ModelAndView modelAndView = invoke.myController()
} catch (Exception e) {
doSomethingWith(modelAndView);
}
So in general I belive you try some thing that is at lest not so advisable. (If it is a cross cutting concern, than it should not depend on the model)
Anyway: lets find a way to get it working. Because a method can not return anything if it throws an exception, I assume that your controller method looks like this;
public String myControllerMethod(ModelMap myModel) {
myModel.put(...);
if (Math.random()<0.5) {
throws new RuntimeException("only a example");
}
}
Because you what to use a HandlerExceptionResolver and not a concreate try/catch I guess you have a strange crosscuting concern that uses the Model. To implement it, I would use AOP. I would add an point cut and a arround advice for the controller methods, that return an other view name if an exception is thrown.
public aspect ServletExceptionReporterAspect {
pointcut stringRequestHandler() :
execution (@RequestMapping String com.demo..*(ModelMap));
String around(ModelMap model): stringRequestHandler(){
try {
return proceed(model);
} catch (Exception ex){
System.out.println(model);
return "myErrorView";
}
}
}
精彩评论