要點:
1.HttpSession:一個session的建立是從一個用戶向服務器發第一個請求開始,而以用戶顯式結束或session超時為結束,借助session能在一定時間內記錄用戶狀態。
2.ModelAndView:既可以設置URL地址,又可以渲染視圖。
3.HandlerInterceptor:攔截器接口,通過實現改接口的三個方法(preHandle、postHandle、afterCompletion)可以自定義一個攔截器。
實例:
實現登錄、購物車功能。
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>樂淘登錄</title> </head> <body> <form action="http://localhost:8888/login-commit" method="post"> <input type="submit" value="login"> </form> </body> </html>
mall.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>樂淘商場</title> </head> <body> <form action="http://localhost:8888/shopcar" method="POST"> <label>請選擇要購買的書籍:<br> <input type="checkbox" name="bookname" value="C Prime Plus">C Prime Plus<br> <input type="checkbox" name="bookname" value="C Prime Plus2">C Prime Plus2<br> <input type="checkbox" name="bookname" value="C Prime Plus3">C Prime Plus3<br> <input type="checkbox" name="bookname" value="C Prime Plus4">C Prime Plus4<br> </label> <input type="submit" value="加入購物車"> </form> <form action="http://localhost:8888/quit" method="POST"> <input value="log out" type="submit"> </form> </body> </html>
myshoppingcar.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>樂淘購物車</title> </head> <body> <h2>我的購物車:</h2> <!--存在購買時顯示已購書籍--> <ul th:if="${books.size()} != 0"> <li th:each="bookcount:${books}" th:text="${bookcount}"></li> </ul> <!--無購買--> <div th:if="${books.size()} == 0"> 您未購買任何書籍! </div> <form action="http://localhost:8888/mall" method="GET"> <input type="submit" value="繼續購買"> </form> </body> </html>
Books.java
package com.example.demo.controller.login; import java.util.HashMap; import java.util.Map.Entry; import java.util.Set; public class Books { private HashMap<String,Integer> books = new HashMap<String,Integer>(); //根據請求URL中獲得的表單數組,更新已有書本 public void refreshBooks(String[] newbooks) { for (String book:newbooks) { if (books.containsKey(book)) { books.put(book, books.get(book)+1); }else { books.put(book, 1); } } } //獲取books集合,送往頁面 public Set<Entry<String, Integer>> getbooks(){ return books.entrySet(); } }
LoginController.java
package com.example.demo.controller.login; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @Controller public class LoginController { //登錄界面 @GetMapping("login") public String getLogin(HttpServletRequest req) { HttpSession session = req.getSession(); //已登錄直接進入到商場 if (session.getAttribute("login")!=null) { return "redirect:mall"; } return "login"; } //登錄請求處理 @PostMapping("login-commit") public String postLogin(HttpServletRequest req) { HttpSession session = req.getSession(); //session標記登錄狀態 session.setAttribute("login",true); return "redirect:mall"; } //退出登錄,保留購物記錄 @PostMapping("quit") public String quit(HttpServletRequest req) { HttpSession session = req.getSession(); session.removeAttribute("login"); return "redirect:login"; } }
ShoppingController.java
package com.example.demo.controller.login; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.servlet.ModelAndView; @Controller public class ShoppingController { //商場 @GetMapping("mall") public String getMall() { return "mall"; } //我的購物車 @PostMapping("shopcar") public ModelAndView getShopCar(ModelAndView view,HttpServletRequest req) { HttpSession session = req.getSession(); Books books = (Books) session.getAttribute("shopcar");//session會話獲取已購書籍 String[] newbooks = req.getParameterValues("bookname");//新的購物請求 //從未購買 if (books==null){ books = new Books(); } //刷新session會話 if (newbooks!=null) { books.refreshBooks(newbooks); session.setAttribute("shopcar", books); } //刷新model,渲染視圖 view.addObject("books",books.getbooks()); view.setViewName("myshoppingcar"); return view; } }
LoginInterceptor.java
package com.example.demo.controller.login; import java.io.IOException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; //登錄攔截器 public class LoginInterceptor implements HandlerInterceptor { @Override //在Controller方法之前調用 public boolean preHandle(HttpServletRequest req,HttpServletResponse res,Object handler) throws IOException { HttpSession session = req.getSession(); if (session.getAttribute("login") != null) { System.out.println("login!"); return true; } res.sendRedirect("login"); return false; } @Override public void postHandle(HttpServletRequest req,HttpServletResponse res,Object handler,ModelAndView modelandview) throws Exception { //Controller方法處理完,但html頁面並未送出顯示時調用 } @Override public void afterCompletion(HttpServletRequest req,HttpServletResponse res,Object handler,Exception ex) { //頁面渲染完畢后調用,通常用來回收資源,類似於finally } }
SpringWebConfig.java
package com.example.demo.controller.login; import org.springframework.boot.SpringBootConfiguration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @SpringBootConfiguration public class SpringWebConfig implements WebMvcConfigurer{ //增加攔截器,可以對特定URL設定攔截以檢查是否登錄 public void addInterceptors(InterceptorRegistry registry) { //裝載一個攔截器,可以使用通配符,或字符串數組 registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/mall","/quit"); } }