在web.xml上的相關配置
SpringMVC前端控制器
<!-- SpringMVC前端控制器 -->
<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:springmvc.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>
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: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
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--這個配置文件與Spring的核心配置文件一樣的 配置SpringMVC的內容 -->
<!-- 開啓MVC註解驅動 -->
<mvc:annotation-driven/>
<!-- 配置註解掃描器 spingmvc的註解掃描器 掃描controller包-->
<context:component-scan base-package="com.hadwinling.controller"/>
<!-- 視圖解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--視圖類型 默認jsp視圖 (省略) -->
<!-- <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>-->
<!-- 視圖前綴 -->
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
@Controller 用於標記在一個類上,使用它標記的類就是一個SpringMVC Controller 對象。分發處理器將會掃描使用了該註解的類的方法,並檢測該方法是否使用了@RequestMapping 註解。@Controller 只是定義了一個控制器類,而使用@RequestMapping 註解的方法纔是真正處理請求的處理器,這個接下來就會講到。
SpringMVC 中重要組件
- 1.1 DispatcherServlet : 前端控制器,接收所有請求(如果配置/不包 含 jsp)
- 1.2 HandlerMapping: 解析請求格式的.判斷希望要執行哪個具體 的方法.
- 1.3 HandlerAdapter: 負責調用具體的方法.
- 1.4 ViewResovler:視圖解析器.解析結果,準備跳轉到具體的物理視 圖
spring web mvc 框架
第一步: 發起請求到前端控制器(DispatcherServlet)
第二步:前端控制器請求 HandlerMapping 查找 handler
可以通過 xml 配置或者通過註解配置
第三步: 處理器映射器向前端控制器返回 Handler
第四步: 前端控制器再去調用處理器適配器執行 Handler
第五步: 處理器適配器真正執行 Handler
第六步: Handler 執行完返回 ModelAndView
第七步: 處理器適配器向前端控制器返回 ModelAndView,ModelAndView 是 SprinveMVC
框架中的一個底層對象,該對象中包括 Model 和 View
第八步: 前端控制器請視圖解析器解析視圖
根據邏輯視圖名解析成真正的視圖,返回個 View
第九步: 視圖解析器向前端控制器返回 View
第十步: 由前端控制器進行視圖渲染
視圖渲染將模型數據填充到 Request 域中.
第十一步: 前端控制器向用戶響應結果.
Springmvc執行流程分析
- 當啓動Tomcat服務器的時候,因爲配置了web.xml中load-on-startup標籤,所以會創建DispatcherServlet對象, 會加載springmvc.xml配置文件
- 開啓了註解掃描,那麼HelloController對象就會被創建
- 從index.jsp發送請求,請求會先到達DispatcherServlet核心控制器,根據配置@RequestMapping註解找到執行的具體方法
- 根據執行方法的返回值,再根據配置的視圖解析器,去指定的目錄下查找指定名稱的JSP文件
- Tomcat服務器渲染頁面,做出響應
RequestMapping註解
- RequestMapping註解的作用是建立請求URL和處理方法之間的對應關係
- RequestMapping註解可以作用在方法和類上
作用在類上:第一級的訪問目錄
作用在方法上:第二級的訪問目錄
路徑可以不編寫 / 表示應用的根目錄開始 - RequestMapping的屬性
- path 指定請求路徑的url
- value value屬性和path屬性是一樣的
- mthod 指定該方法的請求方式
- params 指定限制請求參數的條件
- headers 發送的請求中必須包含的請求頭
請求參數的綁定
請求參數的綁定說明
綁定機制
- 表單提交的數據都是k=v格式的 username=haha&password=123
- SpringMVC的參數綁定過程是把表單提交的請求參數,作爲控制器中方法的參數進行綁定的
- 要求:提交表單的name和參數的名稱是相同的
支持的數據類型
- 基本數據類型和字符串類型
- 實體類型(JavaBean)
- 集合數據類型(List、map集合等)
基本數據類型和字符串類型 - 提交表單的name和參數的名稱是相同的
- 區分大小寫
實體類型(JavaBean) - 提交表單的name和JavaBean中的屬性名稱需要一致
- 如果一個JavaBean類中包含其他的引用類型,那麼表單的name屬性需要編寫成:對象.屬性 例如: address.name
給集合屬性數據封裝
請求參數中文亂碼的解決
在web.xml中配置Spring提供的過濾器類
!--配置springmvc字符集過濾器-->
<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>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
自定義類型轉換器
特殊數據類型 Date 不能直接轉換 默認數據類型轉換器沒有String–>Date
方式1.自定義類型轉換器 springmvc.xml中配置
方式2.在屬性上使用註解@DateTimeFormat(pattern=“yyyy-MM-dd”) *
注意:在springmvc.xml中開啓mvc註解驅動 * mvc:annotation-driven/
方式一:自定義類型轉換器
Date時間的轉換
public class StringToDate implements Converter<String,Date>{
@Override
public Date convert(String source) {
if(source=null) {
throw new RuntimeException("請輸入時間");
}
DateFormat df=new SimpleDateFormat("yyyy-MM-dd");
try {
return df.parse(source);
} catch (ParseException e) {
// TODO Auto-generated catch block
throw new RuntimeException("轉換錯誤");
}
}
}
.2.註冊自定義類型轉換器,在springmvc.xml配置文件中編寫配置
<bean id="conversionUtil" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.gem.springmvcdemo.util.StringToDate"/>
</set>
</property>
</bean>
修改 springmvc.xml註解:
<mvc:annotation-driven conversion-service="conversionUtil"/>
- 方式2.在屬性上使用註解@DateTimeFormat(pattern=“yyyy-MM-dd”) *
注意:在springmvc.xml中開啓mvc註解驅動 * mvc:annotation-driven/
方式二:在實體類中,使用註解
package com.hadwinling.entity;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private String username;
private String password;
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date birth;
}
常用的註解
RequestParam
作用:
把請求中指定名稱的參數給控制器中的形參賦值。
屬性:
value:請求參數中的名稱。
required:請求參數中是否必須提供此參數。默認值:true。表示必須提供,如果不提供將報錯。
@RequestMapping(value="/say02",method=RequestMethod.GET)
public String say02(@RequestParam(name="username",required=true,defaultValue="admin")String name,
@RequestParam(name="id",defaultValue="1") int uid) {
System.out.println(uid+":"+name);
return "main";
}
RequestBody
作用:
用於獲取請求體內容。直接使用得到是 key=value&key=value…結構的數據。
get 請求方式不適用。
屬性:
required:是否必須有請求體。默認值是:true。當取值爲 true 時,get 請求方式會報錯。如果取值
爲 false,get 請求得到是 null
/**
* @RequestBody:以k=v&k=v的形式請求參數
*
* post請求 ,get請求不可以使用
*
*/
@RequestMapping("say05")
public String say05(@RequestBody String body) {
System.out.println(body);
return "main";
}
- 1.在方法上只有@RequestMapping 時,無論方法返回值是什麼認爲需 要跳轉
- 2.在方法上添加@ResponseBody(恆不跳轉)
- 2.1 如果返回值滿足 key-value 形式(對象或 map)
- 2.1.1 把響應頭設置爲 application/json;charset=utf-8
- 2.1.2 把轉換後的內容輸出流的形式響應給客戶端.
- 2.2 如果返回值不滿足 key-value,例如返回值爲 String
- 2.2.1 把相應頭設置爲 text/html
- 2.2.2 把方法返回值以流的形式直接輸出.
- 2.2.3 如果返回值包含中文,出現中文亂碼
- 2.2.3.1 produces 表示響應頭中 Content-Type 取值.
@RequestMapping(value="demo12",produces="text/html; charset=utf-8")
- 2.1 如果返回值滿足 key-value 形式(對象或 map)
PathVaribale
作用:
用於綁定 url 中的佔位符。例如:請求 url 中 /delete/{id},這個{id}就是 url 佔位符。
url 支持佔位符是 spring3.0 之後加入的。是 springmvc 支持 rest 風格 URL 的
一個重要標誌。
屬性:
value:用於指定 url 中佔位符名稱。
required:是否必須提供佔位符。
/**
* restful風格
* 簡約 安全
* /say06/{uid}
* {uid} url中的佔位符
* @PathVariable 蔣將url中的佔位符的值賦值形參
*/
@RequestMapping("/say06/{uid}")
public String say06(@PathVariable(value="uid")int id){
System.out.println(id);
return "main";
}
RequestHeader
作用:
用於獲取請求消息頭。
屬性:
value:提供消息頭名稱
required:是否必須有此消息頭
注:
在實際開發中一般不怎麼用
/**
* 獲取請求頭信息
*/
@RequestMapping("/say07")
public String say07(@RequestHeader(value="Accept") String header) {
System.out.println(header);
return "main";
}
ModelAttribute
作用:
該註解是 SpringMVC4.3 版本以後新加入的。它可以用於修飾方法和參數。
出現在方法上,表示當前方法會在控制器的方法執行之前,先執行。它可以修飾沒有返回值的方法,也可
以修飾有具體返回值的方法。
出現在參數上,獲取指定的數據給參數賦值。
屬性:
value:用於獲取數據的 key
key 可以是 POJO 的屬性名稱,也可以是 map 結構的 key
應用場景:
當表單提交數據不是完整的實體類數據時,保證沒有提交數據的字段使用數據庫對象原來的數據。
例如:
我們在編輯一個用戶時,用戶有一個創建信息字段,該字段的值是不允許被修改的。在提交表單數
據是肯定沒有此字段的內容,一旦更新會把該字段內容置爲 null,此時就可以使用此註解解決問題。
SessionAttribute
作用:
用於多次執行控制器方法間的參數共享。
屬性:
value:用於指定存入的屬性名稱
type:用於指定存入的數據類型。
/**
* @ModelAttribute:
* 作用在方法上 :這個方法會優先執行,一般用來做預處理
* 作用在參數上:獲取指定的數據給參數賦值。
* 應用場景:
* 當在提交表單 時 ,提交的信息不足。先@ModelAttribute修飾的方法中保存一些字段,處理請求時,將保存的字段賦值給參數
*/
@ModelAttribute
public void method(String username,Map<String, User> map) {
System.out.println("@ModelAttribute方法先執行。。。");
User user=new User(username, null);
user.setPassword("123456");
//保存在map中
map.put("currUser", user);
}
@RequestMapping("/say08")
public String say08(@ModelAttribute("currUser") User user) {
System.out.println(user);
return "main";
}
響應數據和結果視圖
程序員自定義視圖解析器
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalR esourceViewResolver"> <property name="prefix" value="/"></property> <property name="suffix" value=".jsp"></property> </bean>
如果希望不執行自定義視圖解析器,在方法返回值前面添加 forward:或 redirect:
返回值分類
- 返回值是void:
如果控制器的方法返回值編寫成void,執行程序報404的異常,默認查找JSP頁面沒有找到。
@RequestMapping("/login")
public void login(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
System.out.println("訪問成功!!");
request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request, response);
}
- 返回值是ModelAndView對象
ModelAndView對象是Spring提供的一個對象,可以用來調整具體的JSP視圖
控制器的代碼塊:
@RequestMapping("/findAll")
public ModelAndView findAll() {
List<User> list=new ArrayList<User>();
list.add(new User("張三", 30));
list.add(new User("張三", 30));
list.add(new User("張三", 30));
list.add(new User("張三", 30));
ModelAndView mv=new ModelAndView();
mv.setViewName("main");
mv.addObject("list",list);
return mv;
}
jsp的代碼塊:
<table>
<c:forEach items="${list }" var="user">
<tr>
<td>${user.uname }</td>
<td>${user.age }</td>
</tr>
</c:forEach>
</table>
SpringMVC框架提供的轉發和重定向
@RequestMapping("test")
public String test() {
//轉發 不經過視圖解析器對象
//return "forward:/WEB-INF/pages/success.jsp";
//重定向不能訪問web-inf中的jsp文件
return "redirect:/index.jsp";
}
ResponseBody響應json數據
DispatcherServlet會攔截到所有的資源,導致一個問題就是靜態資源(img、css、js)也會被攔截到,從而不能被使用。
解決問題:就是需要配置靜態資源不進行攔截,在springmvc.xml配置文件添加如下配置
- mvc:resources標籤配置不過濾
Location屬性表示webapp目錄下的包下的所有文件
Mapping屬性表示以/static開頭的所有請求路徑,如/static/a 或者/static/a/b
代碼示例
<!-- 設置靜態資源不過濾 -->
<mvc:resources location="/css/" mapping="/css/**"/> <!-- 樣式 -->
<mvc:resources location="/images/" mapping="/images/**"/> <!-- 圖片 -->
<mvc:resources location="/js/" mapping="/js/**"/> <!-- javascript -->
發送ajax請求,返回json數據
@RequestMapping("/ajaxtest")
public @ResponseBody User ajaxtest(@RequestBody User user) {
System.out.println(user);
user.setUname("張三");
user.setAge(20);
return user;
}
<!-- json -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>
<script type="text/javascript" src="/springmvcdemo/js/jquery-3.2.1.min.js"></script>
<script type="text/javascript">
$(function () {
$("#btn").click(function(){
//發送ajax請求
$.ajax({
url:"ajaxtest", //服務器地址
contentType:"application/json;charset=UTF-8",//
data:'{"uname":"rose","age":30}',//參數 json
dataType:"json",//預期服務返回數據類型
type:"post",//post
success:function(data){//訪問成功 :執行函數 data:服務器返回數據
console.log(data);
console.log(data.uname);
console.log(data.age);
}
})
});
})
</script>
跳轉方式
- 默認跳轉方式請求轉發.
- 設置返回值字符串內容
2.1 添加 redirect:資源路徑 重定向
2.2 添加 forward:資源路徑 或省略 forward: 轉發