在任何HandlerMapping之前修改HttpServletRequest?

时间:2009-12-28 12:14:32

标签: java spring spring-mvc

我想解决的问题是我想检查所有传入的GET URL对数据库。如果数据库中存在url,则应将其传递给certein控制器。我正在使用Spring 3.0。

首先,我尝试制作interceptor并将其添加到DefaultAnnotationsHandlerMapping。结果我无法修改preHandle()中的url。计划是修改请求中的url,然后让带注释的控制器处理其余的。

接下来我尝试制作自定义HandleMapping。我扩展了AbstractUrlHandlerMapping并创建了我自己的getHandlerInternal(),它返回一个带有Controller名称的String,这是有效的。但我更喜欢一个解决方案,我可以修改请求中的url并让一个带注释的控制器处理它。

写这篇文章的时候我觉得可能servlet过滤器是最合适的解决方案。如果是这种情况,我可以让Spring将EntityManager注入过滤器吗?我可以扩展的任何Spring类使这更容易吗?

在第一段中解决问题的最恰当方法是什么?如果是servlet过滤器,请给我一些关于如何编写它的指示。

4 个答案:

答案 0 :(得分:0)

您可以使用普通javax.servlet.Filter并创建一个HttpServletRequest - Wrapper,为您执行网址处理。

答案 1 :(得分:0)

可能包装servlet请求并将其传递给过滤器链。

...
MyHttpServletRequestWrapper wreq = new MyHttpServletRequestWrapper(request);
doFilter(wreq, response, chain);
...

包装器在被询问时返回修改后的URL。

答案 2 :(得分:0)

正如其他人所指出的那样,标准的servlet过滤器可以完成这项工作,但它不是一个非常适合弹簧的解决方案 - 过滤器不是由Spring管理的,因此不能与Spring bean连接。过滤器需要以编程方式获取spring bean,这不太好。

修改现有请求的URL的麻烦在于它破坏了servlet API模型。 HttpServletRequest有多个与路径和URL相关的方法,它们提取原始URL的不同部分,您必须确保以某种方式修改了所有这些值。无论您使用过滤器还是拦截器,API都不是为此而设计的。

而不是试图破坏API,我的建议是你编写一个接受“旧”路径的Spring控制器,并根据注入的EntityManager将请求转发到“新”路径。转发可以通过让控制器处理程序方法返回带有“新”路径的InternalResourceView来实现。严格来说,这并不是你要转发的观点,但Spring不会知道它们的区别。或者,您可以使用request.getRequestDispatcher(newPath).forward(request, response)直接转发它。

答案 3 :(得分:0)

我意识到这是一个旧线程,但我建议您扩展org.springframework.web.servlet.DispatcherServlet 像这样的东西:

@Override
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    try {
        RequestImpl req = RequestImpl.wrapRequest(request, response);
        request = req;
        response = req.getResponse();
    } catch (Throwable t) {
        //swallow       }
    super.doDispatch(request, response);
}   

然后在web.xml中将此调度程序称为:

<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>blah.com.MyDispatcher</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

等。扩展Spring MVC的绝对核心类似乎很可怕,但是如果你已经足够老了,那么在注解黑暗的日子之前,当真正的成年人仍然致力于我们所爱的美丽的POJO框架时,这就是你的方式。我的意思是使用Spring。