SpringMVC 转发重定向和拦截器

本文介绍了SpringMVC中的转发和重定向,详细讲解了它们的使用方法,包括如何通过return 'redirect:路径'实现重定向,以及不加额外字段时的默认转发行为。此外,还探讨了拦截器的定义和配置,包括实现HandlerInterceptor接口,配置全局和特定路径的拦截器,以及登录检查和拦截器执行顺序。最后,对比了拦截器与过滤器的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转发和重定向
在控制器内部处理请求的方法中,默认返回字符串时的处理方式是转发,转发的值是view组件的名称,比如return "login",实质上会根据视图解析器(ViewResolver)得到最终负责显示的页面,而通过return redirect:路径这样的语法表示重定向,在redirect:右侧的内容是路径,这个路径通常使用相对的路径,是以当前客户端的地址栏中的路径为标准进行参考,
例如当前的地址为:http://localhost:8080/Project/user/reg,然后return "redirect:login",则会重定向到http://localhost:8080/Project/user/login,
如果return "redirect:/main/index"或者return "redirect:../main/index",则会重定向到http://localhost:8080/Project/main/index
forward:
不添加任何字段,那么spring中默认的是转发,比如return login,那么这个会经过视图解析器进行解析,跳转到指定的视图。但是如果添加了forward,那么就不经过视图解析器,而是直接进行跳转,我们一般都是转发到controller中的方法,比如return forward:../user/showLogin.do
redirect:
重定向 : return "redirect:login.do"
返回的是一个Controller方法的路径,而不是一个view,这个不会经过视图解析器,而是直接跳转
实例:

@RequestMapping(value = "login")
    public String login(String name,String pwd,Model model,HttpSession session) {
        
        if (name.equals("srd")&&pwd.equals("123")) {
            session.setAttribute("name", name);
            return "redirect:/main"; //重定向到main这个控制方法,main对应的就是转发到main.jsp
        }else {
            model.addAttribute("mes", "账号密码错误");
            return "login";
        }
    }
@RequestMapping(value = "main")
    public String toMain() {
        return "main";
    }
@RequestMapping(value = "loginOut")
              public String loginOut(HttpSession session) {
        session.invalidate();//session失效
        return "login";
    }

拦截器的定义
在 Spring MVC 框架中定义一个拦截器需要对拦截器进行定义和配置,定义一个拦截器可以通过两种方式:
一种是通过实现 HandlerInterceptor 接口或继承 HandlerInterceptor 接口的实现类来定义;
另一种是通过实现 WebRequestInterceptor 接口或继承 WebRequestInterceptor 接口的实现类来定义。实现 HandlerInterceptor 接口的定义方式自定义拦截器()的使用方法。示例代码如下:

public class TestInterceptor1 implements HandlerInterceptor {

    @Override
    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception {
        // TODO Auto-generated method stub
        System.out.println("拦截器1,视图渲染之后执行>>>>");
    }

    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
            throws Exception {
        // TODO Auto-generated method stub
        System.out.println("拦截器1,业务逻辑执行之后,视图渲染之前执行>>>>");
    }

    @Override
    public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
        // TODO Auto-generated method stub
        
        System.out.println("拦截器1,拦截请求之后,业务逻辑执行之前执行此方法>>>>>");
        
        return true;
    }

}

在上述拦截器的定义中实现了 HandlerInterceptor 接口,并实现了接口中的 3 个方法。
  preHandle 方法:该方法在控制器的处理请求方法前执行,其返回值表示是否中断后续操作,返回 true 表示继续向下执行,返回 false 表示中断后续操作。
  postHandle 方法:该方法在控制器的处理请求方法调用之后、解析视图之前执行,可以通过此方法对请求域中的模型和视图做进一步的修改。
  afterCompletion 方法:该方法在控制器的处理请求方法执行完成后执行,即视图渲染结束后执行,可以通过此方法实现一些资源清理、记录日志信息等工作。

拦截器的配置
  让自定义的拦截器生效需要在 Spring MVC 的配置文件中进行配置,配置示例代码如下:

<!-- 配置拦截器 -->
<mvc:interceptors>
    <!-- 配置一个全局拦截器,拦截所有请求 -->
    <bean class="interceptor.TestInterceptor" /> 
    <mvc:interceptor>
        <!-- 配置拦截器作用的路径 -->
        <mvc:mapping path="/**" />
        <!-- 配置不需要拦截作用的路径 -->
        <mvc:exclude-mapping path="##" />
        <!-- 定义<mvc:interceptor>元素中,表示匹配指定路径的请求才进行拦截 -->
        <bean id="testInterceptor1" class="com.srd.interceptor.TestInterceptor1"></bean>
    </mvc:interceptor>
    <mvc:interceptor>
        <!-- 配置拦截器作用的路径 -->
        <mvc:mapping path="/Test2" />
        <!-- 定义在<mvc: interceptor>元素中,表示匹配指定路径的请求才进行拦截 -->
     <bean id="testInterceptor2" class="com.srd.interceptor.TestInterceptor2"></bean>
    </mvc:interceptor>
</mvc:interceptors>


在上述示例代码中,<mvc:interceptors> 元素用于配置一组拦截器,其子元素 <bean> 定义的是全局拦截器,即拦截所有的请求。

<mvc:interceptor> 元素中定义的是指定路径的拦截器,其子元素 <mvc:mapping> 用于配置拦截器作用的路径,该路径在其属性 path 中定义。

如上述示例代码中,path 的属性值“/**”表示拦截所有路径,“/gotoTest”表示拦截所有以“/gotoTest”结尾的路径。如果在请求路径中包含不需要拦截的内容,可以通过 <mvc:exclude-mapping> 子元素进行配置。

需要注意的是,<mvc:interceptor> 元素的子元素必须按照 <mvc:mapping.../>、<mvc:exclude-mapping.../>、<bean.../> 的顺序配置。

演示登录检查
登录检查: 当涉及到用户信息的修改,查看什么的,必须要验证是否登录,因此需要设计拦截器验证登录
先设定登录数据,即: 在login.jsp中添加登录按钮,登录完成之后,需要自己定义一个标记存储在session中,比如用户的id或者用户的对象
我们使用用户的id作为标记验证是否已经的登录,如果用户登录成功,会在session中添加一个uid的属性
用户退出登录使用session.invalidate();清除session,并且重定向到登录界面
自定义拦截器(LoginInterceptor)

public class LoginInterceptor implements HandlerInterceptor{

    @Override
    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
            throws Exception {
        // TODO Auto-generated method stub
        
    }

    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object obj) throws Exception {
        // TODO Auto-generated method stub
        String news=req.getRequestURI();
                                //如果存在,那么即可登录完成
        if (news.indexOf("toLogin")>=0||news.indexOf("login")>=0) {
            return true;//返回true,登录成功就需要执行后续的流程
        }
        Object object= req.getSession().getAttribute("name");
        if (object!=null) {
            return true;//返回true,登录成功就需要执行后续的流程
        }else {
            req.setAttribute("mes", "请先登录!!!");
            req.getRequestDispatcher("login.jsp").forward(req, res);
            return false;//返回false,后面的流程也不用执行了,直接中断
        }
        
    }

}


springmvc中配置拦截器
由于这里只是跳转到用户中心需要验证登录,那么只是匹配了login

<!-- 配置拦截器,拦截全部,放行登录login路径-->    
    <mvc:interceptors>
         <mvc:interceptor>
                <mvc:mapping path="/**" />
                <mvc:exclude-mapping path="/login"/>
                <bean id="LoginInterceptor" class="com.srd.interceptor.LoginInterceptor"></bean>
         </mvc:interceptor>
     </mvc:interceptors>


多个拦截器的执行顺序
根据在springmvc配置文件中配置的顺序执行,即是在<mvc:interceptors>下配置的拦截器的顺序,如果对同一个路径进行了拦截器,那么先配置的先拦截
拦截器和过滤器的区别(主要的区别)
拦截器是springmvc中,仅仅当使用springmvc才可以使用拦截器,过滤器是Java EE体系中的,无论使用哪种框架都可以使用过滤器
拦截器在DispatcherServlet之后,在处理器之前执行,过滤器在DispatcherServlet之前执行
过滤器会在所有的servlet之前执行(所有的请求都会执行),而拦截器会在springmvc中DispatcherServlet之后执行,所以过滤器在项目中可以过滤任何请求(只要是配置了对应的路径),而拦截器只会在DispatcherServlet处理的请求的基础之上进行拦截。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值