資料綁定
springmvc作為web層技術,要接受頁面傳遞過來的參數值,以下幾種方式都是擷取參數值
綁定servlet内置對象
@RequestMapping("show1")
@ResponseStatus(HttpStatus.OK) //傳回void 沒有頁面傳回,給出響應狀态為200
public void test1(HttpServletRequest request , HttpServletResponse response , HttpSession session){
//有了這些對象,之前怎麼用,這裡怎麼用
System.out.println(request);
System.out.println(response);
System.out.println(session);
}
@PathVariable
@RequestMapping(“show2/{id}/{name}”)
@PathVariable(“id”) 指定擷取請求路徑中的參數值
@RequestMapping("show2/{id}/{name}")//@PathVariable("xx")參數可以省略,建議指定擷取
public String test2(@PathVariable int id ,@PathVariable String name){
System.out.println("id:"+id);
System.out.println("name:"+name);
//傳回String
return "hello";//可以直接跳到視圖解析器下找hello.jsp
}
@RequestParam
屬性名 | 屬性值 |
value | 參數名 |
required | true(預設) false |
defaultValue | 預設值,如果不給參數值,就走預設值 |
- 普通serlvet擷取參數值
//通過綁定servlet對象,擷取請求參數
@RequestMapping("show3")
@ResponseStatus(HttpStatus.OK)
public void test3(HttpServletRequest request){
System.out.println(request.getParameter("id"));
System.out.println(request.getParameter("name"));
}
- @RequestParam擷取參數值
/**
* 擷取請求攜帶的參數 show4.do?id=33&name=jack
* 1、@RequestParam 擷取請求指定參數
* 2、value 參資料
* 3、required 參數是否必須,預設true
* true: 必須
* false:可以不寫
* 4、 defaultValue 如果沒有傳值,預設給出一個值 defaultValue = "jack"
*/
@RequestMapping("show4")
@ResponseStatus(HttpStatus.OK)
public void test4(
@RequestParam(value = "id",required = true) int id,
@RequestParam(value = "name",required = false, defaultValue = "jack") String name ){
System.out.println("id:"+id);
System.out.println("name:"+name);
}
@CookieValue
/**
* 通過背景跳轉到cookie視圖
* @return
*/
@RequestMapping("toCookie")
public ModelAndView toCookie(){
ModelAndView mv = new ModelAndView();
mv.setViewName("cookie");
return mv;
}
/**
* 擷取cookie的值
* @param name
*/
@RequestMapping("show5")
@ResponseStatus(HttpStatus.OK)
public void test5(@CookieValue(value = "name",required = false) String name){
System.out.println("cookie的值為:"+name);
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="/hello/show5.do">測試cookie</a>
<script>
document.cookie = "name=jack";
</script>
</body>
</html>
POJO對象綁定參數
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
</dependency>
@Data
public class User {
private Integer id;
private String name;
private Integer age;
}
/**
* 接收綁定的pojo對象
* @param user
* @return
*/
@RequestMapping("show6")
public ModelAndView test6(User user){
System.out.println(user);
ModelAndView mv = new ModelAndView();
mv.addObject("msg",user);
mv.setViewName("hello");
return mv;
}
基本資料類型綁定
/**
* 通過背景跳轉到user視圖
* @return
*/
@RequestMapping("toUser")
public ModelAndView toUser(){
ModelAndView mv = new ModelAndView();
mv.setViewName("user");
return mv;
}
<form action="http://localhost:8080/springmvc-test02/hello2/show18.do" method="post">
<div>姓名:</div>
<div><input name="name" value="張三"/></div>
<div class="clear"></div>
<div>年齡:</div>
<div><input name="age" value="20"/></div>
<div class="clear"></div>
<div>收入:</div>
<div><input name="income" value="100000"/></div>
<div class="clear"></div>
<div>結婚:</div>
<div>
<input type="radio" name="isMarried" value="true" checked="checked"/>是
<input type="radio" name="isMarried" value="false"/>否</div>
<div class="clear"></div>
<div>興趣:</div>
<div>
<input type="checkbox" name="interests" value="聽歌" checked="checked"/>聽歌
<input type="checkbox" name="interests" value="書法" checked="checked"/>書法
<input type="checkbox" name="interests" value="看電影" checked="checked"/>看電影
</div>
<div class="clear"></div>
<div><input type="submit" value="送出表單"/></div>
</form>
/**
* 接收基本資料類型
*/
@PostMapping("show8")
@ResponseStatus(HttpStatus.OK)
public void test7(
@RequestParam("name") String name,
@RequestParam("age") Integer age,
@RequestParam("income") Double income,
@RequestParam("isMarried") Boolean isMarried,
@RequestParam("interests") String[] interests){
System.out.println("name: "+name);
System.out.println("age: "+age);
System.out.println("income: "+income);
System.out.println("isMarried: "+isMarried);
for(String str : interests){
System.out.println("interests: "+str);
}
}
解決亂碼問題
springmvc提供了編碼過濾器
隻解post中文亂碼問題,注意解析源碼
配置位置 web.xml
<!--編碼過濾器-->
<filter>
<!--注意這裡是filter,不要配置成servlet-->
<filter-name>encodingFilter</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>encodingFilter</filter-name><!--過濾器名稱-->
<url-pattern>/*</url-pattern><!--URL映射,給所有頁面處理亂碼-->
</filter-mapping>
通用頁面跳轉
我們發現上面我們寫了很多次頁面跳轉的方法,其實我們可以抽取統一
@RequestMapping("to")
@Controller
public class Topage {
/**
* 通用頁面跳轉---視圖解析器
http://localhost:8080/rest/to/hello
*/
@RequestMapping("{page}")
public String toPage1(@PathVariable("page") String page){
return page;
}
/**
* 通用頁面跳轉---webapp下視圖--寫着玩
*/
@RequestMapping("wp/{page}")
public String toPage2(@PathVariable("page") String page){
return "forward:/"+page+".html";
}
}
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
數組類型
<form action="/hello/show9.do" method="post">
<input type="checkbox" name="addr" value="鄭州"> 鄭州 <br>
<input type="checkbox" name="addr" value="上海"> 上海 <br>
<input type="checkbox" name="addr" value="杭州"> 杭州 <br>
<input type="checkbox" name="addr" value="北京"> 北京 <br>
<input type="checkbox" name="addr" value="曹縣"> 曹縣 <br>
<input type="submit" value="數組類型">
</form>
/**
* 接收數組
* @param addr
*/
@PostMapping("show9")
@ResponseStatus(HttpStatus.OK)
public void show9(String[] addr){
for (String str : addr){
System.out.println(str);
}
}
綁定複雜類型
如果送出的是一個集合的資料,SpringMVC的方法形參是無法接收的,我們必須通過實體類進行包裝才行
@Data
public class UserVO {
private String name;
private Integer age;
private User user;
private List<User> list;
private Map<String,User> map;
private String[] addr;
}
<form action="/hello/show10.do" method="post">
姓名: <input type="text" name="name">
年齡: <input type="text" name="age"> <br/>
user屬性中的姓名:<input type="text" name="user.name"><br/>
user屬性中的年齡:<input type="text" name="user.age"> <br/>
list中第一個user對象的年齡:<input type="text" name="list[0].age"> <br/>
list中第一個user對象的姓名:<input type="text" name="list[0].name"> <br/>
list中第二個user對象的年齡: <input type="text" name="list[1].age"> <br/>
list中第二個user對象的姓名: <input type="text" name="list[1].name"> <br/>
map中第一個鍵值對中值user對象的年齡: <input type="text" name="map['one'].age"> <br/>
map中第一個鍵值對中值user對象的姓名: <input type="text" name="map['one'].name"> <br/>
map中第二個鍵值對中值user對象的年齡: <input type="text" name="map['two'].age"> <br/>
map中第二個鍵值對中值user對象的姓名: <input type="text" name="map['two'].name"><br/>
請選擇喜歡的城市:
<input type="checkbox" name="addr" value="鄭州"> 鄭州 <br>
<input type="checkbox" name="addr" value="上海"> 上海 <br>
<input type="checkbox" name="addr" value="杭州"> 杭州 <br>
<input type="checkbox" name="addr" value="北京"> 北京 <br>
<input type="checkbox" name="addr" value="曹縣"> 曹縣 <br>
<input type="submit" value="複雜類型">
</form>
/**
* 接受複雜類型
* @param userVO
*/
@PostMapping("show10")
@ResponseStatus(HttpStatus.OK)
public void show10(UserVO userVO){
System.out.println(userVO);
}
日期類型
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birth;
jsp和jstl視圖解析器
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
/**
* 把資料轉發到jsp頁面中進行顯示
*/
@GetMapping("show20")
public ModelAndView test20(){
ModelAndView mv = new ModelAndView();
Person person = new Person();
person.setId(11);
person.setName("戈爾丹");
person.setAge(22);
Person person2 = new Person();
person2.setId(11);
person2.setName("趙日天");
person2.setAge(33);
Person person3 = new Person();
person3.setId(11);
person3.setName("葉良晨");
person3.setAge(44);
List<Person> list = new ArrayList<>();
list.add(person);
list.add(person2);
list.add(person3);
mv.addObject("list",list);
mv.setViewName("list");
return mv;
}
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<table border="1px" cellpadding="8px" cellspacing="0px" width="80%">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Age</th>
</tr>
</thead>
<tbody>
<c:forEach items="${list}" var="person">
<tr>
<td>${person.id}</td>
<td>${person.name}</td>
<td>${person.age}</td>
</tr>
</c:forEach>
</tbody>
</table>
</body>
</html>
SpringMVC異步互動
在之前我們講的請求響應都是同步的,但是在實際開發中我們都是使用異步請求,是以下面我們使用ajax發送異步請求!
在異步請求中資料傳輸的格式我們都是使用josn來進行傳輸,速度快,小巧,使用友善!!
在響應的同時,我們也是響應json字元串,在前端解析json字元串即可!
回顧ajax
- 發送ajax請求:$.ajax() / $.get() / $.post()
- 響應json資料:new ObjectMapper().writeValueAsString()
我們學習完SpringMVC之後,就不用像之前那麼麻煩了,還要建立ObjectMapper對象來轉換成josn資料進行響應。
SpringMVC已經幫我們做這些事情了。SpringMVC提供了兩個注解@RequestBody和@ResponseBody實作josn資料的轉換
@ResponseBody
用于将controller方法傳回的對象通過轉換器轉換為指定的格式(通常為json)之後,寫入到response對象的響應體中。
添加依賴
<!-- Jackson Json處理工具包 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.5</version>
</dependency>
引入jq檔案
<script src="js/jquery-3.4.1.js"></script>
編寫ajax代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/jquery-3.4.1.js"></script>
</head>
<body>
<table border="1">
<tr>
<td>name</td>
<td>age</td>
</tr>
</table>
<script>
$.ajax({
url: 'UserController/ajaxResponse.do',
type: 'POST',
dataType:"json",
success: function (data) {
var str = '';
$(data).each(function (i) {
str += `
<tr>
<td>${data.name}</td>
<td>${data.age}</td>
<td></td>
</tr>
`;
});
$("table").append(str);
}
});
</script>
</body>
</html>
編寫Controller
@Controller
@RequestMapping("UserController")
public class UserController {
/**
* 響應json串
* @return
*/
@PostMapping("ajaxResponse")
@ResponseBody //傳回的對象以json的形式響應 {"name":"jack","age":99}
public User getUser(){
User user = new User();
user.setName("jack");
user.setAge(99);
return user;
}
}
@RestController用法
@RequestMapping("UserController")
@RestController //@RestController == @Controller 和 @ResponseBody
public class UserController {
/**
* 響應json串
* @return
*/
@PostMapping("ajaxResponse")
public User getUser(){
User user = new User();
user.setName("jack");
user.setAge(99);
return user;
}
}
@RequestBody
用于接收前端請求體中的json資料,使用@RequestBody注解就可以自動的封裝指定的對象中
引入jq檔案
<script src="js/jquery-3.4.1.js"></script>
編寫ajax代碼
- 使用: $.ajax() 函數
- 規則:
- ajax送出的資料必須是一個标準的json字元串
- ajax送出的方式必須為post,資料必須在請求體中
- ajax送出的MIME類型必須為:application/json;charset=utf-8
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/jquery-3.4.1.js"></script>
</head>
<body>
<script>$(function () {
$.ajax({
url: '/UserController/ajaxRequest.do',
type: 'POST',
data: '{"name":"jack","age":99}',
contentType:'application/json;charset=utf-8',
success: function (data) {
}
});
});</script>
</body>
</html>
編寫Controller
/**
* 接受json串
* @param user
*/
@PostMapping("ajaxRequest")
public void test(@RequestBody User user){
//User(name=jack, age=99)
System.out.println(user);
}
小結
@RequestBody
:将請求體中的json字元串,轉為指定類型的java對象
@ResponseBody
:将java對象轉為json字元串,再設定到響應體中,傳回到浏覽器(用戶端)
處理靜态資源
測試前端代碼
當點選按鈕時,發現沒有任何反應,這是因為SpringMVC在預設情況下,所有的靜态資源都會被攔截(js,css。html,圖檔、視訊、音頻),在web.xml檔案中,我們配置的攔截路徑是
/
這種形式除了jsp都會被攔截
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!--攔截webapp下所有靜态資源,除了jsp-->
<url-pattern>/</url-pattern>
</servlet-mapping>
把攔截路徑設定為 / 時,會發現連html靜态頁面都無法通路
三種方式解決
- web.xml配置方式一
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!--攔截webapp下所有資源,除了jsp-->
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 處理靜态資源攔截-->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
- springmvc-servlet.xml 配置檔案
<!--
靜态資源手動映射
mapping="/img/**" 浏覽器發送請求
location="/img/" 靜态資源的路徑
-->
<mvc:resources mapping="/html/**" location="/html/"/>
<mvc:resources mapping="/img/**" location="/img/" />
<mvc:resources mapping="/js/**" location="/js/" />
<mvc:resources mapping="/css/**" location="/css/"/>
- springmvc-servlet.xml 配置檔案【簡化方式】
<!-- 處理靜态資源攔截-->
<!--配置tomcat預設的靜态資源處理-->
<mvc:default-servlet-handler/>