Spring MVC學習筆記(一)
注:學習筆記,比較雜亂
Spring MVC業務處理流程
DAO層、Service層和Controller層
1、DAO層
資料訪問層(data access object),具體到對某張表的增刪改查,某一DAO一定對應著資料庫中的某張表。在DAO層應該只做增刪改查操作。
2、Service層
服務層,對一個或多個DAO的再次封裝,封裝成一個服務。需要進行事務控制。
3、Controller層
負責請求轉發,接受頁面發過來的引數,傳遞給Service處理,接到返回結果在傳遞給頁面。
總結:DAO面向表,Service面向業務。後端開發時先設計出資料庫中的表,再針對每一張表設計出DAO層,然後根據具體的業務邏輯進一步把DAO封裝成Service層,對外提供一個服務。
SpringMVC開發環境搭建——IDEA版(Maven)
1、使用Maven建立專案
左側選擇“Maven”,在右側勾選“Create from archetype(意思是從原型建立)”,在左側原型列表中找到“maven-archetype-webapp ”並選中,點選Next。不要忘記選擇合適的SDK。
輸入Name(專案名)和GroupId(一般是公司名),點選Next。
設定Maven屬性。在Properties裡新增一組鍵值對“archetypeCatalog-internal”,解決maven專案建立過慢的問題。點選finish。
2、補全目錄結構。Maven專案的目錄結構是固定的,但是創建出來的專案目錄結構是不全的,所以需要手動補全。在src-main目錄上右鍵,new-Directory,在彈出的視窗選擇Java,新增Java目錄;再用同樣的方式新增resources目錄(IDEA2020.1.2版本,不能這麼新增的可以手動輸入java和resources新增,然後右鍵java目錄“Make Directoryas --Source Root”;右鍵resources目錄“MakeDirectoryas --Resources Root)。
=======>>>
3、修改專案pom.xml配置檔案,引入SpringMVC依賴。將<maven.compiler.source>和<maven.compiler.target>兩個標籤中的內容改為使用的JDK版本。並新增<Spring.Version>標籤。如下所示。
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>14</maven.compiler.source> <maven.compiler.target>14</maven.compiler.target> <spring.version>5.0.2.RELEASE</spring.version> </properties>
在專案pom.xml檔案的<dependencies>標籤內填入以下程式碼:
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-web --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency>
4、配置前端控制器(即servlet)。在src—main—webapp—WEB-INF—web.xml檔案內的<web-app>標籤內新增以下程式碼。其中,<servlet-class>標籤內的org.springframework.web.servlet.DispatcherServlet是固定的,<url-pattern>內的/表示攔截所有請求。兩個<xxx-name>標籤內可以隨便填寫,一般填寫類的小寫名稱。
<servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
5、配置SpringMVC的配置檔案。在第2步建立的resources資料夾上New-XML Configuration File-Spring Config,命名為SpringMVC(名字隨便取,叫SpringMVC便於識別)
6、部署伺服器。點選右上角“Add Configuration”,點選彈出的視窗左上角的加號,選擇tomcat,然後選擇Deployment選項卡,點選右側的加號,選擇Artifact,在選擇“專案名:war”,刪掉“Application Context”中的內容(也可以不刪,如果不刪的話專案中的連結都要在前面加上Application Context裡的內容,我這裡沒刪,應該加上/SpringMVCLearn_war),點選OK,再點選OK。
編寫入門程式
1、刪掉src—main—webapp目錄下的index.jsp,新建index.html檔案
2、先在index.html檔案的body標籤內新增一個<h2>和<a>標籤,<a>標籤的href屬性先留空。程式碼如下:
<body> <h2>入門程式</h2> <a href="">入門程式</a> </body>
3、建立後臺類。在src—main—java目錄下新建controller資料夾,建立一個 名為HelloController的類。
====>>>
4、在HelloController類上添加註解@Controller,將其標記為Controller。新增一個名問sayHello的方法,並添加註解@RequestMapping(path = "/hello")
package controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; //控制器類 @Controllerpublic class HelloController { @RequestMapping(path = "/hello") //url應為“/SpringMVCLearn_war/hello”,如果Application Context內的內容刪掉了,則url為“/hello” public String sayHello() { System.out.println("Hello SpringMVC"); return "success"; } }
5、在webapp目錄下新建一個名為HTML的資料夾,存放.html檔案。在新建的HTML資料夾內新建一個名為success.html的檔案,隨便寫點東西。
6、修改SpringMVC.xml配置檔案,開啟註解掃描,並指定檢視解析器的尋找路徑。在SpringMVC.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 http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!--開啟註解掃描--> <context:component-scan base-package="controller"></context:component-scan> <!-- 預設的註解對映 --> <mvc:annotation-driven /> <!-- 解除servlet對靜態資原始檔訪問的限制,使得靜態資源先經過,必須設定,不然啟動時無法訪問主頁--> <mvc:default-servlet-handler /> <!--檢視解析器物件:class是固定的--> <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!--尋找檢視的路徑 此處要與上一步建立的資料夾路徑嚴格對應起來!!!!!!!--> <property name="prefix" value="/HTML/" /> <!--尋找檔案的字尾名--> <property name="suffix" value=".html" /> </bean> </beans>
7、前端控制器(servlet)載入SpringMVC配置檔案。在web.xml檔案的<servlet>標籤內新增以下程式碼:
<init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:SpringMVC.xml</param-value> </init-param> <load-on-startup>1</load-on-startup>
最終web.xml檔案的內容為:
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:SpringMVC.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
8、在index.html的<a>標籤的href屬性內寫入“/SpringMVCLearn_war/hello”。
9、點選右上角啟動按鈕啟動。
註解
RequestMapping註解
作用:建立請求url和處理請求方法之間的對應關係
常用屬性:
value與path:作用相同,指定對映路徑。如果只用了RequestMapping註解的一個屬性,可以省略引數名只寫路徑名
method:指定請求方式。RequestMethod列舉類
params:用於指定限制請求引數的條件,支援簡單的表示式。要求請求引數的key和value必須和配置的一模一樣
例如:
params={“accountName”},表示請求中必須有accountName
params={“money!100”},表示請求引數中money不能是100
headers:用於指定限制請求訊息頭的條件
注意:以上4個屬性同時出現2個或以上時,它們之間是與的關係,即必須同時成立。
RequestParam註解
作用:把請求中指定名稱的引數給控制器中的形參賦值
常用屬性:
value:請求引數中的名稱
required:請求引數中是否必須提供此引數。預設值:true,表示必須提供,如果不提供將報錯。
例如:
<a href="/hello?name=hahaha"></a>
@RequestMapping(path = "/hello") public String sayHello(@RequestParam("name") String userName) { System.out.println(userName); return "success"; }
RequestBody註解
作用:用於獲取請求體的內容。直接使用得到的是key=value&key=value……結構的資料。不適用於get請求,因為get請求沒有請求體。
屬性:
required:是否必須有請求體。預設值是:true。當取值為true時,get請求方式會報錯。如果取值為false,get請求得到null。
PathVariable註解
作用:用於繫結url中的佔位符。例如:請求url中/delete/{id},這個{id}就是url佔位符。url支援佔位符是Spring3.0之後加入的,是SpringMVC支援rest風格URL的重要標誌。
屬性:
name和value:用於指定url中佔位符的名稱。
required:指定是否必須提供佔位符。
例如:
<a href="/PathVariable/10">PathVariable註解</a>
@RequestMapping("/PathVariable/{id}") public String testPathVariable(@PathVariable(name = "id") String id) { System.out.println(id); return "success"; }
上述程式碼後臺會輸出"10"
RequestHeader註解
作用:用於獲取請求訊息頭。(一般用不到此註解)
屬性:
value:提供訊息頭名稱。
required:是否必須有此訊息頭。
CookieValue註解
作用:用於把指定cookie名稱的值傳入控制器方法引數。
屬性:
value:指定cookie的名稱。
required:指定是否必須有此cookie。
ModelAttribute註解(此註解可能已過期,帶查閱資料確定)
作用:該註解是SpringMVC4.3版本引入的,它可以用於修飾方法和引數。該註解修飾方法時,表示當前方法會在控制器的方法執行之前先執行。它可以修飾沒有返回值的方法,也可以修飾有返回值的方法。出現在引數上時,獲取指定的資料給引數賦值。
屬性:
value:用於獲取資料的key。key可以是POJO的屬性名稱,也可以是map結構的key。
應用場景:
當表單提交資料不是完整的實體類資料時,保證沒有提交資料的欄位使用資料庫物件原來的資料。
例如:
我們在編輯一個使用者時,使用者有一個建立資訊欄位,該欄位的值是不允許被修改的。在提交表單時肯定沒有此欄位的內容,一旦更新會把該欄位內容置為null,此時就可以使用此註解解決問題。
SessionAttributes註解(在html中不太好用,待解決或尋找其他方式,例如Ajax)
作用:用於多次執行控制器方法間的引數共享
屬性:
value:用於指定存入的屬性名稱。
type:用於指定存入的資料型別。
請求引數的繫結
1、後臺方法會自動接收傳遞的url中與方法引數名相同的引數,例如:
@RequestMapping("paramsTest") public String ParamsMethod(String user,String pwd){ /**/ System.out.println(user); System.out.println(pwd); return null; }
如果傳遞過來的url為“***/paramsTest?user=song&pwd=123456,則後臺會列印song(即user)和123456(即pwd)
2、使用JavaBean繫結
java類:
package domain; import java.io.Serializable; public class Account implements Serializable { private String userName; private String password; private double money; private User user; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } @Override public String toString() { return "Account{" + "userName='" + userName + '\'' + ", password='" + password + '\'' + ", money=" + money + ", user=" + user + '}'; } }
/** * @author :宋慶國 * @date :Created in 2020/7/5 21:37 * @modified By: */ package domain; import java.io.Serializable; public class User implements Serializable { private String uname; private Integer age; public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "User{" + "uname='" + uname + '\'' + ", age=" + age + '}'; } }
頁面表單:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h2>JavaBean引數繫結</h2> <form action="/saveAccount" method="post"> 姓名:<input type="text" name="userName"/><br> <!--name的值嚴格對應Account類的屬性名--> 密碼:<input type="text" name="password"/><br> 金額:<input type="text" name="money"/><br> 使用者姓名:<input type="text" name="user.uname"/><br> <!--Account類中還有個User引用型別的例項,要想給這個User類傳遞引數,應使用此類"例項名.屬性名"--> 使用者年齡:<input type="text" name="user.age"/><br> <input type="submit" value="提交"/> </form> </body> </html>
Controller類:
package controller; import domain.Account; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class ParamsBind { /* * 請求引數繫結,把資料封裝到JavaB的類中 * * */ @RequestMapping("/saveAccount") public String saveAccount(Account account) { System.out.println(account.toString()); return "success"; } }
配置解決中文亂碼的過濾器
在web.xml中新增以下程式碼:
<!--配置解決中文亂碼的過濾器--> <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> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>