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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM