zoukankan      html  css  js  c++  java
  • SpringMVC学习笔记二:重定向,拦截器,参数绑定

    Controller方法返回值

    返回ModelAndView

    controller方法中定义ModelAndView对象并返回,对象中可添加model数据、指定view。

    返回void

    在Controller方法形参上可以定义request和response,使用request或response指定响应结果:

    1、使用request转发页面,如下:

    request.getRequestDispatcher("页面路径").forward(request, response)
    request.getRequestDispatcher("/WEB-INF/jsp/success.jsp").forward(request, response);

    2、可以通过response页面重定向:

    response.sendRedirect("url")
    response.sendRedirect("/springmvc-web2/itemEdit.action");

    3、可以通过response指定响应结果,例如响应json数据如下:

    response.getWriter().print("{"abc":123}");
    复制代码
    /**
     * 返回void测试
     * 
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping("queryItem")
    public void queryItem(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 1 使用request进行转发
        // request.getRequestDispatcher("/WEB-INF/jsp/success.jsp").forward(request,
        // response);
    
        // 2 使用response进行重定向到编辑页面
        // response.sendRedirect("/springmvc-web2/itemEdit.action");
    
        // 3 使用response直接显示
        response.getWriter().print("{"abc":123}");
    }
    复制代码

    返回字符串

    controller方法返回字符串可以指定逻辑视图名,通过视图解析器解析为物理视图地址。

    //指定逻辑视图名,经过视图解析器解析为jsp物理路径:/WEB-INF/jsp/itemList.jsp
    return "itemList";

    Redirect重定向

    Contrller方法返回字符串可以重定向到一个url地址,如下商品修改提交后重定向到商品编辑页面。

    复制代码
    /**
     * 更新商品
     * 
     * @param item
     * @return
     */
    @RequestMapping("updateItem")
    public String updateItemById(Item item) {
        // 更新商品
        this.itemService.updateItemById(item);
    
        // 修改商品成功后,重定向到商品编辑页面
        // 重定向后浏览器地址栏变更为重定向的地址,
        // 重定向相当于执行了新的request和response,所以之前的请求参数都会丢失
        // 如果要指定请求参数,需要在重定向的url后面添加 ?itemId=1 这样的请求参数
        return "redirect:/itemEdit.action?itemId=" + item.getId();
    }
    复制代码

    forward转发

     Controller方法执行后继续执行另一个Controller方法。如下商品修改提交后转向到商品修改页面,修改商品的id参数可以带到商品修改方法中。

    复制代码
    /**
     * 更新商品
     * 
     * @param item
     * @return
     */
    @RequestMapping("updateItem")
    public String updateItemById(Item item) {
        // 更新商品
        this.itemService.updateItemById(item);
    
        // 修改商品成功后,重定向到商品编辑页面
        // 重定向后浏览器地址栏变更为重定向的地址,
        // 重定向相当于执行了新的request和response,所以之前的请求参数都会丢失
        // 如果要指定请求参数,需要在重定向的url后面添加 ?itemId=1 这样的请求参数
        // return "redirect:/itemEdit.action?itemId=" + item.getId();
    
        // 修改商品成功后,继续执行另一个方法
        // 使用转发的方式实现。转发后浏览器地址栏还是原来的请求地址,
        // 转发并没有执行新的request和response,所以之前的请求参数都存在
        return "forward:/itemEdit.action";
    
    }
    //结果转发到editItem.action,request可以带过去
    return "forward: /itemEdit.action";

    拦截器

    Spring Web MVC 的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理。

    拦截器定义

    实现HandlerInterceptor接口,如下:

    复制代码
    public class HandlerInterceptor1 implements HandlerInterceptor {
        // controller执行后且视图返回后调用此方法
        // 这里可得到执行controller时的异常信息
        // 这里可记录操作日志
        @Override
        public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
                throws Exception {
            System.out.println("HandlerInterceptor1....afterCompletion");
        }
    
        // controller执行后但未返回视图前调用此方法
        // 这里可在返回用户前对模型数据进行加工处理,比如这里加入公用信息以便页面显示
        @Override
        public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
                throws Exception {
            System.out.println("HandlerInterceptor1....postHandle");
        }
    
        // Controller执行前调用此方法
        // 返回true表示继续执行,返回false中止执行
        // 这里可以加入登录校验、权限拦截等
        @Override
        public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
            System.out.println("HandlerInterceptor1....preHandle");
            // 设置为true,测试使用
            return true;
        }
    }
    复制代码

    拦截器配置

    上面定义的拦截器再复制一份HandlerInterceptor2,注意新的拦截器修改代码:System.out.println("HandlerInterceptor2....preHandle");

    在springmvc.xml中配置拦截器

    复制代码
    <!-- 配置拦截器 -->
    <mvc:interceptors>
        <mvc:interceptor>
            <!-- 所有的请求都进入拦截器 -->
            <mvc:mapping path="/**" />
            <!-- 配置具体的拦截器 -->
            <bean class="cn.itcast.ssm.interceptor.HandlerInterceptor1" />
        </mvc:interceptor>
        <mvc:interceptor>
            <!-- 所有的请求都进入拦截器 -->
            <mvc:mapping path="/**" />
            <!-- 配置具体的拦截器 -->
            <bean class="cn.itcast.ssm.interceptor.HandlerInterceptor2" />
        </mvc:interceptor>
    </mvc:interceptors>
    复制代码

     正常流程测试

    浏览器访问地址:http://127.0.0.1:8080/springmvc-web2/itemList.action

    运行流程

    控制台打印:

    复制代码
    HandlerInterceptor1..preHandle..
    
    HandlerInterceptor2..preHandle..
    
    HandlerInterceptor2..postHandle..
    
    HandlerInterceptor1..postHandle..
    
    HandlerInterceptor2..afterCompletion..
    
    HandlerInterceptor1..afterCompletion..
    复制代码

    中断流程测试

    浏览器访问地址:http://127.0.0.1:8080/springmvc-web2/itemList.action

    运行流程:HandlerInterceptor1的preHandler方法返回false,HandlerInterceptor2返回true,运行流程如下:

    HandlerInterceptor1..preHandle..

    从日志看出第一个拦截器的preHandler方法返回false后第一个拦截器只执行了preHandler方法,其它两个方法没有执行,第二个拦截器的所有方法不执行,且Controller也不执行了。

    HandlerInterceptor1的preHandler方法返回true,HandlerInterceptor2返回false,运行流程如下:

    HandlerInterceptor1..preHandle..
    
    HandlerInterceptor2..preHandle..
    
    HandlerInterceptor1..afterCompletion..

    从日志看出第二个拦截器的preHandler方法返回false后第一个拦截器的postHandler没有执行,第二个拦截器的postHandler和afterCompletion没有执行,且controller也不执行了。

    总结

    1. preHandle按拦截器定义顺序调用
    2. postHandler按拦截器定义逆序调用
    3. afterCompletion按拦截器定义逆序调用
    4. postHandler在拦截器链内所有拦截器返成功调用
    5. afterCompletion只有preHandle返回true才调用

    拦截器应用

     处理流程

    1. 有一个登录页面,需要写一个Controller访问登录页面
    2. 登录页面有一提交表单的动作。需要在Controller中处理。

    a) 判断用户名密码是否正确(在控制台打印)

    b) 如果正确,向session中写入用户信息(写入用户名username)

    c) 跳转到商品列表

    拦截器

    a) 拦截用户请求,判断用户是否登录(登录请求不能拦截)

    b) 如果用户已经登录。放行

    c) 如果用户未登录,跳转到登录页面。

    1、编写登录jsp

    复制代码
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    
    <form action="${pageContext.request.contextPath }/user/login.action">
    <label>用户名:</label>
    <br>
    <input type="text" name="username">
    <br>
    <label>密码:</label>
    <br>
    <input type="password" name="password">
    <br>
    <input type="submit">
    
    </form>
    
    </body>
    </html>
    复制代码

    2、用户登陆Controller

    复制代码
    @Controller
    @RequestMapping("user")
    public class UserController {
    
        /**
         * 跳转到登录页面
         * 
         * @return
         */
        @RequestMapping("toLogin")
        public String toLogin() {
            return "login";
        }
    
        /**
         * 用户登录
         * 
         * @param username
         * @param password
         * @param session
         * @return
         */
        @RequestMapping("login")
        public String login(String username, String password, HttpSession session) {
            // 校验用户登录
            System.out.println(username);
            System.out.println(password);
    
            // 把用户名放到session中
            session.setAttribute("username", username);
    
            return "redirect:/item/itemList.action";
        }
    
    }
    复制代码

    3、编写拦截器

    复制代码
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
        // 从request中获取session
        HttpSession session = request.getSession();
        // 从session中获取username
        Object username = session.getAttribute("username");
        // 判断username是否为null
        if (username != null) {
            // 如果不为空则放行
            return true;
        } else {
            // 如果为空则跳转到登录页面
            response.sendRedirect(request.getContextPath() + "/user/toLogin.action");
        }
    
        return false;
    }
    复制代码

    4、 配置拦截器

    只能拦截商品的url,所以需要修改ItemController,让所有的请求都必须以item开头,如下图:

     

    在springmvc.xml配置拦截器

    复制代码
    <mvc:interceptor>
      <!-- 配置商品被拦截器拦截 -->
      <mvc:mapping path="/item/**" />
      <!-- 配置具体的拦截器 -->
      <bean class="cn.itcast.ssm.interceptor.LoginHandlerInterceptor" />
    </mvc:interceptor>

    转自:https://www.cnblogs.com/ginb/p/7350964.html
  • 相关阅读:
    HDU 5115 Dire Wolf (区间DP)
    HDU 4283 You Are the One(区间DP(最优出栈顺序))
    ZOJ 3469 Food Delivery(区间DP好题)
    LightOJ 1422 Halloween Costumes(区间DP)
    POJ 1651 Multiplication Puzzle(区间DP)
    NYOJ 石子合并(一)(区间DP)
    POJ 2955 Brackets(括号匹配一)
    POJ 1141 Brackets Sequence(括号匹配二)
    ZOJ 3537 Cake(凸包+区间DP)
    Graham求凸包模板
  • 原文地址:https://www.cnblogs.com/lgg20/p/11205205.html
Copyright © 2011-2022 走看看