1.回顧MVC
1.1什么是MVC
-
MVC是模型(Model)、視圖(View)、控制器(Controller)的簡寫,是一種軟體設計規范,
-
是將業務邏輯、資料、顯示分離的方法來組織代碼,
-
MVC主要作用是降低了視圖與業務邏輯間的雙向偶合,
-
MVC不是一種設計模式,MVC是一種架構模式,當然不同的MVC存在差異,
Model(模型):資料模型,提供要展示的資料,因此包含資料和行為,可以認為是領域模型或JavaBean組件(包含資料和行為),不過現在一般都分離開來:Value Object(資料Dao) 和 服務層(行為Service),也就是模型提供了模型資料查詢和模型資料的狀態更新等功能,包括資料和業務,
View(視圖):負責進行模型的展示,一般就是我們見到的用戶界面,客戶想看到的東西,
Controller(控制器):接收用戶請求,委托給模型進行處理(狀態改變),處理完畢后把回傳的模型資料回傳給視圖,由視圖負責展示,也就是說控制器做了個調度員的作業,
最典型的MVC就是JSP + servlet + javabean的模式,

1.2Model1時代
-
在web早期的開發中,通常采用的都是Model1,
-
Model1中,主要分為兩層,視圖層和模型層,

Model1優點:架構簡單,比較適合小型專案開發;
Model1缺點:JSP職責不單一,職責過重,不便于維護;
1.3Model2時代
Model2把一個專案分成三部分,包括視圖、控制、模型,

-
用戶發請求
-
Servlet接收請求資料,并呼叫對應的業務邏輯方法
-
業務處理完畢,回傳更新后的資料給servlet
-
servlet轉向到JSP,由JSP來渲染頁面
-
回應給前端更新后的頁面
職責分析:
Controller:控制器
-
取得表單資料
-
呼叫業務邏輯
-
轉向指定的頁面
Model:模型
-
業務邏輯
-
保存資料的狀態
View:視圖
- 顯示頁面
Model2這樣不僅提高的代碼的復用率與專案的擴展性,且大大降低了專案的維護成本,Model 1模式的實作比較簡單,適用于快速開發小規模專案,Model1中JSP頁面身兼View和Controller兩種角色,將控制邏輯和表現邏輯混雜在一起,從而導致代碼的重用性非常低,增加了應用的擴展性和維護的難度,Model2消除了Model1的缺點,
1.4回顧Servlet
1.4.1新建Maven匯入依賴
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.22</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
1.4.2 建子專案
為子專案添加Web
1.4.3 撰寫一個Servlet類
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.獲取前端引數
String method = req.getParameter("method");
if(method.equals("add")){
req.getSession().setAttribute("msg","執行了add方法");
}
if(method.equals("delete")){
req.getSession().setAttribute("msg","執行了delete方法");
}
//2.呼叫業務層
//3.視圖轉發或者重定向
req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
1.4.4 撰寫Hello.jsp
在WEB-INF目錄下新建一個jsp的檔案夾,新建test.jsp<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Kuangshen</title>
</head>
<body>
${msg}
</body>
</html>
1.4.5 web.xml中注冊Servlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.tang.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
1.4.5撰寫form.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/hello" method="post">
<input type="text" name="method">
<input type="submit" name="method">
</form>
</body>
</html>
1.4.6配置Tomcat,并啟動測驗
-
http://localhost:8080/SpringMVC_01_servlet_war_exploded/hello?method=add

*http://localhost:8080/SpringMVC_01_servlet_war_exploded/hello?method=delete

1.5MVC框架要做的事情
-
將url映射到java類或java類的方法 .
-
封裝用戶提交的資料 .
-
處理請求--呼叫相關的業務處理--封裝回應資料 .
-
將回應的資料進行渲染 . jsp / html 等表示層資料
說明:
常見的服務器端MVC框架有:Struts、Spring MVC、ASP.NET MVC、Zend Framework、JSF;常見前端MVC框架:vue、angularjs、react、backbone;由MVC演化出了另外一些模式如:MVP、MVVM 等等....
2.什么是SpringMVC
2.1、概述
Spring MVC是Spring Framework的一部分,是基于Java實作MVC的輕量級Web框架,查看官方檔案:https://docs.spring.io/spring-framework/docs/4.3.24.RELEASE/spring-framework-reference/html/
我們為什么要學習SpringMVC呢?
Spring MVC的特點:
-
輕量級,簡單易學
-
高效 , 基于請求回應的MVC框架
-
與Spring兼容性好,無縫結合
-
約定優于配置
-
功能強大:RESTful、資料驗證、格式化、本地化、主題等
-
簡潔靈活
Spring的web框架圍繞DispatcherServlet [ 調度Servlet ] 設計,
DispatcherServlet的作用是將請求分發到不同的處理器,從Spring 2.5開始,使用Java 5或者以上版本的用戶可以采用基于注解形式進行開發,十分簡潔;
正因為SpringMVC好 , 簡單 , 便捷 , 易學 , 天生和Spring無縫集成(使用SpringIoC和Aop) , 使用約定優于配置 . 能夠進行簡單的junit測驗 . 支持Restful風格 .例外處理 , 本地化 , 國際化 , 資料驗證 , 型別轉換 , 攔截器 等等......所以我們要學習 .
最重要的一點還是用的人多 , 使用的公司多 .
2.2、中心控制器
Spring的web框架圍繞DispatcherServlet設計,DispatcherServlet的作用是將請求分發到不同的處理器,從Spring 2.5開始,使用Java 5或者以上版本的用戶可以采用基于注解的controller宣告方式,
Spring MVC框架像許多其他MVC框架一樣, 以請求為驅動 , 圍繞一個中心Servlet分派請求及提供其他功能,DispatcherServlet是一個實際的Servlet (它繼承自HttpServlet 基類),

SpringMVC的原理如下圖所示:
當發起請求時被前置的控制器攔截到請求,根據請求引數生成代理請求,找到請求對應的實際控制器,控制器處理請求,創建資料模型,訪問資料庫,將模型回應給中心控制器,控制器使用模型與視圖渲染視圖結果,將結果回傳給中心控制器,再將結果回傳給請求者,

2.3、SpringMVC執行原理

圖為SpringMVC的一個較完整的流程圖,實線表示SpringMVC框架提供的技術,不需要開發者實作,虛線表示需要開發者實作,
簡要分析執行流程
-
DispatcherServlet表示前置控制器,是整個SpringMVC的控制中心,用戶 發出請求,DispatcherServlet接收請求并攔截請求,
我們假設請求的url為 : http://localhost:8080/SpringMVC/hello
如上url拆分成三部分:
http://localhost:8080服務器域名
SpringMVC部署在服務器上的web站點
hello表示控制器
通過分析,如上url表示為:請求位于服務器localhost:8080上的SpringMVC站點的hello控制器,
-
HandlerMapping為處理器映射,DispatcherServlet呼叫 HandlerMapping,HandlerMapping根據請求url查找Handler,
-
HandlerExecution表示具體的Handler,其主要作用是根據url查找控制器,如上url被查找控制器為:hello,
-
HandlerExecution將決議后的資訊傳遞給DispatcherServlet,如決議控制器映射等,
-
HandlerAdapter表示處理器配接器,其按照特定的規則去執行Handler,
-
Handler讓具體的Controller執行,
-
Controller將具體的執行資訊回傳給HandlerAdapter,如ModelAndView,
-
HandlerAdapter將視圖邏輯名或模型傳遞給DispatcherServlet,
-
DispatcherServlet呼叫視圖決議器(ViewResolver)來決議HandlerAdapter傳遞的邏輯視圖名,
-
視圖決議器將決議的邏輯視圖名傳給DispatcherServlet,
-
DispatcherServlet根據視圖決議器決議的視圖結果,呼叫具體的視圖,
-
最終視圖呈現給用戶,
在這里先聽一遍原理,不理解沒有關系,我們馬上來寫一個對應的代碼實作大家就明白了,如果不明白,那就寫10遍,沒有笨人,只有懶人!
3.第一個MVC程式
3.1、配置版
-
新建一個Moudle ,SpringMVC-02-hellomvc , 添加web的支持!
-
確定匯入了SpringMVC 的依賴!
-
配置web.xml , 注冊DispatcherServlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--1.注冊DispatcherServlet-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--關聯一個springmvc的組態檔:【servlet-name】-servlet.xml-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<!--啟動級別-1-->
<load-on-startup>1</load-on-startup>
</servlet>
<!--/ 匹配所有的請求;(不包括.jsp)-->
<!--/* 匹配所有的請求;(包括.jsp)-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
- 撰寫SpringMVC 的 組態檔!名稱:springmvc-servlet.xml
說明,這里的名稱要求是按照官方來的
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
- 在springmvc-servlet.xml 添加 處理映射器
<bean />
- 繼續添加添加 處理器配接器
<bean />
- 繼續添加 視圖決議器
<!--視圖決議器:DispatcherServlet給他的ModelAndView-->
<bean id="InternalResourceViewResolver">
<!--前綴-->
<property name="prefix" value="https://www.cnblogs.com/WEB-INF/jsp/"/>
<!--后綴-->
<property name="suffix" value="https://www.cnblogs.com/twq46/archive/2022/08/26/.jsp"/>
</bean>
- 撰寫我們要操作業務Controller ,要么實作Controller介面,要么增加注解;需要回傳一個ModelAndView,裝資料,封視圖;
//注意:這里我們先匯入Controller介面
public class HelloController implements Controller {
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
//ModelAndView 模型和視圖
ModelAndView mv = new ModelAndView();
//封裝物件,放在ModelAndView中,Model
mv.addObject("msg", "HelloSpringMVC!");
//封裝要跳轉的視圖,放在ModelAndView中
mv.setViewName("hello"); //: /WEB-INF/jsp/hello.jsp
return mv;
}
}
- 將自己的類交給SpringIOC容器,注冊bean
<!--Handler-->
<bean id="/hello" />
- 寫要跳轉的jsp頁面,顯示ModelandView存放的資料,以及我們的正常頁面;
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
- 配置Tomcat 啟動測驗!

可能遇到的問題:訪問出現404,排查步驟:
-
查看控制臺輸出,看一下是不是缺少了什么jar包,
-
如果jar包存在,顯示無法輸出,就在IDEA的專案發布中,添加lib依賴!

-
重啟Tomcat 即可解決!
小結:看這個估計大部分同學都能理解其中的原理了,但是我們實際開發才不會這么寫,不然就瘋了,還學這個玩意干嘛!我們來看個注解版實作,這才是SpringMVC的精髓,到底有多么簡單,看這個圖就知道了

3.2、注解版
-
新建一個Moudle,SpringMVC-03-annotation ,添加web支持!
-
由于Maven可能存在資源過濾的問題,我們將配置完善
-
配置web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--1.注冊servlet--> <servlet> <servlet-name>SpringMVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--通過初始化引數指定SpringMVC組態檔的位置,進行關聯--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc-servlet.xml</param-value> </init-param> <!-- 啟動順序,數字越小,啟動越早 --> <load-on-startup>1</load-on-startup> </servlet> <!--所有請求都會被springmvc攔截 --> <servlet-mapping> <servlet-name>SpringMVC</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app> -
添加Spring MVC組態檔
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 自動掃描包,讓指定包下的注解生效,由IOC容器統一管理 --> <context:component-scan base-package="com.tang.controller"/> <!-- 讓Spring MVC不處理靜態資源 --> <mvc:default-servlet-handler /> <!-- 支持mvc注解驅動 在spring中一般采用@RequestMapping注解來完成映射關系 要想使@RequestMapping注解生效 必須向背景關系中注冊DefaultAnnotationHandlerMapping 和一個AnnotationMethodHandlerAdapter實體 這兩個實體分別在類級別和方法級別處理, 而annotation-driven配置幫助我們自動完成上述兩個實體的注入, --> <mvc:annotation-driven /> <!-- 視圖決議器 --> <bean id="internalResourceViewResolver"> <!-- 前綴 --> <property name="prefix" value="https://www.cnblogs.com/WEB-INF/jsp/" /> <!-- 后綴 --> <property name="suffix" value="https://www.cnblogs.com/twq46/archive/2022/08/26/.jsp" /> </bean> </beans> -
創建Controller
撰寫一個Java控制類:com.kuang.controller.HelloController , 注意編碼規范@Controller public class HelloController { //真實訪問地址 : 專案名/h1 @RequestMapping("/h1") public String sayHello(Model model){ //向模型中添加屬性msg與值,可以在JSP頁面中取出并渲染 model.addAttribute("msg","hello,SpringMVC"); //web-inf/jsp/hello.jsp return "hello"; } }-
@Controller是為了讓Spring IOC容器初始化時自動掃描到;
-
@RequestMapping是為了映射請求路徑,這里因為類與方法上都有映射所以訪問時應該是/HelloController/hello;
-
-
方法中宣告Model型別的引數是為了把Action中的資料帶到視圖中;
-
方法回傳的結果是視圖的名稱hello,加上組態檔中的前后綴變成WEB-INF/jsp/hello.jsp,
創建視圖層
在WEB-INF/ jsp目錄中創建hello.jsp , 視圖可以直接取出并展示從Controller帶回的資訊;
可以通過EL表示取出Model中存放的值,或者物件;
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>SpringMVC</title>
</head>
<body>
${msg}
</body>
</html>
測驗結果圖

-
小結
-
實作步驟其實非常的簡單:
-
新建一個web專案
-
匯入相關jar包
-
撰寫web.xml , 注冊DispatcherServlet
-
撰寫springmvc組態檔
-
接下來就是去創建對應的控制類 , controller
-
最后完善前端視圖和controller之間的對應
測驗運行除錯.
使用springMVC必須配置的三大件:
處理器映射器、處理器配接器、視圖決議器
通常,我們只需要手動配置視圖決議器,而處理器映射器和處理器配接器只需要開啟注解驅動即可,而省去了大段的xml配置
-
4.控制器controller
-
控制器復雜提供訪問應用程式的行為,通常通過介面定義或注解定義兩種方法實作,
-
控制器負責決議用戶的請求并將其轉換為一個模型,
-
在Spring MVC中一個控制器類可以包含多個方法
-
在Spring MVC中,對于Controller的配置方式有很多種
4.1實作Controller介面
Controller是一個介面,在org.springframework.web.servlet.mvc包下,介面中只有一個方法; 測驗- 新建一個Moudle,SpringMVC-04-controller ,將剛才的03 拷貝一份, 我們進行操作!
-
刪掉HelloController
-
mvc的組態檔只留下 視圖決議器!
撰寫一個Controller類,ControllerTest1
public class ControllerTest1 implements Controller {
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView mv = new ModelAndView();
mv.addObject("msg","ControllerTest1");
mv.setViewName("test");
return mv;
}
}
- 撰寫完畢后,去Spring組態檔中注冊請求的bean;name對應請求路徑,class對應處理請求的類
<bean name="/t1" ></bean>
- 撰寫前端test.jsp,注意在WEB-INF/jsp目錄下撰寫,對應我們的視圖決議器
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
配置Tomcat運行測驗,我這里沒有專案發布名配置的就是一個 / ,所以請求不用加專案名,OK!

4.2使用注解@Controller
-
@Controller注解型別用于宣告Spring類的實體是一個控制器(在講IOC時還提到了另外3個注解);
-
Spring可以使用掃描機制來找到應用程式中所有基于注解的控制器類,為了保證Spring能找到你的控制器,需要在組態檔中宣告組件掃描,
<!-- 自動掃描包,讓指定包下的注解生效,由IOC容器統一管理 -->
<context:component-scan base-package="com.tang.controller"/>
- 增加一個ControllerTest2類,使用注解實作;
@Controller
public class ControllerTest2 {
//映射訪問路徑
@RequestMapping("/t2")
public String test(Model model){
//Spring MVC會自動實體化一個Model物件用于向視圖中傳值
model.addAttribute("msg","ControllerTest2");
//回傳視圖位置
return "test";
}
}
運行tomcat測驗

可以發現,我們的兩個請求都可以指向一個視圖,但是頁面結果的結果是不一樣的,從這里可以看出視圖是被復用的,而控制器與視圖之間是弱偶合關系,
注解方式是平時使用的最多的方式!
4.3RestFul風格
概念
Restful就是一個資源定位及資源操作的風格,不是標準也不是協議,只是一種風格,基于這個風格設計的軟體可以更簡潔,更有層次,更易于實作快取等機制,
功能
資源:互聯網所有的事物都可以被抽象為資源
資源操作:使用POST、DELETE、PUT、GET,使用不同方法對資源進行操作,
分別對應 添加、 洗掉、修改、查詢,
傳統方式操作資源 :通過不同的引數來實作不同的效果!方法單一,post 和 get
http://127.0.0.1/item/queryItem.action?id=1 查詢,GET
http://127.0.0.1/item/saveItem.action 新增,POST
http://127.0.0.1/item/updateItem.action 更新,POST
http://127.0.0.1/item/deleteItem.action?id=1 洗掉,GET或POST
使用RESTful操作資源 :可以通過不同的請求方式來實作不同的效果!如下:請求地址一樣,但是功能可以不同!
http://127.0.0.1/item/1 查詢,GET
http://127.0.0.1/item 新增,POST
http://127.0.0.1/item 更新,PUT
http://127.0.0.1/item/1 洗掉,DELETE
學習測驗
在新建一個類 RestFulController

4.4結果跳轉方式
通過SpringMVC來實作轉發和重定向 - 無需視圖決議器;
測驗前,需要將視圖決議器注釋掉
@Controller
public class ResultSpringMVC {
@RequestMapping("/rsm/t1")
public String test1(){
//轉發
return "/index.jsp";
}
@RequestMapping("/rsm/t2")
public String test2(){
//轉發二
return "forward:/index.jsp";
}
@RequestMapping("/rsm/t3")
public String test3(){
//重定向
return "redirect:/index.jsp";
}
}
通過SpringMVC來實作轉發和重定向 - 有視圖決議器;
重定向 , 不需要視圖決議器 , 本質就是重新請求一個新地方嘛 , 所以注意路徑問題.
可以重定向到另外一個請求實作 .
@Controller
public class ResultSpringMVC2 {
@RequestMapping("/rsm2/t1")
public String test1(){
//轉發
return "test";
}
@RequestMapping("/rsm2/t2")
public String test2(){
//重定向
return "redirect:/index.jsp";
//return "redirect:hello.do"; //hello.do為另一個請求/
}
}
4.5資料處理
處理提交資料4.5.1提交的域名稱和處理方法的引數名一致
提交資料 : http://localhost:8080/SpringMVC_04_controller_war_exploded/user/t1?name=Twq處理方法 :
@RequestMapping("/user")
public class UserController {
@GetMapping("/t1")
public String test1(String name,Model model){
//1.接收前端引數
System.out.println("接收到的前端的引數為:" +name);
//2.回傳的結果傳遞給前端
model.addAttribute("msg",name);
//3.視圖跳轉
return "test";
}
}
4.5.2提交的域名稱和處理方法的引數名不一致

4.5.3提交的域名稱和處理方法的引數名不一致
@Controller
@RequestMapping("/user")
public class UserController {
@GetMapping("/t1")
public String test1(@RequestParam("username") String name, Model model){
//1.接收前端引數
System.out.println("接收到的前端的引數為:" +name);
//2.回傳的結果傳遞給前端
model.addAttribute("msg",name);
//3.視圖跳轉
return "test";
}
}

4.5.4提交的是一個物件
要求提交的表單域和物件的屬性名一致 , 引數使用物件即可@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String name;
private int age;
}
測驗代碼
//前端接受的是一個物件:id,name,age
/*
1.接收前端用戶傳的引數,判斷引數的名字,假設名字直接在方法上,可以直接使用
2.假設出阿尼的是一個物件User,匹配User物件中的欄位名:如果名字一致則OK,否則,匹配不到
*/
@GetMapping("/t2")
public String test2(User user){
System.out.println(user);
return "test";
}


4.6亂碼問題解決
@Controller
public class EncodingController {
@PostMapping("e1/t1")
public String test(String name,Model model){
model.addAttribute("msg",name);
return "test";
}
}
提交界面
<body>
<form action="e1/t1" method="post">
用戶名 <input type="text" name="name">
<input type="submit">
</form>
</body>
測驗結果

解決方法
在web.xml中配置SpringMVC的亂碼的過濾
<!--配置SpringMVC的亂碼過濾 -->
<filter>
<filter-name>encoding</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>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
在啟動Tomcat測驗

如果以上方法還是解決不了,可以自定義以下過濾器,以下代碼建議全部復制,如果讓IDEA自動導包的話可能會倒錯包,以下代碼為網上大牛寫的,實在不行的情況下建議使用
package com.tang.filter;//這一行除外,根據自己的包名寫
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;
/**
* 解決get和post請求 全部亂碼的過濾器
*/
public class GenericEncodingFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//處理response的字符編碼
HttpServletResponse myResponse=(HttpServletResponse) response;
myResponse.setContentType("text/html;charset=UTF-8");
// 轉型為與協議相關物件
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
// 對request包裝增強
HttpServletRequest myrequest = new MyRequest(httpServletRequest);
chain.doFilter(myrequest, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
}
}
//自定義request物件,HttpServletRequest的包裝類
class MyRequest extends HttpServletRequestWrapper {
private HttpServletRequest request;
//是否編碼的標記
private boolean hasEncode;
//定義一個可以傳入HttpServletRequest物件的建構式,以便對其進行裝飾
public MyRequest(HttpServletRequest request) {
super(request);// super必須寫
this.request = request;
}
// 對需要增強方法 進行覆寫
@Override
public Map getParameterMap() {
// 先獲得請求方式
String method = request.getMethod();
if (method.equalsIgnoreCase("post")) {
// post請求
try {
// 處理post亂碼
request.setCharacterEncoding("utf-8");
return request.getParameterMap();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
} else if (method.equalsIgnoreCase("get")) {
// get請求
Map<String, String[]> parameterMap = request.getParameterMap();
if (!hasEncode) { // 確保get手動編碼邏輯只運行一次
for (String parameterName : parameterMap.keySet()) {
String[] values = parameterMap.get(parameterName);
if (values != null) {
for (int i = 0; i < values.length; i++) {
try {
// 處理get亂碼
values[i] = new String(values[i]
.getBytes("ISO-8859-1"), "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
}
hasEncode = true;
}
return parameterMap;
}
return super.getParameterMap();
}
//取一個值
@Override
public String getParameter(String name) {
Map<String, String[]> parameterMap = getParameterMap();
String[] values = parameterMap.get(name);
if (values == null) {
return null;
}
return values[0]; // 取回引數的第一個值
}
//取所有值
@Override
public String[] getParameterValues(String name) {
Map<String, String[]> parameterMap = getParameterMap();
String[] values = parameterMap.get(name);
return values;
}
}
web.xml注冊該過濾器
<filter>
<filter-name>encoding</filter-name>
<filter-class>com.tang.filter.GenericEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
6.JSON
6.1什么是JSON
-
JSON(JavaScript Object Notation, JS 物件標記) 是一種輕量級的資料交換格式,目前使用特別廣泛,
-
采用完全獨立于編程語言的文本格式來存盤和表示資料,
-
簡潔和清晰的層次結構使得 JSON 成為理想的資料交換語言,
-
易于人閱讀和撰寫,同時也易于機器決議和生成,并有效地提升網路傳輸效率,
在 JavaScript 語言中,一切都是物件,因此,任何JavaScript 支持的型別都可以通過 JSON 來表示,例如字串、數字、物件、陣列等,看看他的要求和語法格式:
-
物件表示為鍵值對,資料由逗號分隔
-
花括號保存物件
-
方括號保存陣列
JSON 鍵值對是用來保存 JavaScript 物件的一種方式,和 JavaScript 物件的寫法也大同小異,鍵/值對組合中的鍵名寫在前面并用雙引號 "" 包裹,使用冒號 : 分隔,然后緊接著值:
{"name": "QinJiang"}
{"age": "3"}
{"sex": "男"}
很多人搞不清楚 JSON 和 JavaScript 物件的關系,甚至連誰是誰都不清楚,其實,可以這么理解:
JSON 是 JavaScript 物件的字串表示法,它使用文本表示一個 JS 物件的資訊,本質是一個字串,
var obj = {a: 'Hello',
b: 'World'}; //這是一個物件,注意鍵名也是可以使用引號包裹的
var json = '{"a": "Hello",
"b": "World"}'; //這是一個 JSON 字串,本質是一個字串
JSON 和 JavaScript 物件互轉
要實作從JSON字串轉換為JavaScript 物件,使用 JSON.parse() 方法:
var obj = JSON.parse('{"a": "Hello", "b": "World"}');
//結果是 {a: 'Hello', b: 'World'}
要實作從JavaScript 物件轉換為JSON字串,使用 JSON.stringify() 方法:
var json = JSON.stringify({a: 'Hello', b: 'World'});
//結果是 '{"a": "Hello", "b": "World"}'
代碼測驗
-
新建一個module ,springmvc-05-json , 添加web的支持
-
在web目錄下新建一個 json-1.html , 撰寫測驗內容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JSON</title>
</head>
<body>
<script type="text/javascript">
//撰寫一個js的物件
var user = {
name:"唐昊",
age:21,
sex:"男"
};
//將js物件轉換成json字串
var str = JSON.stringify(user);
console.log(str);
//將json字串轉換為js物件
var user2 = JSON.parse(str);
console.log(user2.age,user2.name,user2.sex);
</script>
</body>
</html>

6.2Jackson使用
Jackson應該是目前比較好的json決議工具了當然工具不止這一個,比如還有阿里巴巴的 fastjson 等等,
我們這里使用Jackson,使用它需要匯入它的jar包;
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.3</version>
</dependency>
配置SpringMVC需要的配置
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--1.注冊servlet-->
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--通過初始化引數指定SpringMVC組態檔的位置,進行關聯-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<!-- 啟動順序,數字越小,啟動越早 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!--所有請求都會被springmvc攔截 -->
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>encoding</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>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/</url-pattern>
</filter-mapping>
</web-app>
springmvc-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 自動掃描指定的包,下面所有注解類交給IOC容器管理 -->
<context:component-scan base-package="com.tang.controller"/>
<context:annotation-config />
<mvc:annotation-driven />
<!-- 視圖決議器 -->
<bean
id="internalResourceViewResolver">
<!-- 前綴 -->
<property name="prefix" value="https://www.cnblogs.com/WEB-INF/jsp/" />
<!-- 后綴 -->
<property name="suffix" value="https://www.cnblogs.com/twq46/archive/2022/08/26/.jsp" />
</bean>
</beans>
這里我們需要兩個新東西,一個是@ResponseBody,一個是ObjectMapper物件,我們看下具體的用法
撰寫一個Controller;
package com.tang.controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tang.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class UserController {
@RequestMapping("/j1")
@ResponseBody
public String test() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
User user = new User("唐三", 2, "女");
String str = mapper.writeValueAsString(user);
return str;
}
}
物體類
package com.tang.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String name;
private int age;
private String sex;
}
發現出現了亂碼問題,我們需要設定一下他的編碼格式為utf-8,以及它回傳的型別;
通過@RequestMaping的produces屬性來實作,修改下代碼
//produces:指定回應體回傳型別和編碼
@RequestMapping(value = "https://www.cnblogs.com/json1",produces = "application/json;charset=utf-8")
再次測驗發現亂碼問題解決
亂碼統一解決
上一種方法比較麻煩,如果專案中有許多請求則每一個都要添加,可以通過Spring配置統一指定,這樣就不用每次都去處理了!
我們可以在springmvc的組態檔上添加一段訊息StringHttpMessageConverter轉換配置!
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean >
<constructor-arg value="https://www.cnblogs.com/twq46/archive/2022/08/26/UTF-8"/>
</bean>
<bean >
<property name="objectMapper">
<bean >
<property name="failOnEmptyBeans" value="https://www.cnblogs.com/twq46/archive/2022/08/26/false"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
回傳json字串統一解決
在類上直接使用 @RestController ,這樣子,里面所有的方法都只會回傳 json 字串了,不用再每一個都添加@ResponseBody !我們在前后端分離開發中,一般都使用 @RestController ,十分便捷!
@RestController
public class UserController {
//produces:指定回應體回傳型別和編碼
@RequestMapping(value = "https://www.cnblogs.com/json1")
public String json1() throws JsonProcessingException {
//創建一個jackson的物件映射器,用來決議資料
ObjectMapper mapper = new ObjectMapper();
//創建一個物件
User user = new User("秦疆1號", 3, "男");
//將我們的物件決議成為json格式
String str = mapper.writeValueAsString(user);
//由于@ResponseBody注解,這里會將str轉成json格式回傳;十分方便
return str;
}
}
6.3fastjson
fastjson.jar是阿里開發的一款專門用于Java開發的包,可以方便的實作json物件與JavaBean物件的轉換,實作JavaBean物件與json字串的轉換,實作json物件與json字串的轉換,實作json的轉換方法很多,最后的實作結果都是一樣的,
fastjson 的 pom依賴!
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.60</version>
</dependency>
fastjson 三個主要的類:
-
JSONObject 代表 json 物件
-
JSONObject實作了Map介面, 猜想 JSONObject底層操作是由Map實作的,
-
JSONObject對應json物件,通過各種形式的get()方法可以獲取json物件中的資料,也可利用諸如size(),isEmpty()等方法獲取"鍵:值"對的個數和判斷是否為空,其本質是通過實作Map介面并呼叫介面中的方法完成的,
-
-
JSONArray 代表 json 物件陣列
- 內部是有List介面中的方法來完成操作的,
-
JSON代表 JSONObject和JSONArray的轉化
-
JSON類原始碼分析與使用
-
仔細觀察這些方法,主要是實作json物件,json物件陣列,javabean物件,json字串之間的相互轉化,
-
package com.tang.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.kuang.pojo.User;
import java.util.ArrayList;
import java.util.List;
public class FastJsonDemo {
public static void main(String[] args) {
//創建一個物件
User user1 = new User("唐昊1號", 3, "男");
User user2 = new User("唐昊2號", 3, "男");
User user3 = new User("唐昊3號", 3, "男");
User user4 = new User("唐昊4號", 3, "男");
List<User> list = new ArrayList<User>();
list.add(user1);
list.add(user2);
list.add(user3);
list.add(user4);
System.out.println("*******Java物件 轉 JSON字串*******");
String str1 = JSON.toJSONString(list);
System.out.println("JSON.toJSONString(list)==>"+str1);
String str2 = JSON.toJSONString(user1);
System.out.println("JSON.toJSONString(user1)==>"+str2);
System.out.println("\n****** JSON字串 轉 Java物件*******");
User jp_user1=JSON.parseObject(str2,User.class);
System.out.println("JSON.parseObject(str2,User.class)==>"+jp_user1);
System.out.println("\n****** Java物件 轉 JSON物件 ******");
JSONObject jsonObject1 = (JSONObject) JSON.toJSON(user2);
System.out.println("(JSONObject) JSON.toJSON(user2)==>"+jsonObject1.getString("name"));
System.out.println("\n****** JSON物件 轉 Java物件 ******");
User to_java_user = JSON.toJavaObject(jsonObject1, User.class);
System.out.println("JSON.toJavaObject(jsonObject1, User.class)==>"+to_java_user);
}
}
7.SSM整合
匯入依賴<?xml version="1.0" encoding="UTF-8" ?>
<!--maven的版本和頭檔案-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example </groupId>
<artifactId>SSMBuild</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 建立父子關系時,父類的打包方式必須是pom,而且必須宣告-->
<packaging>pom</packaging>
<dependencies>
<!--Junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<!--資料庫驅動-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<!-- 資料庫連接池 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.5</version>
</dependency>
<!--Servlet - JSP -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!--Mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.10</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.7</version>
</dependency>
<!--Spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.22</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.22</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>
7.1Mybatis層
專案結構圖
7.1.1撰寫db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssmbuild?useSSL=true&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=root123456
7.1.2IDEA關聯資料庫

7.1.3撰寫MyBatis的核心組態檔
mybatis-config.xml<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="com.tang.pojo"/>
</typeAliases>
<mappers>
<mapper />
</mappers>
</configuration>
7.1.4.撰寫物體類
Books@Data
@AllArgsConstructor
@NoArgsConstructor
public class Books {
private int bookID;
private String bookName;
private int bookCounts;
private String detail;
}
7.1.5撰寫Dao層的 Mapper介面!
public interface BookMapper {
//增加一本書
int addBook(Books books);
//洗掉一本書
int deleteBookById(@Param("bookId") int id);
//更新一本書
int updateBook(Books books);
//查詢一本書
Books queryBookById(@Param("bookId") int id);
//查詢全部的書
List<Books> queryAllBook();
}
7.1.6撰寫介面對應的 Mapper.xml 檔案
需要匯入MyBatis的包; BookMapper.xml<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tang.dao.BookMapper">
<!--增加一本Book-->
<insert id="addBook" parameterType="Books">
insert into ssmbuild.books (bookName,bookCounts,detail)
values (#{bookName},#{bookCounts},#{detail})
</insert>
<!--根據id洗掉一本Book-->
<delete id="deleteBookById" parameterType="int">
delete from ssmbuild.books where bookID=#{bookId}
</delete>
<!--更新Book-->
<update id="updateBook" parameterType="Books">
update ssmbuild.books
set bookName=#{bookName},bookCounts=#{bookCounts},detail=#{detail}
where bookID=#{bookID}
</update>
<!--根據id查詢,回傳一本Book-->
<select id="queryBookById" resultType="Books">
select * from books
where bookID=#{bookId}
</select>
<!--查詢全部Book-->
<select id="queryAllBook" resultType="Books">
select * from books
</select>
</mapper>
7.1.7撰寫Service層的介面和實作類
介面
public interface BookService {
//增加一本書
int addBook(Books books);
//洗掉一本書
int deleteBookById( int id);
//更新一本書
int updateBook(Books books);
//查詢一本書
Books queryBookById(int id);
//查詢全部的書
List<Books> queryAllBook();
}
實作類
package com.tang.service;
import com.tang.dao.BookMapper;
import com.tang.pojo.Books;
import java.util.List;
public class BookServiceImpl implements BookService{
//service調dao層,組合Dao
private BookMapper bookMapper;
public void setBookMapper(BookMapper bookMapper){
this.bookMapper = bookMapper;
}
public int addBook(Books books) {
return bookMapper.addBook(books);
}
public int deleteBookById(int id) {
return bookMapper.deleteBookById(id);
}
public int updateBook(Books books) {
return bookMapper.updateBook(books);
}
public Books queryBookById(int id) {
return bookMapper.queryBookById(id);
}
public List<Books> queryAllBook() {
return bookMapper.queryAllBook();
}
}
OK,到此,底層需求操作撰寫完畢!
7.2Spring層
7.2.1配置Spring整合MyBatis
我們這里資料源使用c3p0連接池;7.2.2撰寫Spring整合Mybatis的組態檔
7.2.3spring整合dao層
spring-dao.xml<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--1.關聯資料庫組態檔-->
<context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
<!--2.連接池-->
<!--資料庫連接池
dbcp 半自動化操作 不能自動連接
c3p0 自動化操作(自動的加載組態檔 并且設定到物件里面)
-->
<bean id="dataSource" >
<property name="driverClass" value="https://www.cnblogs.com/twq46/archive/2022/08/26/${jdbc.driver}"/>
<property name="jdbcUrl" value="https://www.cnblogs.com/twq46/archive/2022/08/26/${jdbc.url}"/>
<property name="user" value="https://www.cnblogs.com/twq46/archive/2022/08/26/${jdbc.username}"/>
<property name="password" value="https://www.cnblogs.com/twq46/archive/2022/08/26/${jdbc.password}"/>
<!-- c3p0連接池的私有屬性 -->
<property name="maxPoolSize" value="https://www.cnblogs.com/twq46/archive/2022/08/26/30"/>
<property name="minPoolSize" value="https://www.cnblogs.com/twq46/archive/2022/08/26/10"/>
<!-- 關閉連接后不自動commit -->
<property name="autoCommitOnClose" value="https://www.cnblogs.com/twq46/archive/2022/08/26/false"/>
<!-- 獲取連接超時時間 ms-->
<property name="checkoutTimeout" value="https://www.cnblogs.com/twq46/archive/2022/08/26/10000"/>
<!-- 當獲取連接失敗重試次數 -->
<property name="acquireRetryAttempts" value="https://www.cnblogs.com/twq46/archive/2022/08/26/2"/>
</bean>
<!-- 3.配置SqlSessionFactory物件 -->
<bean id="sqlSessionFactory" >
<!-- 注入資料庫連接池 -->
<property name="dataSource" ref="dataSource"/>
<!-- 配置MyBaties全域組態檔:mybatis-config.xml -->
<property name="configLocation" value="https://www.cnblogs.com/twq46/archive/2022/08/26/classpath:mybatis-config.xml"/>
</bean>
<!--配置dao介面掃描包,動態的實作了Dao介面可以注入到Spring容器中-->
<bean >
<property name="sqlSessionFactoryBeanName" value="https://www.cnblogs.com/twq46/archive/2022/08/26/sqlSessionFactory"/>
<!--要掃描的dao包-->
<property name="basePackage" value="https://www.cnblogs.com/twq46/archive/2022/08/26/com.tang.dao"/>
</bean>
</beans>
7.2.4Spring整合service層
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--1. 掃描service相關的bean -->
<context:component-scan base-package="com.tang.service" />
<!--2.BookServiceImpl注入到IOC容器中-->
<bean id="BookServiceImpl" >
<!--service層要和dao層聯系起來,除了IDEA自動幫我們做的之外,
還可以在service層通過import來匯入spring-dao.xml使得service層和dao層關聯起來-->
<property name="bookMapper" ref="bookMapper"/>
</bean>
<!--3.配置事務管理器 -->
<bean id="transactionManager" >
<!-- 注入資料庫連接池 -->
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
7.3SpringMVC層
7.3.1web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--DispatchServlet-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--亂碼過濾-->
<filter>
<filter-name>encoding</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>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--Session-->
<session-config>
<session-timeout>15</session-timeout>
</session-config>
</web-app>
7.3.2spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--1.注解驅動-->
<mvc:annotation-driven/>
<!--2.靜態資源過濾-->
<mvc:default-servlet-handler/>
<!--3.掃描包:controller-->
<context:component-scan base-package="com.tang.controller"/>
<!--4.視圖決議器-->
<bean >
<property name="prefix" value="https://www.cnblogs.com/WEB-INF/jsp"/>
<property name="suffix" value="https://www.cnblogs.com/twq46/archive/2022/08/26/.jsp"/>
</bean>
</beans>
7.3.3applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="classpath:spring-dao.xml"/>
<import resource="classpath:spring-service.xml"/>
<import resource="classpath:spring-mvc.xml"/>
</beans>
7.4查詢書籍功能
7.4.1 BookController類撰寫
方法一:查詢全部書籍package com.tang.controller;
import com.tang.pojo.Books;
import com.tang.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
@RequestMapping("/book")
public class BookController {
//controller調service層
@Autowired
@Qualifier("BookServiceImpl")
public BookService bookService;
//查詢全部的書籍,并且回傳到一個書籍展示界面
@RequestMapping("/allBook")
public String list(Model model){
List<Books> list = bookService.queryAllBook();
model.addAttribute("list",list);
return "allBook";
}
}
7.4.2撰寫首頁 index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>首頁</title>
</head>
<body>
<h3>
<a href="https://www.cnblogs.com/twq46/archive/2022/08/26/${pageContext.request.contextPath}/book/allBook">進入書籍頁面</a>
</h3>
</body>
</html>
7.4.3書籍串列頁面 allbook.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>書籍展示頁面</title>
</head>
<body>
<h1>書籍展示</h1>
</body>
</html>
先測驗一下,看會不會報錯,我總共遇到三個錯誤
-
專案發布失敗,檢查發現,在專案結構中沒有加上lib目錄并匯入相應庫檔案,加上后就可以正常發布專案
-
target檔案中發現xml和properties都沒有,一開始以為是pom檔案中的bulid寫錯了,最后發現專案的pom檔案中專案的打包方式寫錯了,最后將打包方式改為jar的方式即可
-
然后再繼續運行發現又報錯說No qualifying bean of type 'com.tang.service.BookService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier("BookServiceImpl")}
解決步驟:
-
查看這個bean是否注入成功!ok
-
Junit單元測驗,看我們的代碼是否能夠查詢出來結果 ok

-
問題一定不再底層,是spring出了問題
-
SpringMVC,整合的時候沒呼叫到我們的service層的bean:
- applicationContext.xml沒有注入bean
- web.xml中,我們也系結過組態檔,發現我們配置的是Spring-mvc.xml這里面沒有service bean,解決方方法將web.xml中Spring-mvc.xml改為applicationContext.xml
最終結果

7.4.4美化首頁
撰寫首頁 index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>首頁</title>
<style>
a{
text-decoration: none;/*去除a標簽的下劃線*/
color: black;
font-size: 18px;
}
h3{
width: 180px;
height: 38px;
margin: 100px auto;
text-align: center;
line-height: 38px;
background: deepskyblue;
border-radius: 5px;
}
</style>
</head>
<body>
<h3>
<a href="https://www.cnblogs.com/twq46/archive/2022/08/26/${pageContext.request.contextPath}/book/allBook">進入書籍頁面</a>
</h3>
</body>
</html>
7.4.5美化書籍展示頁面
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>書籍展示頁面</title>
<!-- 引入 Bootstrap -->
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div >
<div >
<div >
<div >
<h1>
<small>書籍串列 —— 顯示所有書籍</small>
</h1>
</div>
</div>
</div>
<div >
<div >
<table >
<%--表格的標題--%>
<thead>
<tr>
<th>書籍編號</th>
<th>書籍名字</th>
<th>書籍數量</th>
<th>書籍詳情</th>
</tr>
</thead>
<%--書籍從資料庫中查詢出來,從這個list中遍歷出來:foreach--%>
<%--表格的身體--%>
<tbody>
<c:forEach var="book" items="${list}">
<tr>
<td>${book.bookID}</td>
<td>${book.bookName}</td>
<td>${book.bookCounts}</td>
<td>${book.detail}</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
運行Tomcat查看運行結果

7.5添加書籍功能
btn-primary(重點藍)、
btn-success(成功綠)、
btn-info(資訊藍)、
btn-warning(警告橙)、
btn-danger(危險紅)
在allBook界面先添加增加書籍的按鈕
<div >
<div >
<%--toAddBook--%>
<a href ="https://www.cnblogs.com/twq46/archive/2022/08/26/${pageContext.request.contextPath}/book/toAddBook">新增書籍</a>
</div>
</div>
當點擊新增書籍按鈕后先到controller
BookController代碼
@RequestMapping("/toAddBook")
public String toAddPage(){
return "addBook";//經過controller處理之后跳轉到增加書籍頁面
}
添加書籍前端頁面
addBook.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>新增書籍</title>
<!-- 引入 Bootstrap -->
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div >
<div >
<div >
<div >
<h1>
<small>新增書籍</small>
</h1>
</div>
</div>
</div>
<form action="${pageContext.request.contextPath}/book/addBook" method="post">
<div >
<label>書籍名稱:</label>
<input type="text" name="bookName" required>
</div>
<div >
<label>書籍數量:</label>
<input type="text" name="bookCounts" required>
</div>
<div >
<label>書籍描述:</label>
<input type="text" name="detail" required>
</div>
<div >
<input type="submit" value="https://www.cnblogs.com/twq46/archive/2022/08/26/添加">
</div>
</form>
</div>
</body>
</html>
當在添加書籍頁面點擊添加之后請求處理界面
BookController代碼
//添加書籍的請求
@RequestMapping("/addBook")
public String addBook(Books books){
System.out.println("addBook=>"+books);
bookService.addBook(books);
return "redirect:/book/allBook";//重定向到我們的@RequestMapping("/allBook")請求
}
運行結果

7.6修改書籍
現在展示所有書籍界面的表格中添加操作標題,并且添加修改和洗掉按鈕 allBook.jsp<td>
<%--當點擊修改時先跳轉到controller--%>
<a href="https://www.cnblogs.com/twq46/archive/2022/08/26/${pageContext.request.contextPath}/book/toUpdate?id=${book.bookID}">修改</a>
|
<a href="https://www.cnblogs.com/twq46/archive/2022/08/26/#">洗掉</a>
</td>
BookController
@RequestMapping("/toUpdate")
public String toUpdatePaper(int id,Model model){
Books books = bookService.queryBookById(id);//到修改頁面需要先將該書籍原來的資料查詢出來
model.addAttribute("QBooks",books);
return "updateBook";//跳轉到修改頁面
}
修改頁面updateBook.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>修改書籍</title>
<!-- 引入 Bootstrap -->
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div >
<div >
<div >
<div >
<h1>
<small>修改書籍</small>
</h1>
</div>
</div>
</div>
<form action="${pageContext.request.contextPath}/book/updateBook" method="post">
<div >
<label>書籍名稱:</label>
<%--value的值就是拿到該書原來的資料--%>
<input type="text" name="bookName" value="https://www.cnblogs.com/twq46/archive/2022/08/26/${QBooks.bookName}" required>
</div>
<div >
<label>書籍數量:</label>
<input type="text" name="bookCounts" value="https://www.cnblogs.com/twq46/archive/2022/08/26/${QBooks.bookCounts}" required>
</div>
<div >
<label>書籍描述:</label>
<input type="text" name="detail" value="https://www.cnblogs.com/twq46/archive/2022/08/26/${QBooks.detail}" required>
</div>
<div >
<input type="submit" value="https://www.cnblogs.com/twq46/archive/2022/08/26/修改">
</div>
</form>
</div>
</body>
</html>
處理點擊修改按鈕之后請求
//跳轉到修改頁面
@RequestMapping("/updateBook")
public String updateBook(Books books){
System.out.println("updateBook=>"+books);
bookService.updateBook(books);
return "redirect:/book/allBook";
}
測驗結果

出現的問題:我們提交了修改的SQL請求,但是修改失敗,初次考慮,是事務問題,配置完畢事務,依舊失敗
看一下SQL陳述句,能夠執行成功:SQL執行失敗,修改未完成,解決方法:在前端傳遞隱藏域
在updateBook.jsp頁面的form表單中添加隱藏域
<input type="hidden" name="bookID" value="https://www.cnblogs.com/twq46/archive/2022/08/26/${QBooks.bookID}">
再次測驗

7.7洗掉書籍
allBook.jsp中點擊洗掉后進行的操作<a href="https://www.cnblogs.com/twq46/archive/2022/08/26/${pageContext.request.contextPath}/book/toDelete/${book.bookID}">洗掉</a>
點擊洗掉后進入BookController
//洗掉書籍
@RequestMapping("/toDelete/{bookId}")
public String deleteBook(@PathVariable("bookId") int id){
bookService.deleteBookById(id);
return "redirect:/book/allBook";
}
測驗結果

7.8新增搜索功能
BookMapper添加介面//根據書名查詢
Books queryBookName(@Param("bookName") String bookName);
BookMapper.xml
<select id="queryBookName" resultType="Books">
select * from books where bookName=#{bookName}
</select>
service層BookService添加介面
//根據書名查詢書籍
Books queryBookName(String bookName);
BookServiceImpl
public Books queryBookName(String bookName) {
return bookMapper.queryBookName(bookName);
}
在所有書籍(allBook.jsp)界面中添加搜索框和搜索按鈕
<div >
<%--搜索書籍--%>
<form action="${pageContext.request.contextPath}/book/queryBook" method="post" style="float: right">
<input type="text" name="queryBookName" placeholder="請輸入要查詢的書籍名稱">
<input type="submit" value="https://www.cnblogs.com/twq46/archive/2022/08/26/查詢" >
</form>
</div>
點擊搜索先到controller層
//查詢書籍
@RequestMapping("/queryBook")
public String queryBook(String queryBookName,Model model){
Books books = bookService.queryBookName(queryBookName);
ArrayList<Books> list = new ArrayList<Books>();
list.add(books);
model.addAttribute("list",list);
return "allBook";
}
拓展添加一個顯示所有書籍的按鈕
<a href ="https://www.cnblogs.com/twq46/archive/2022/08/26/${pageContext.request.contextPath}/book/allBook">顯示全部書籍</a>
啟動Tomcat測驗

新增功能當未查到時提示未查到
BookController中查詢添加如下判斷
if(books == null){
list = bookService.queryAllBook();
model.addAttribute("error","未查到");
}
然后在前端界面顯示該提示
<span style="color:red; font-weight: bold ">${error}</span>
在啟動Tomcat測驗

將搜索框搜索按鈕以及提示資訊橫向展示只需要在搜索框的form表單中添加如下屬性即可
這個是我們的第一個SSM整合案例,一定要爛熟于心!
SSM框架的重要程度是不言而喻的,學到這里,大家已經可以進行基本網站的單獨開發,但是這只是增刪改查的基本操作,可以說學到這里,大家才算是真正的步入了后臺開發的門,也就是能找一個后臺相關作業的底線,
或許很多人,作業就做這些事情,但是對于個人的提高來說,還遠遠不夠!
我們后面還要學習一些 SpringMVC 的知識!
8.Ajax
最終的專案結構圖
8.1簡介
-
AJAX = Asynchronous JavaScript and XML(異步的 JavaScript 和 XML),
-
AJAX 是一種在無需重新加載整個網頁的情況下,能夠更新部分網頁的技術,
-
Ajax 不是一種新的編程語言,而是一種用于創建更好更快以及互動性更強的Web應用程式的技術,
-
在 2005 年,Google 通過其 Google Suggest 使 AJAX 變得流行起來,Google Suggest能夠自動幫你完成搜索單詞,
-
Google Suggest 使用 AJAX 創造出動態性極強的 web 界面:當您在谷歌的搜索框輸入關鍵字時,JavaScript 會把這些字符發送到服務器,然后服務器會回傳一個搜索建議的串列,
-
就和國內百度的搜索框一樣!
-
傳統的網頁(即不用ajax技術的網頁),想要更新內容或者提交一個表單,都需要重新加載整個網頁,
-
使用ajax技術的網頁,通過在后臺服務器進行少量的資料交換,就可以實作異步區域更新,
-
使用Ajax,用戶可以創建接近本地桌面應用的直接、高可用、更豐富、更動態的Web用戶界面,
8.2偽造Ajax
8.2.1測驗環境
applicationContext.xml以及web.xml中的內容就不在贅述了 AjaxController代碼@RestController
public class AjaxController {
@RequestMapping("/t1")
public String test(){
return "hello";
}
}
測驗結果

8.2.2iframe標簽來實作
我們可以使用前端的一個標簽來偽造一個ajax的樣子,就是點擊提交按鈕后將請求提交給iframe框中,而不是重繪當前頁面<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
<!--點擊提交按鈕就會觸發該事件-->
function go(){
//所有的值和變數,提前獲取
var url = document.getElementById("url").value;//拿到url的value值
document.getElementById("iframe1").src=https://www.cnblogs.com/twq46/archive/2022/08/26/url;//將iframe1的src值設定為付訓取的url
}
</script>
<body>
請輸入地址:
測驗結果

8.2.3jQuery.ajax
純JS原生實作Ajax我們不去講解這里,直接使用jquery提供的,方便學習和使用,避免重復造輪子,有興趣的同學可以去了解下JS原生XMLHttpRequest !
Ajax的核心是XMLHttpRequest物件(XHR),XHR為向服務器發送請求和決議服務器回應提供了介面,能夠以異步方式從服務器獲取新資料,
jQuery 提供多個與 AJAX 有關的方法,
通過 jQuery AJAX 方法,您能夠使用 HTTP Get 和 HTTP Post 從遠程服務器上請求文本、HTML、XML 或 JSON – 同時您能夠把這些外部資料直接載入網頁的被選元素中,
jQuery 不是生產者,而是大自然搬運工,
jQuery Ajax本質就是 XMLHttpRequest,對他進行了封裝,方便呼叫!
jQuery.ajax(...)
部分引數:
url:請求地址
type:請求方式,GET、POST(1.9.0之后用method)
headers:請求頭
data:要發送的資料
contentType:即將發送資訊至服務器的內容編碼型別(默認: "application/x-www-form-urlencoded; charset=UTF-8")
async:是否異步
timeout:設定請求超時時間(毫秒)
beforeSend:發送請求前執行的函式(全域)
complete:完成之后執行的回呼函式(全域)
success:成功之后執行的回呼函式(全域)
error:失敗之后執行的回呼函式(全域)
accepts:通過請求頭發送給服務器,告訴服務器當前客戶端可接受的資料型別
dataType:將服務器端回傳的資料轉換成指定型別
"xml": 將服務器端回傳的內容轉換成xml格式
"text": 將服務器端回傳的內容轉換成普通文本格式
"html": 將服務器端回傳的內容轉換成普通文本格式,在插入DOM中時,如果包含JavaScript標簽,則會嘗試去執行,
"script": 嘗試將回傳值當作JavaScript去執行,然后再將服務器端回傳的內容轉換成普通文本格式
"json": 將服務器端回傳的內容轉換成相應的JavaScript物件
"jsonp": JSONP 格式使用 JSONP 形式呼叫函式時,如 "myurl?callback=?" jQuery 將自動替換 ? 為正確的函式名,以執行回呼函式
我們來個簡單的測驗,使用最原始的HttpServletResponse處理 , .最簡單 , 最通用
匯入jquery , 可以使用在線的CDN , 也可以下載匯入
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://www.cnblogs.com/twq46/archive/2022/08/26/${pageContext.request.contextPath}/statics/js/jquery-3.5.1.min.js"></script>
jQuery官網下載地址
https://jquery.com/download/
在applicationContext中添加靜態資源過濾否則,statics中的js檔案就不會被打包
<!--靜態資源過濾-->
<mvc:default-servlet-handler/>
撰寫index.jsp
<%--
Created by IntelliJ IDEA.
User: twq
Date: 2022/8/26
Time: 08:19
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
<script src="https://www.cnblogs.com/twq46/archive/2022/08/26/${pageContext.request.contextPath}/statics/js/jquery-3.5.1.js"></script>
<script>
function a(){
$.post({
url:"${pageContext.request.contextPath}/a1",
data:{"name" : $("#username").val()},
success:function (data){
alert(data);
}
})
}
</script>
</head>
<body>
<%--失去焦點的時候,發起一個請求(攜帶資訊)到后臺--%>
用戶名:<input type="text" id="username" onblur="a()">
</body>
</html>
AjaxController
@RestController
public class AjaxController {
@RequestMapping("/a1")
public void a1(String name, HttpServletResponse response) throws IOException {
System.out.println();
if("Twq".equals(name)){
response.getWriter().print("true");
}else {
response.getWriter().print("false");
}
}
}
測驗結果

8.3Springmvc實作
物體類user
package com.tang.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String name;
private int age;
private String sex;
}
我們來獲取一個集合物件,展示到前端頁面
@RequestMapping("/a2")
public List<User> a2(){
List<User> users = new ArrayList<User>();
//添加資料
users.add(new User("唐昊",3,"男"));
users.add(new User("唐三",2,"男"));
users.add(new User("小舞",1,"女"));
return users;
}
前端頁面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<input type="button" id="btn" value="https://www.cnblogs.com/twq46/archive/2022/08/26/獲取資料"/>
<table align="center">
<tr>
<td>姓名</td>
<td>年齡</td>
<td>性別</td>
</tr>
<tbody id="content">
</tbody>
</table>
<script src="https://www.cnblogs.com/twq46/archive/2022/08/26/${pageContext.request.contextPath}/statics/js/jquery-3.5.1.js"></script>
<script>
$(function () {
$("#btn").click(function () {//當點擊獲取資料按鈕觸發事件
/*
$.post(url,param[可以省略],success(回呼函式))
*/
$.post("${pageContext.request.contextPath}/a2",function (data) {
console.log(data)//到這已經獲取到了User資料
var html="";
for (var i = 0; i <data.length ; i++) {//獲取前端資料,并拼接
html+= "<tr>" +
"<td>" + data[i].name + "</td>" +
"<td>" + data[i].age + "</td>" +
"<td>" + data[i].sex + "</td>" +
"</tr>"
}
$("#content").html(html);//將User資料存入tbody中
});
})
})
</script>
</body>
</html>
8.4注冊提示效果
我們再測驗一個小Demo,思考一下我們平時注冊時候,輸入框后面的實時提示怎么做到的;如何優化
我們寫一個Controller
@RequestMapping("/a3")
public String ajax3(String name,String pwd){
String msg = "";
//模擬資料庫中存在資料
if (name!=null){
if ("admin".equals(name)){
msg = "OK";
}else {
msg = "用戶名輸入錯誤";
}
}
if (pwd!=null){
if ("123456".equals(pwd)){
msg = "OK";
}else {
msg = "密碼輸入有誤";
}
}
return msg; //由于@RestController注解,將msg轉成json格式回傳
}
前端頁面 login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>ajax</title>
<script src="https://www.cnblogs.com/twq46/archive/2022/08/26/${pageContext.request.contextPath}/statics/js/jquery-3.5.1.js"></script>
<script>
function a1(){
$.post({
url:"${pageContext.request.contextPath}/a3",
data:{'name':$("#name").val()},
success:function (data) {
if (data.toString()=='OK'){
$("#userInfo").css("color","green");
}else {
$("#userInfo").css("color","red");
}
$("#userInfo").html(data);
}
});
}
function a2(){
$.post({
url:"${pageContext.request.contextPath}/a3",
data:{'pwd':$("#pwd").val()},
success:function (data) {
if (data.toString()=='OK'){
$("#pwdInfo").css("color","green");
}else {
$("#pwdInfo").css("color","red");
}
$("#pwdInfo").html(data);
}
});
}
</script>
</head>
<body>
<p>
用戶名:<input type="text" id="name" onblur="a1()"/>
<span id="userInfo"></span>
</p>
<p>
密碼:<input type="text" id="pwd" onblur="a2()"/>
<span id="pwdInfo"></span>
</p>
</body>
</html>
記得處理json亂碼問題
在application.xml中添加如下代碼即可解決亂碼問題
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean >
<constructor-arg value="https://www.cnblogs.com/twq46/archive/2022/08/26/UTF-8"/>
</bean>
<bean >
<property name="objectMapper">
<bean >
<property name="failOnEmptyBeans" value="https://www.cnblogs.com/twq46/archive/2022/08/26/false"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
測驗結果

9.攔截器
9.1概述
SpringMVC的處理器攔截器類似于Servlet開發中的過濾器Filter,用于對處理器進行預處理和后處理,開發者可以自己定義一些攔截器來實作特定的功能,
過濾器與攔截器的區別:攔截器是AOP思想的具體應用,
過濾器
-
servlet規范中的一部分,任何java web工程都可以使用
-
在url-pattern中配置了/*之后,可以對所有要訪問的資源進行攔截
攔截器
-
攔截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用
-
攔截器只會攔截訪問的控制器方法, 如果訪問的是jsp/html/css/image/js是不會進行攔截的
9.2自定義攔截器
那如何實作攔截器呢?
想要自定義攔截器,必須實作 HandlerInterceptor 介面,
-
新建一個Moudule , springmvc-07-Interceptor , 添加web支持
-
配置web.xml 和 springmvc-servlet.xml 檔案
9.2.1撰寫一個攔截器
public class MyInterceptor implements HandlerInterceptor {
//return true:執行下一個攔截器,放行
//return false:不執行下一個攔截器
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("===========處理前===========");
return true;
}
//日志
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("===========處理后===========");
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("===========清理===========");
}
}
9.2.2在springmvc的組態檔中配置攔截器
<!--關于攔截器的配置-->
<mvc:interceptors>
<mvc:interceptor>
<!--/** 包括路徑及其子路徑-->
<!--/admin/* 攔截的是/admin/add等等這種 , /admin/add/user不會被攔截-->
<!--/admin/** 攔截的是/admin/下的所有-->
<mvc:mapping path="/**"/>
<!--bean配置的就是攔截器-->
<bean />
</mvc:interceptor>
</mvc:interceptors>
9.2.3撰寫一個Controller接收請求
@RestController
public class TestController {
@RequestMapping("/a1")
public String test(){
System.out.println("TestController執行了");
return "hello";
}
}
測驗結果

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/502832.html
標籤:其他
上一篇:day27--Java集合10
