【问题标题】:Intercepting requests before they go to the controller in an annotation-based Spring web-app在基于注释的 Spring Web 应用程序中拦截请求,然后再到达控制器
【发布时间】:2010-11-19 02:05:30
【问题描述】:

我正在开发一个网络应用程序并且我正在使用 Spring 框架。问题是,我从来没有正确地学会使用 Spring,我有点迷失在这一切中。

但是,使用基于注释的控制器,我能够创建我的大部分应用程序!

现在,问题是我需要能够在请求发送到控制器之前拦截请求(我需要它,以便我可以验证用户是否可以访问他请求的页面)。我只花了大约 5 个小时搜索这方面的信息,实际上我发现了很多,它们都没有按预期工作,我无法让我的拦截器显示一个简单的“Hello World”。

这是我的 *-servlet.xml 中的内容(当然,我还有其他 bean 定义):

<!-- this should be the class that contains the "hello world" -->
<bean id="myInterceptor" class="com.ibm.brmt.srb.admin.web.controller.TimeBasedAccessInterceptor"/>

<!-- this should "map" my interceptor no? -->
<bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    <property name="interceptors">
        <list>
            <ref bean="myInterceptor"/>
        </list>
    </property>
</bean> 

这是我的 TimeBasedAccessInterceptor 类(名称不相关,可能会更改)

package web.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;



public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter{

    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception {
        System.out.println("-------------------------------------------------------------------------------------------");      
        }

    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception {
        System.out.println("-------------------------------------------------------------------------------------------");      
        }

    public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
        System.out.println("-------------------------------------------------------------------------------------------");      
        return false;
    }
}

代码编译并运行,但 TimeBasedAccessInterceptor 类中的内容从未被调用(我什至使用了断点)。有人可以帮我吗?

根据要求,这是我在 *-servlet.xml 中实现控制器方式的“预览”

<bean id="controllerName" class="web.controller.controllerNameController">  
    <property name="property1" ref="beanRef" />
    <property name="property1" ref="beanRef2"/>
</bean>

在controllerNameController.java中:

  package web.controller;

    @Controller
    public class controllerNameController{

        @RequestMapping
        public void find(String[] enabledLvlCodes, String reset, String readRuleId, Filter filter, Errors errors,
                Model model, HttpSession session) {

       //Code goes here
       }
}

【问题讨论】:

  • 应该可以。您能否更新您的答案以显示您的控制器类,以及您在春季如何声明它?
  • 您的 @RequestMapping 未指定 URI 路径。您确定请求正在到达您的控制器吗?
  • 是的,我敢肯定。 Spring 能够根据方法的名称自动“创建”uri。如果请求没有到达控制器,我就看不到我看到的返回页面!
  • 好奇者和好奇者。我建议使用远程调试器查看 AbstractHandlerMapping.getHandlerExecutionChain 中发生了什么,这是处理程序与“adaptedInterceptors”结合的地方。

标签: java spring spring-mvc


【解决方案1】:

您的映射看起来正确。

也许除了 DefaultAnnotationHandlerMapping 之外,您还定义了其他处理程序映射(这将为您的控制器提供一种通过不同路径调用的方式)?

或者您的上下文文件可能没有正确部署(是的,这是一个愚蠢的建议,但您会惊讶于这种情况发生的频率:-))

如果两者的答案都是“否”,我建议你在AbstractHandlerMapping.getHandler() 中设置一个断点,然后单步执行HandlerExecutionChain 的获取点,检查它是否包含你的拦截器。

【讨论】:

  • 会: 会导致问题吗?
  • 绝对。正如 skaffman 在他的评论中提到的,没有在 @RequestMapping 中指定 URI 会有效地使您的注释映射无用,从而导致回退到 ControllerClassNameHandlerMapping
  • 你是对的,在控制器中删除 ControllerClassNameHandlerMapping 并指定 URI 后,它确实进入了拦截器,谢谢你们真是太棒了
  • 事实上,如果我只是将“interceptor”属性添加到 ControllerClassNameHandlerMapping,我可以保持我之前使用的自动映射到方法名称
  • 当然可以,但是您应该删除DefaultAnnotationHandlerMapping@RequestMapping 注释。有两个相互冲突的映射方案并不理想。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-15
  • 2020-08-09
  • 1970-01-01
相关资源
最近更新 更多