SpringMVC 请求接收
# Spring MVC请求接收
Spring MVC Controller 接收请求参数的方式有很多种,有的适合 get 请求方式,有的适合 post 请求方式,有的两者都适合。主要有以下几种方式:
- 通过 处理方法的形参接收请求参数
- 通过 HttpServletRequest 接收请求参数
- 通过 @PathVariable 接收 URL 中的请求参数
- 通过 @RequestParam 接收请求参数
- 通过 @RequestBody 接收请求参数
- 获取 不同类型的对象 (日期、数组、集合、...)
项目结构:(主要测试文件其余省略)
.
|
├── com
│ ├── controller
| | └── UserController
│ ├── ov
| | └── QueryVO
| User
|
└── webapp
└── jsp
├── parameterTest.jsp
└── ok.jsp
说明:
UserController类 添加了 @RequestMapping 注解路径
@Controller @RequestMapping("/user") public class UserController {···}
User类 有 (int)id、(String)name、(int)age、(String)location 属性,分别有各自的 get和set方法 和 toString方法
# 逐个参数接收
逐个传递参数
parameterTest.jsp
<form action="/user/parameterMethod" method="post">
<span>id:</span> <input type="text" name="id" > <br>
<span>name:</span> <input type="text" name="name" > <br>
<span>age:</span> <input type="text" name="age" > <br>
<span>location:</span> <input type="text" name="location" > <br>
<button type="submit">提交</button>
</form>
UserController类
/**
* 通过 方法逐个参数传递
* 前提:前端属性名 与 实体类属性名 保持一致,否则获取不到
*/
@RequestMapping("parameterMethod")
public ModelAndView parameterMethod(int id, String name, int age, String location){
System.out.println("方法逐个参数传递===============");
System.out.println("id : " + id);
System.out.println("name : " + name);
System.out.println("age : " + age);
System.out.println("location : " + location);
ModelAndView mv = new ModelAndView();
mv.setViewName("jsp/ok");
return mv;
}
对象传递参数
parameterTest.jsp
<form action="/user/parameterMethod2" method="post">
<span>id:</span> <input type="text" name="id" > <br>
<span>name:</span> <input type="text" name="name" > <br>
<span>age:</span> <input type="text" name="age" > <br>
<span>location:</span> <input type="text" name="location" > <br>
<button type="submit">提交</button>
</form>
UserController类
/**
* 通过 方法对象参数传递
* 条件:传参要有对应的实体对象
* 前提:前端属性名 与 实体类属性名 保持一致,否则获取不到
*/
@RequestMapping("parameterMethod2")
public ModelAndView parameterMethod2(User user){
System.out.println("方法对象参数传递===============");
System.out.println(user);
ModelAndView mv = new ModelAndView();
mv.setViewName("jsp/ok");
return mv;
}
# 原生Servlet接收
parameterTest.jsp
<form action="/user/parameterServletRequest" method="post">
<span>id:</span> <input type="text" name="id"> <br>
<span>name:</span> <input type="text" name="name"> <br>
<span>age:</span> <input type="text" name="age"> <br>
<span>location:</span> <input type="text" name="location"> <br>
<button type="submit">提交</button>
</form>
UserController类
/**
* 通过 HttpServletRequest 进行参数传递
*/
@RequestMapping("parameterServletRequest")
public ModelAndView parameterServletRequest(HttpServletRequest rs){
System.out.println("HttpServletRequest对象传递===============");
System.out.println("id : " + rs.getParameter("id"));
System.out.println("name : " + rs.getParameter("name"));
System.out.println("age : " + rs.getParameter("age"));
System.out.println("location : " + rs.getParameter("location"));
ModelAndView mv = new ModelAndView();
mv.setViewName("jsp/ok");
return mv;
}
# @PathVariable 注解接收
通过 @PathVariable
注解 进行匹配参数逐个接收
它的独特之处在于它能够通过 URL的RESTful风格 传递参数,以下是应用实例
UserController类
/**
* 通过 @PathVariable 接收 URL中的请求参数
* 地址应用:http://localhost:8088/user/parameterPathVariable/1003/zhu/23/jsp
* 属性:
* String value:对应前端属性名
* boolean required(默认true):参数是否必须,如果 获取前端数有丝毫问题就会报400异常(获取并非指定的参数值为null)
*/
@RequestMapping("parameterPathVariable/{id}/{name}/{age}/{location}")
public ModelAndView paraeterPathVariable(
@PathVariable(value = "id" , required = false) Integer id,
@PathVariable(value = "name" , required = false) String name,
@PathVariable(value = "age" , required = false) Integer age,
@PathVariable(value = "location" , required = false) String location){
System.out.println("通过 @PathVariable 接收 URL中的请求参数===============");
System.out.println("id : " + id);
System.out.println("name : " + name);
System.out.println("age : " + age);
System.out.println("location : " + location);
ModelAndView mv = new ModelAndView();
mv.setViewName("jsp/ok");
return mv;
}
# @RequestParam 接收
通过 @RequestParam
注解 进行匹配参数逐个接收,和上面有些类似,但接收形式不一样!
接收形式:
不同请求头 form默认提交的请求头是 ==content-type: form-data、x-www-form-urlencoded== , 因此填充填充参数可以直接用
@RequestParam
注解 进行接收获取url参数填充
在已经固定请求头的类型且又想获取数据是 可以直接在url拼接获取如:
http://localhost:8080/login?code=123
(传递 code)
parameterTest.jsp
<form action="/user/parameterRequestParam" method="post">
<span>id:</span> <input type="text" name="userId" > <br>
<span>name:</span> <input type="text" name="userName" > <br>
<span>age:</span> <input type="text" name="userAge" > <br>
<span>location:</span> <input type="text" name="userLocation" > <br>
<button type="submit">提交</button>
</form>
UserController类
/**
* 通过 @RequestParam 进行参数传递
* 作用:矫正 前端属性名 与 方法参数名 不一致
* 属性:
* String value:对应前端属性名
* boolean required(默认true):参数是否必须,如果 获取前端数有丝毫问题就会报400异常(获取并非指定的参数值为null)
*/
@RequestMapping("parameterRequestParam")
public ModelAndView parameterRequestParam(
@RequestParam("userId") int id,
@RequestParam("userName") String name,
@RequestParam("userAge") int age,
//制造参数名不匹配 (获取参数结果为null,并非400页面)
@RequestParam(value = "userLocationABC", required = false) String location){
System.out.println("@RequestParam 进行参数传递===============");
System.out.println("id : " + id);
System.out.println("name : " + name);
System.out.println("age : " + age);
System.out.println("location : " + location);
ModelAndView mv = new ModelAndView();
mv.setViewName("jsp/ok");
return mv;
}
# @RequestBody 接收
@RequestBody
注解 来处理Content-Type为 application/json
, application/xml
数据,他们传递形式是已JSON形式进行的 , 后端接收的可直接封装成实体对象(前提key名称必须与 实体类的属性名一致!!!)
axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
axios.post("/user/login", {
userName: this.userName,
userPassword: this.userPassword,
code: this.code
}).then(res => {...});
@RequestMapping("/login")
public void login(@RequestBody User user) {
...
}
请求和响应必须都使用 JSON形式进行传递数据
# 获取 不同类型的对象
# 日期
user类
public class User {
private int id;
private String name;
private int age;
private String location;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date createTime;
·····
}
parameterTest.jsp
<form action="/user/parameterDate" method="post">
<span>id:</span> <input type="text" name="id" > <br>
<span>name:</span> <input type="text" name="name" > <br>
<span>age:</span> <input type="text" name="age" > <br>
<span>location:</span> <input type="text" name="location" > <br>
<span>createTime:</span> <input type="text" name="createTime" > <br>
<button type="submit">提交</button>
</form>
UserController类
/**
* 日期
* 通过 方法对象参数传递(包含日期类型)
* 条件:实体对象的日期类型必须包含 @DateTimeFormat(pattern = "yyyy-MM-dd") 注解
* 前提:传输格式符合:("yyyy-MM-dd")格式且是日期值范围内,否则报400
*/
@RequestMapping("parameterDate")
public ModelAndView parameterDate(User user){
System.out.println("传递日期类型===============");
System.out.println(user);
ModelAndView mv = new ModelAndView();
mv.setViewName("jsp/ok");
return mv;
}
# 数组
parameterTest.jsp
<form action="/user/parameterArrays" method="post">
<span>name1:</span> <input type="text" name="names" > <br>
<span>name2:</span> <input type="text" name="names" > <br>
<span>name3:</span> <input type="text" name="names" > <br>
<button type="submit">提交</button>
</form>
UserController类
/*
* 数组
* 传递数组对象
* 获取方式:
* 1.参数直接获取(变量名 与 前端的属性名一致)
* 2. HttpServletRequest原生对象获取
* */
@RequestMapping("parameterArrays")
public ModelAndView parameterArrays(String[] names , HttpServletRequest rs){
System.out.println("传递数组对象===============");
System.out.println("方式1:");
//方式1:(参数数组形式获取)
for (String n : names) {
System.out.println("\t"+n);
}
System.out.println("==========");
System.out.println("方式2:");
//方式2:(原生对象获取)
String[] names2 = rs.getParameterValues("names");
for (String n : names2) {
System.out.println("\t"+n);
}
ModelAndView mv = new ModelAndView();
mv.setViewName("jsp/ok");
return mv;
}
# 集合
parameterTest.jsp
<form action="/user/parameterSet" method="post">
<span>name1:</span> <input type="text" name="names" > <br>
<span>name2:</span> <input type="text" name="names" > <br>
<span>name3:</span> <input type="text" name="names" > <br>
<button type="submit">提交</button>
</form>
UserController类
/*
* 集合
* 前提:需要 @RequestParam() 指定value 前端属性名 (属性类型不匹配较为特殊需自行配置)
* */
@RequestMapping("parameterSet")
public ModelAndView parameterSet(@RequestParam("names") List<String> nameList){
System.out.println("传递集合对象===============");
for (String name : nameList) {
System.out.println(name);
}
ModelAndView mv = new ModelAndView();
mv.setViewName("jsp/ok");
return mv;
}
# 对象集合
QueryVO类
package com.vo;
import com.User;
import java.util.List;
public class QueryVO {
private List<User> userList;
public List<User> getUserList() {
return userList;
}
public void setUserList(List<User> userList) {
this.userList = userList;
}
}
parameterTest.jsp
<form action="/user/parameterObjectSet" method="post">
<span>id1:</span> <input type="text" name="userList[0].id" > <br>
<span>id2:</span> <input type="text" name="userList[1].id" > <br>
<span>id3:</span> <input type="text" name="userList[2].id" > <br>
<span>name1:</span> <input type="text" name="userList[0].name" > <br>
<span>name2:</span> <input type="text" name="userList[1].name" > <br>
<span>name3:</span> <input type="text" name="userList[2].name" > <br>
<span>age1:</span> <input type="text" name="userList[0].age" > <br>
<span>age2:</span> <input type="text" name="userList[1].age" > <br>
<span>age3:</span> <input type="text" name="userList[2].age" > <br>
<button type="submit">提交</button>
</form>
UserController类
/*
* 对象集合
* 提前:
* 2. QueryVO类 中指定的 变量名 与 前端集合属性名 必须一致
* 1. 对象集合中指定的 User实体类变量名(属性名)与 前端属性名 必须一致
* */
@RequestMapping("parameterObjectSet")
public ModelAndView parameterObjectSet(QueryVO vo){
System.out.println("传递对象集合===============");
for (User user : vo.getUserList()) {
System.out.println(user);
}
ModelAndView mv = new ModelAndView();
mv.setViewName("jsp/ok");
return mv;
}
# 中文乱码解决
在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>
<!--强制 request(请求) 使用 UTF-8-->
<init-param>
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<!--强制 response(响应) 使用 UTF-8-->
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<!--对应映射名称 指定 url地址 进行过滤-->
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
# SpringMVC 响应返回参数
使用@Controller 注解的处理器的处理器方法,其返回值常用的有四种类型:
- ModelAndView
- String
- 返回自定义类型对象
- 无返回值 void
项目结构说明:(主要测试文件其余省略)
.
|
├── com
│ ├── controller
| | └── ResultController
| User
|
└── webapp
└── jsp
└── resultTest.jsp
说明:
ResultController类 添加了 @RequestMapping 注解路径
@Controller @RequestMapping("/user") public class ResultController {···}
User类 有 (int)id、(String)name、(int)age、(String)location 属性,分别有各自的 get和set方法 和 toString方法
# ModelAndView 响应
如果是前后端不分的开发,大部分情况下,返回 ModelAndView,即数据模型+视图:(跳转才能传递数据)
resultTest.jsp
<h3>通过 ModelAndView 进行返回</h3>
<div>
<span>id: ${id}</span> <br>
<span>name: ${name}</span> <br>
<span>age: ${age}</span> <br>
<span>location: ${location}</span> <br>
</div>
ResultController类
/**
* 通过 ModelAndView 形式跳转返回
* 响应传参 需要 addObject()方法 进行
*/
@RequestMapping("resultMAV")
public ModelAndView resultMAV() {
ModelAndView mv = new ModelAndView();
//返回参数 (逐个传参)
mv.addObject("id","001");
mv.addObject("name","Sanscan12");
mv.addObject("age","21");
mv.addObject("location","福州");
//需要经过视图解析器转换物理路径
mv.setViewName("jsp/resultTest");
return mv;
}
# String 响应
resultTest.jsp
<h3>通过 String 进行返回</h3>
<h4>requestScope 作用区域测试</h4>
<div>
<span>id: ${requestScope.user.id}</span> <br>
<span>name: ${requestScope.user.name}</span> <br>
<span>age: ${requestScope.user.age}</span> <br>
<span>location: ${requestScope.user.location}</span> <br>
</div>
<h4>Session 作用区域测试</h4>
<div>
<span>id: ${sessionScope.user.id}</span> <br>
<span>name: ${sessionScope.user.name}</span> <br>
<span>age: ${sessionScope.user.age}</span> <br>
<span>location: ${sessionScope.user.location}</span> <br>
</div>
ResultController类
/*
* 通过 String 形式跳转返回
* 响应传参 需要 HttpServletRequest原生对象 进行
* */
@RequestMapping("resultString")
public String resultString(HttpServletRequest request){
//实例对象
User user = new User(002,"柏竹",21,"平南");
//携带参数进行传递
request.setAttribute("user",user);
request.getSession().setAttribute("user",user);
return "jsp/resultTest";
}
# 自定义类型对象 响应
自定义对象类型常用的有:Integer、Double、List、Map (返回并非逻辑视图名称,而是数据返回)
以上数据类型一般搭配 ajax 请求使用,将 JSON格式 的数据直接响应返回
应用前提&说明:
方法需要添加
@ResponseBody
注解引入依赖 Maven项目引入
<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-databind</artifactId> <version>2.9.0</version> </dependency>
数据的返回用 AJAX进行响应呈现
# Integer 整型
resultTest.jsp
<h4>Integer 整型</h4>
<div id="Integer"></div>
<button id="IntegerAjax">ajax请求</button>
···
<!--ajax测试-->
$("#IntegerAjax").click(function(){
$.ajax({
type:"POST",
url: "resultInteger",
data: "",
success: function(msg){
$("#Integer").html("值:"+msg);
}
});
});
ResultController类
/*
* Integer 整型
* 搭配 ajax 请求使用,将 JSON格式 的数据直接响应返回
* */
@ResponseBody
@RequestMapping("resultInteger")
public Integer resultInteger(){
return 2188;
}
# String 字符型
同样是返回数据,因 @ResponseBody
注解
resultTest.jsp
<h4>String 字符型</h4>
<div id="String"></div>
<button id="StringAjax">ajax请求</button>
···
<!--ajax测试-->
$("#StringAjax").click(function(){
$.ajax({
type: "POST",
url: "resultString2",
data: "",
success: function(msg){
$("#String").html("值:"+msg);
}
});
});
ResultController类
/*
* String 整型
* 搭配 ajax 请求使用,将 JSON格式 的数据直接响应返回
* */
@ResponseBody
@RequestMapping("resultString2")
public String resultString(){
return "resultString2";
}
# Double 浮点型
resultTest.jsp
<h4>Double 浮点型</h4>
<div id="Double"></div>
<button id="DoubleAjax">ajax请求</button>
···
<!--ajax测试-->
$("#DoubleAjax").click(function(){
$.ajax({
type: "POST",
url: "resultDouble",
data: "",
success: function(msg){
$("#Double").html("值:"+msg);
}
});
});
ResultController类
/*
* Double 浮点型
* 搭配 ajax 请求使用,将 JSON格式 的数据直接响应返回
* */
@ResponseBody
@RequestMapping("resultDouble")
public double resultDouble(){
return 3.14;
}
# List 列表
resultTest.jsp
<h4>List 列表</h4>
<div id="List"></div>
<button id="ListAjax">ajax请求</button>
···
<!--ajax测试-->
$("#ListAjax").click(function(){
$.ajax({
type: "POST",
url: "resultList",
data: "",
success: function(msg){
var str = "";
for (let i = 0; i < msg.length; i++) {
str= str+" "+i+"."+msg[i];
}
$("#List").html("值:"+str);
}
});
});
ResultController类
/*
* List 列表
* 搭配 ajax 请求使用,将 JSON格式 的数据直接响应返回
* */
@ResponseBody
@RequestMapping("resultList")
public List resultList(){
List list = new ArrayList();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("赵六");
return list;
}
# Map 哈希表
resultTest.jsp
<h4>Map 哈希表</h4>
<div id="Map"></div>
<button id="MapAjax">ajax请求</button>
···
<!--ajax测试-->
$("#MapAjax").click(function(){
$.ajax({
type: "POST",
url: "resultMap",
data: "",
success: function(msg){
var str= "id: "+msg.id+
",name: "+msg.name+
",age: "+msg.age+
",location: "+msg.location;
$("#Map").html("值:"+str);
}
});
});
ResultController类
/*
* Map 哈希表
* 搭配 ajax 请求使用,将 JSON格式 的数据直接响应返回
* */
@ResponseBody
@RequestMapping("resultMap")
public Map resultMap(){
Map map = new HashMap();
map.put("id","04");
map.put("name","李四");
map.put("age","23");
map.put("location","深圳");
return map;
}
# 对象
resultTest.jsp
<h4>User 对象</h4>
<div id="User"></div>
<button id="UserAjax">ajax请求</button>
···
<!--ajax测试-->
$("#UserAjax").click(function(){
$.ajax({
type: "POST",
url: "resultUser",
data: "",
success: function(msg){
var str= "id: "+msg.id+
",name: "+msg.name+
",age: "+msg.age+
",location: "+msg.location;
$("#User").html("值:"+str);
}
});
});
ResultController类
/*
* User 对象
* 搭配 ajax 请求使用,将 JSON格式 的数据直接响应返回
* */
@ResponseBody
@RequestMapping("resultUser")
public User resultUser(){
return new User(002,"张三",23,"南宁");
}
整体结果:
响应返回值
通过 ModelAndView 进行返回
id:
name:
age:
location:
通过 String 进行返回
requestScope 作用区域测试
id: 2
name: 柏竹
age: 21
location: 平南
Session 作用区域测试
id: 2
name: 柏竹
age: 21
location: 平南
返回自定义对象类型 进行返回
Integer 整型
值:2188
ajax请求
String 字符型
值:resultString2
ajax请求
Double 浮点型
值:3.14
ajax请求
List 列表
值: 0.张三 1.李四 2.王五 3.赵六
ajax请求
Map 哈希表
值:id: 04,name: 李四,age: 23,location: 深圳
ajax请求
User 对象
值:id: 2,name: 张三,age: 23,location: 南宁
ajax请求
# 无返回值 void 响应
方法的返回值为 void,并不一定真的没有返回值,可以通过其他方式给前端返回。实际上,这种方 式也可以理解为 Servlet 中的的处理方案。响应一般为:跳转、重定向
//页面转换形式: 跳转
@RequestMapping("resultVoid1")
public void resultVoid1(HttpServletRequest rs, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("resultVoid1");
rs.getRequestDispatcher("/jsp/ok.jsp").forward(rs,resp);
}
//页面转换形式: 重定向
@RequestMapping("resultVoid2")
public void resultVoid2(HttpServletRequest rs, HttpServletResponse resp) throws IOException {
System.out.println("resultVoid2");
resp.sendRedirect("/jsp/ok.jsp");
}
//void类型 ajax应用
@RequestMapping("resultVoid3")
public void resultVoid3(HttpServletResponse resp) throws IOException {
System.out.println("resultVoid3");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
PrintWriter pw = resp.getWriter();
pw.flush();
pw.close();
}
//页面转换形式: 重定向响应码 302
@RequestMapping("resultVoid4")
public void resultVoid4(HttpServletResponse resp) {
System.out.println("resultVoid4");
resp.setStatus(302);
resp.setHeader("Location","/jsp/ok.jsp");
}