第一章 初識SpringMVC
1.1 SpringMVC概述
-
SpringMVC是Spring子框架
-
SpringMVC是Spring 為【展現層|表示層|表述層|控制層】提供的基于 MVC 設計理念的優秀的 Web 框架,是目前最主流的MVC 框架,
-
SpringMVC是非侵入式:可以使用注解讓普通java物件,作為請求處理器【Controller】,
-
SpringMVC是用來代替Servlet
Servlet作用
1. 處理請求 - 將資料共享到域中 2. 做出回應 - 跳轉頁面【視圖】
1.2 SpringMVC處理請求原理簡圖
- 請求
- DispatcherServlet【前端控制器】
- 將請求交給Controller|Handler
- Controller|Handler【請求處理器】
- 處理請求
- 回傳資料模型
- ModelAndView
- Model:資料模型
- View:視圖物件或視圖名
- DispatcherServlet渲染視圖
- 將資料共享到域中
- 跳轉頁面【視圖】
- 回應

第二章 SpringMVC搭建框架
2.1 搭建SpringMVC框架
-
創建工程【web工程】
-
匯入jar包
<!--spring-webmvc--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.1</version> </dependency> <!-- 匯入thymeleaf與spring5的整合包 --> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring5</artifactId> <version>3.0.12.RELEASE</version> </dependency> <!--servlet-api--> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> -
撰寫組態檔
- web.xml注冊DispatcherServlet
- url配置:/
- init-param:contextConfigLocation,設定springmvc.xml組態檔路徑【管理容器物件】
- <load-on-startup>:設定DispatcherServlet優先級【啟動服務器時,創建當前Servlet物件】
- springmvc.xml
- 開啟組件掃描
- 配置視圖決議器【決議視圖(設定視圖前綴&后綴)】
- web.xml注冊DispatcherServlet
-
撰寫請求處理器【Controller|Handler】
- 使用@Controller注解標識請求處理器
- 使用@RequestMapping注解標識處理方法【URL】
-
準備頁面進行,測驗
第三章 @RequestMapping詳解
@RequestMapping注解作用:為指定的類或方法設定相應URL
3.1 @RequestMapping注解位置
- 書寫在類上面
- 作用:為當前類設定映射URL
- 注意:不能單獨使用,需要與方法上的@RequestMapping配合使用
- 書寫在方法上面
- 作用:為當前方法設定映射URL
- 注意:可以單獨使用
3.2 @RequestMapping注解屬性
-
value屬性
- 型別:String[]
- 作用:設定URL資訊
-
path屬性
- 型別:String[]
- 作用:與value屬性作用一致
-
method屬性
-
型別:RequestMethod[]
public enum RequestMethod { GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE } -
作用:為當前URL【類或方法】設定請求方式【POST、DELETE、PUT、GET】
-
注意:
- 默認情況:所有請求方式均支持
- 如請求方式不支持,會報如下錯誤
- 405【Request method 'GET' not supported】
-
-
params
- 型別:String[]
- 作用:為當前URL設定請求引數
- 注意:如設定指定請求引數,但URL中未攜帶指定引數,會報如下錯誤
- 400【Parameter conditions "lastName" not met for actual request parameters:】
-
headers
- 型別:String[]
- 作用:為當前URL設定請求頭資訊
- 注意:如設定指定請求頭,但URL中未攜帶請求頭,會報如下錯誤
- 404:請求資源未找到
-
示例代碼
@RequestMapping(value = https://www.cnblogs.com/ygstudy/p/{"/saveEmp","/insertEmp"}, method = RequestMethod.GET, params = "lastName=lisi", headers = "User-Agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.84 Safari/537.36") public String saveEmp(){ System.out.println("添加員工資訊!!!!"); return SUCCESS; }
@RequestMapping(method = RequestMethod.POST) public @interface PostMapping {} @RequestMapping(method = RequestMethod.GET) public @interface GetMapping {} @RequestMapping(method = RequestMethod.PUT) public @interface PutMapping {} @RequestMapping(method = RequestMethod.DELETE) public @interface DeleteMapping {}
3.3 @RequestMapping支持Ant 風格的路徑(了解)
-
常用通配符
a) ?:匹配一個字符
b) *:匹配任意字符
c) **:匹配多層路徑
-
示例代碼
@RequestMapping("/testAnt/**") public String testAnt(){ System.out.println("==>testAnt!!!"); return SUCCESS; }
第四章 @PathVariable 注解
4.1 @PathVariable注解位置
@Target(ElementType.PARAMETER)
- 書寫在引數前面
4.2 @PathVariable注解作用
-
獲取URL中占位符引數
-
占位符語法:{}
-
示例代碼
<a th:href="https://www.cnblogs.com/ygstudy/p/@{/EmpController/testPathVariable/1001}">測驗PathVariable注解</a><br>/** * testPathVariable * @return */ @RequestMapping("/testPathVariable/{empId}") public String testPathVariable(@PathVariable("empId") Integer empId){ System.out.println("empId = " + empId); return SUCCESS; }
4.3 @PathVariable注解屬性
- value屬性
- 型別:String
- 作用:設定占位符中的引數名
- name屬性
- 型別:String
- 作用:與name屬性的作用一致
- required屬性
- 型別:boolean
- 作用:設定當前引數是否必須入參【默認值:true】
- true:表示當前引數必須入參,如未入參會報如下錯誤
- Missing URI template variable 'empId' for method parameter of type Integer
- false:表示當前引數不必須入參,如未入參,會裝配null值
- true:表示當前引數必須入參,如未入參會報如下錯誤
第五章 REST【RESTful】風格CRUD
5.1 REST的CRUD與傳統風格CRUD對比
-
傳統風格CRUD
- 功能 URL 請求方式
- 增 /insertEmp POST
- 刪 /deleteEmp?empId=1001 GET
- 改 /updateEmp POST
- 查 /selectEmp?empId=1001 GET
-
REST風格CRUD
- 功能 URL 請求方式
- 增 /emp POST
- 刪 /emp/1001 DELETE
- 改 /emp PUT
- 查 /emp/1001 GET
5.2 REST風格CRUD優勢
- 提高網站排名
- 排名方式
- 競價排名
- 技術排名
- 排名方式
- 便于第三方平臺對接
5.3 實作PUT&DELETE提交方式步驟
- 注冊過濾器HiddenHttpMethodFilter
- 設定表單的提交方式為POST
- 設定引數:_method=PUT或_method=DELETE
5.4 原始碼決議HiddenHttpMethodFilter
public static final String DEFAULT_METHOD_PARAM = "_method";
private String methodParam = DEFAULT_METHOD_PARAM;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
HttpServletRequest requestToUse = request;
if ("POST".equals(request.getMethod()) && request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) {
String paramValue = https://www.cnblogs.com/ygstudy/p/request.getParameter(this.methodParam);
if (StringUtils.hasLength(paramValue)) {
String method = paramValue.toUpperCase(Locale.ENGLISH);
if (ALLOWED_METHODS.contains(method)) {
requestToUse = new HttpMethodRequestWrapper(request, method);
}
}
}
filterChain.doFilter(requestToUse, response);
}
/**
* Simple {@link HttpServletRequest} wrapper that returns the supplied method for
* {@link HttpServletRequest#getMethod()}.
*/
private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {
private final String method;
public HttpMethodRequestWrapper(HttpServletRequest request, String method) {
super(request);
this.method = method;
}
@Override
public String getMethod() {
return this.method;
}
}
第六章 SpringMVC處理請求資料
使用Servlet處理請求資料
- 請求引數
- String param = request.getParameter();
- 請求頭
- request.getHeader();
- Cookie
- request.getCookies();
6.1 處理請求引數
-
默認情況:可以將請求引數名,與入參引數名一致的引數,自動入參【自動型別轉換】
-
SpringMVC支持POJO入參
-
要求:請求引數名與POJO的屬性名保持一致
-
示例代碼
<form th:action="@{/saveEmp}" method="POST"> id:<input type="text" name="id"><br> LastName:<input type="text" name="lastName"><br> Email:<input type="text" name="email"><br> Salary:<input type="text" name="salary"><br> <input type="submit" value="https://www.cnblogs.com/ygstudy/p/添加員工資訊"> </form>/** * 獲取請求引數POJO * @return */ @RequestMapping(value = "https://www.cnblogs.com/saveEmp",method = RequestMethod.POST) public String saveEmp(Employee employee){ System.out.println("employee = " + employee); return SUCCESS; }
-
-
@RequestParam注解
-
作用:如請求引數與入參引數名不一致時,可以使用@RequestParam注解設定入參引數名
-
屬性
- value
- 型別:String
- 作用:設定需要入參的引數名
- name
- 型別:String
- 作用:與value屬性作用一致
- required
- 型別:Boolean
- 作用:設定當前引數,是否必須入參
- true【默認值】:表示當前引數必須入參,如未入參會報如下錯誤
- 400【Required String parameter 'sName' is not present】
- false:表示當前引數不必須入參,如未入參,裝配null值
- true【默認值】:表示當前引數必須入參,如未入參會報如下錯誤
- defaultValue
- 型別:String
- 作用:當裝配數值為null時,指定當前defaultValue默認值
- value
-
示例代碼
/** * 獲取請求引數 * @return */ @RequestMapping("/requestParam1") public String requestParam1(@RequestParam(value = "https://www.cnblogs.com/ygstudy/p/sName",required = false, defaultValue = "https://www.cnblogs.com/ygstudy/p/zhangsan") String stuName, Integer stuAge){ System.out.println("stuName = " + stuName); System.out.println("stuAge = " + stuAge); return SUCCESS; }
-
6.2 處理請頭
-
語法:@RequestHeader注解
-
屬性
- value
- 型別:String
- 作用:設定需要獲取請求頭名稱
- name
- 型別:String
- 作用:與value屬性作用一致
- required
- 型別:boolean
- 作用:【默認值true】
- true:設定當前請求頭是否為必須入參,如未入參會報如下錯誤
- 400【Required String parameter 'sName' is not present】
- false:表示當前引數不必須入參,如未入參,裝配null值
- true:設定當前請求頭是否為必須入參,如未入參會報如下錯誤
- defaultValue
- 型別:String
- 作用:當裝配數值為null時,指定當前defaultValue默認值
- value
-
示例代碼
<a th:href="https://www.cnblogs.com/ygstudy/p/@{/testGetHeader}">測驗獲取請求頭</a>/** * 獲取請求頭 * @return */ @RequestMapping(value = "https://www.cnblogs.com/testGetHeader") public String testGetHeader(@RequestHeader("Accept-Language")String al, @RequestHeader("Referer") String ref){ System.out.println("al = " + al); System.out.println("ref = " + ref); return SUCCESS; }
6.3 處理Cookie資訊
-
語法:@CookieValue獲取Cookie數值
-
屬性
- value
- 型別:String
- 作用:設定需要獲取Cookie名稱
- name
- 型別:String
- 作用:與value屬性作用一致
- required
- 型別:boolean
- 作用:【默認值true】
- true:設定當前Cookie是否為必須入參,如未入參會報如下錯誤
- 400【Required String parameter 'sName' is not present】
- false:表示當前Cookie不必須入參,如未入參,裝配null值
- true:設定當前Cookie是否為必須入參,如未入參會報如下錯誤
- defaultValue
- 型別:String
- 作用:當裝配數值為null時,指定當前defaultValue默認值
- value
-
示例代碼
<a th:href="https://www.cnblogs.com/ygstudy/p/@{/setCookie}">設定Cookie資訊</a><br> <a th:href="https://www.cnblogs.com/ygstudy/p/@{/getCookie}">獲取Cookie資訊</a><br>/** * 設定Cookie * @return */ @RequestMapping("/setCookie") public String setCookie(HttpSession session){ // Cookie cookie = new Cookie(); System.out.println("session.getId() = " + session.getId()); return SUCCESS; } /** * 獲取Cookie * @return */ @RequestMapping("/getCookie") public String getCookie(@CookieValue("JSESSIONID")String cookieValue){ System.out.println("cookieValue = "https://www.cnblogs.com/ygstudy/p/+ cookieValue); return SUCCESS; }
6.4 使用原生Servlet-API
- 將原生Servlet相關物件,入參即可
@RequestMapping("/useRequestObject")
public String useRequestObject(HttpServletRequest request){}
第七章 SpringMVC處理回應資料
7.1 使用ModelAndView
-
使用ModelAndView物件作為方法回傳值型別,處理回應資料
-
ModelAndView是模型資料與視圖物件的集成物件,原始碼如下
public class ModelAndView { /** View instance or view name String. */ //view代表view物件或viewName【建議使用viewName】 @Nullable private Object view; /** Model Map. */ //ModelMap集成LinkedHashMap,存盤資料 @Nullable private ModelMap model; /** 設定視圖名稱 */ public void setViewName(@Nullable String viewName) { this.view = viewName; } /** * 獲取視圖名稱 */ @Nullable public String getViewName() { return (this.view instanceof String ? (String) this.view : null); } /** 獲取資料,回傳Map【無序,model可以為null】 */ @Nullable protected Map<String, Object> getModelInternal() { return this.model; } /** * 獲取資料,回傳 ModelMap【有序】 */ public ModelMap getModelMap() { if (this.model == null) { this.model = new ModelMap(); } return this.model; } /** * 獲取資料,回傳Map【無序】 */ public Map<String, Object> getModel() { return getModelMap(); } /** 設定資料 */ public ModelAndView addObject(String attributeName, @Nullable Object attributeValue) { getModelMap().addAttribute(attributeName, attributeValue); return this; } } -
示例代碼
@GetMapping("/testMvResponsedata") public ModelAndView testMvResponsedata(){ ModelAndView mv = new ModelAndView(); //設定邏輯視圖名 mv.setViewName("response_success"); //設定資料【將資料共享到域中(request\session\servletContext)】 mv.addObject("stuName","zhouxu"); return mv; }
7.2 使用Model、ModelMap、Map
-
使用Model、ModelMap、Map作為方法入參,處理回應資料
-
示例代碼
/** * 使用Map、Model、ModelMap處理回應資料 * @return */ @GetMapping("/testMapResponsedata") public String testMapResponsedata(Map<String,Object> map /* Model model ModelMap modelMap*/){ map.put("stuName","zhangsan"); // model.addAttribute("stuName","lisi"); // modelMap.addAttribute("stuName","wangwu"); return "response_success"; }
7.3 SpringMVC中域物件
-
SpringMVC封裝資料,默認使用request域物件
-
session域的使用
-
方式一
/** * 測驗回應資料【其他域物件】 * @return */ @GetMapping("/testScopeResponsedata") public String testScopeResponsedata(HttpSession session){ session.setAttribute("stuName","xinlai"); return "response_success"; } -
方式二
@Controller @SessionAttributes(value = "https://www.cnblogs.com/ygstudy/p/stuName") //將request域中資料,同步到session域中 public class TestResponseData { /** * 使用ModelAndView處理回應資料 * @return */ @GetMapping("/testMvResponsedata") public ModelAndView testMvResponsedata(){ ModelAndView mv = new ModelAndView(); //設定邏輯視圖名 mv.setViewName("response_success"); //設定資料【將資料共享到域中(request\session\servletContext)】 mv.addObject("stuName","zhouxu"); return mv; } }
-
第八章 SpringMVC處理請求回應亂碼
8.1 原始碼決議CharacterEncodingFilter
public class CharacterEncodingFilter extends OncePerRequestFilter {
//需要設定字符集
@Nullable
private String encoding;
//true:處理請亂碼
private boolean forceRequestEncoding = false;
//true:處理回應亂碼
private boolean forceResponseEncoding = false;
public String getEncoding() {
return this.encoding;
}
public boolean isForceRequestEncoding() {
return this.forceRequestEncoding;
}
public void setForceResponseEncoding(boolean forceResponseEncoding) {
this.forceResponseEncoding = forceResponseEncoding;
}
public void setForceEncoding(boolean forceEncoding) {
this.forceRequestEncoding = forceEncoding;
this.forceResponseEncoding = forceEncoding;
}
@Override
protected void doFilterInternal(
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String encoding = getEncoding();
if (encoding != null) {
if (isForceRequestEncoding() || request.getCharacterEncoding() == null) {
request.setCharacterEncoding(encoding);
}
if (isForceResponseEncoding()) {
response.setCharacterEncoding(encoding);
}
}
filterChain.doFilter(request, response);
}
}
8.2 處理請求與回應亂碼
-
SpringMVC底層默認處理回應亂碼
-
SpringMVC處理請求亂碼步驟
- 注冊CharacterEncodingFilter
- 注冊CharacterEncodingFilter必須是第一Filter位置
- 為CharacterEncodingFilter中屬性encoding賦值
- 為CharacterEncodingFilter中屬性forceRequestEncoding賦值
- 注冊CharacterEncodingFilter
-
示例代碼
<!-- 必須是第一過濾器位置--> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceRequestEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
第九章 原始碼決議SpringMVC作業原理
9.1 Controller中方法的回傳值問題
-
無論方法回傳是ModelAndView還是String,最終SpringMVC底層,均會封裝為ModelAndView物件
//DispatcherServlet的1061行代碼 ModelAndView mv = null; mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); -
SpringMVC決議mv【ModelAndView】
//DispatcherServlet的1078行代碼 processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); -
ThymeleafView物件中344行代碼【SpringMVC底層處理回應亂碼】
//computedContentType="text/html;charset=UTF-8" response.setContentType(computedContentType); -
WebEngineContext物件中783行代碼【SpringMVC底層將資料默認共享到request域】
this.request.setAttribute(name, value);
9.2 視圖及視圖決議器原始碼
-
視圖決議器將View從ModelAndView中決議出來
-
ThymeleafViewResolver的837行代碼
//底層使用反射的方式,newInstance()創建視圖物件 final AbstractThymeleafView viewInstance = BeanUtils.instantiateClass(getViewClass());
-
第十章 SpringMVC視圖及視圖決議器
10.1 視圖決議器物件【ViewResolver】
-
概述:ViewResolver介面的實作類或子介面,稱之為視圖決議器
-
作用:將ModelAndView中的View物件決議出來

10.2 視圖物件【View】
- 概述:View介面的實作類或子介面,稱之為視圖物件
- 作用:視圖渲染
- 將資料共享域中
- 跳轉路徑【轉發或重定向】
第十一章 視圖控制器&重定向&加載靜態資源
11.1 視圖控制器
- 語法:view-controller
- 步驟
- 添加<mvc:view-controller>標簽:為指定URL映射html頁面
- 添加<mvc:annotation-driven>
- 有20+種功能
- 配置了<mvc:view-controller>標簽之后會導致其他請求路徑都失效,添加<mvc:annotation-driven>解決
11.2 重定向
- 語法:return "redirect:/xxx.html";
11.3 加載靜態資源
-
由DefaultServlet加載靜態資源到服務器
- 靜態資源:html、css、js等資源
- tomcat->conf->web.xml關鍵代碼如下:
<servlet> <servlet-name>default</servlet-name> <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>0</param-value> </init-param> <init-param> <param-name>listings</param-name> <param-value>false</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> -
發現問題
- DispatcherServlet與DefaultServlet的URL配置均為:/,導致DispatcherServlet中的配置將DefaultServlet配置的/覆寫了【DefaultServlet失效,無法加載靜態資源】
-
解決方案
<!-- 解決靜態資源加載問題--> <mvc:default-servlet-handler></mvc:default-servlet-handler> <!-- 添加上述標簽,會導致Controller無法正常使用,需要添加mvc:annotation-driven解決 --> <mvc:annotation-driven></mvc:annotation-driven>
11.4 原始碼決議重定向原理
-
創建RedirectView物件【ThymeleafViewResolver的775行代碼】
// Process redirects (HTTP redirects) if (viewName.startsWith(REDIRECT_URL_PREFIX)) { vrlogger.trace("[THYMELEAF] View \"{}\" is a redirect, and will not be handled directly by ThymeleafViewResolver.", viewName); final String redirectUrl = viewName.substring(REDIRECT_URL_PREFIX.length(), viewName.length()); final RedirectView view = new RedirectView(redirectUrl, isRedirectContextRelative(), isRedirectHttp10Compatible()); return (View) getApplicationContext().getAutowireCapableBeanFactory().initializeBean(view, REDIRECT_URL_PREFIX); } -
RedirectView視圖渲染
- RedirectView物件URL處理【330行代碼】

- 執行重定向【RedirectView的627行代碼】

第十二章 REST風格CRUD練習
12.1 搭建環境
-
匯入相關jar包
<!--spring-webmvc--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.1</version> </dependency> <!-- 匯入thymeleaf與spring5的整合包 --> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring5</artifactId> <version>3.0.12.RELEASE</version> </dependency> <!--servlet-api--> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> -
撰寫組態檔
- web.xml
- CharacterEncodingFilter
- HiddenHttpMethodFilter
- DispatcherServlet
- springmvc.xml
- 開啟組件掃描
- 裝配視圖決議器
- 裝配視圖控制器
- 解決靜態資源加載問題
- 裝配annotation-driver
- web.xml
-
dao&pojo
12.2 實作功能思路
-
實作添加功能思路
- 跳轉添加頁面【查詢所有部門資訊】
- 實作添加功能
-
實作洗掉功能思路
-
方式一:直接使用表單實作DELETE提交方式
-
方式二:使用超鏈接【a】實作DELETE提交方式
-
使用Vue實作單擊超鏈接,后提交對應表單
-
取消超鏈接默認行為
-
示例代碼
<div align="center" id="app"> <a href="https://www.cnblogs.com/ygstudy/p/#" @click="deleteEmp">洗掉</a> <form id="delForm" th:action="@{/emps/}+${emp.id}" method="post"> <input type="hidden" name="_method" value="https://www.cnblogs.com/ygstudy/p/DELETE"> </form> </div> <script type="text/javascript" src="https://www.cnblogs.com/ygstudy/p/static/js/vue_v2.6.14.js"></script> <script type="text/javascript"> new Vue({ el:"#app", data:{}, methods:{ deleteEmp(){ alert("hehe"); //獲取回應表單 var formEle = document.getElementById("delForm"); formEle.submit(); //取消超鏈接默認行為 event.preventDefault(); } } }); </script>
-
-
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/543968.html
標籤:Java
上一篇:day10-1-中文亂碼處理
