如何从 Spring 中的 HandlerExceptionResolver 访问模型?

发布于 2024-11-02 04:51:44 字数 420 浏览 1 评论 0原文


我的项目中有一个 Spring AbstractHandlerExceptionResolver 的实现。该处理程序负责处理从控制器抛出的所有异常。在大多数情况下,这对于处理我们的特殊情况并将其转换为视图/HTTP 响应非常有效。

但是,我们要求在每种情况下(甚至错误)都必须向响应标头写入某些内容。该数据必须在控制器操作本身中配置/设置(因为它与控制器正在执行的任何操作相关)。因此,我试图将这些数据传递到我的视图中,以便可以使用它。

从逻辑上讲,将这些数据放入模型中是有意义的...但是,看起来 HandlerExceptionResolver 接口不会保留控制器在模型中设置的任何内容(其中将包含控制器必须的数据)放)。

有没有办法在 HandlerExceptionResolver 实现中访问控制器的模型值?

谢谢!

I have an implementation of a 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 (which would contain the data the controller must set).

Is there a way to access the Controller's model values in a HandlerExceptionResolver implementation?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不醒的梦 2024-11-09 04:51:44

我先总结一下:
* 你有一个 MVC 控制器方法
* 如果这个控制器方法中有异常,那么你想要采用模型并做一些不同的事情(然后当没有异常时)

对我来说,它看起来像正常的异常处理:

public ModelAndView myController() {
    Model model = new Model();
    model.put(...); 
    try {
       ...
       return new ModelAndView("success", model);
    } catch (SomethingWrongException e) {
       return new ModelAndView("failure", model);   
    }        
}

也许你已经注意到 try 块不包括模型人口。 - 因为如果它位于 try 块中,则不应在 catch 子句中使用它,因为它可能未填充。

但这就是你尝试的。
您尝试的内容有点像这样(从概念角度的角度来看):

try {
   ModelAndView modelAndView = invoke.myController()
} catch (Exception e) {
   doSomethingWith(modelAndView);
}

所以总的来说,我相信您尝试的东西至少不是那么可取。
(如果这是一个横切问题,那么它不应该依赖于模型)


无论如何:让我们找到一种方法让它工作。因为方法如果抛出异常就无法返回任何内容,所以我假设您的控制器方法如下所示;

public String myControllerMethod(ModelMap myModel) {
   myModel.put(...);
   if (Math.random()<0.5) {
     throws new RuntimeException("only a example");
   }
}

因为你要使用 HandlerExceptionResolver 而不是 concreate try/catch 我猜你有一个使用模型的奇怪的横切问题。为了实现它,我将使用 AOP。我会为控制器方法添加一个切入点和一个环绕建议,如果抛出异常,它们会返回另一个视图名称。

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";
    }
}   
}

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";
    }
}   
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文