文章目录
- 1 单个简单数据类型
- 1.1 提交
- 1.2 接收
- 2 多个简单数据类型
- 1.1 提交
- 1.2 接收
- 3 自定义类型
- 3.1 提交
- 3.2 接收
- 4 JSON数据类型
- 4.1 提交
- 4.2 接收
- 5 控制器处理请求
- 5.1 转发、重定向
- 5.2 传递数据
- 5.3 处理异步请求
- 6 RestFul风格
1 单个简单数据类型
1.1 提交
提交单个基本数据类型方式有两种,一是通过URl进行提交,二是通过构建表单进行提交。
- 方式1:URL
<a href="../user/add?userName=tom&userAge=22&userSex=1">URL提交数据</a>
- 方式二:表单
- 输入框需要提供name属性,springMVC控制器是通过name属性取值。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="../user/add"method="post">
<p>姓名</p><input type="text"name="userName"/>
<p>年龄</p><input type="text"name="useAge"/>
<p>性别</p><input type="text"name="userSex"/>
<p><input type="submit" value="提交"></p>
</form>
</body>
</html>
注意
当前目录结构如下:
<form action="user/add"method="post">
请求路径为:http://localhost:8080/demo2_war/pages/user/add
<form action="/user/add"method="post">
请求路径为:http://localhost:8080/user/add
<form action="../user/add"method="post">
正确请求路径为:http://localhost:8080/demo2_war/user/add
1.2 接收
无论通过URL还是通过表单,接收方式一样。但需要注意以下几点。
- 如果控制器方法中接收数据的参数名与请求传值的key一致,则自动复制。
- 如果不一致,使用@RequestParam注解进行关联。该注解共有四个属性值
- vaule name的别名,请求参数的名称,绑定请求参数,基本等价与name。
- name 绑定请求参数名称,等价于vaule
- required,指定参数是否为必须,默认为true,如果请求路劲没有传入该参数,则会报错。
- defaultValue 设置参数默认值,如果设置了值, 则required=ture不会生效,自动变成required=false
- 也可以直接使用对象接收数据,前提是对象是属性名必须与name一致。
package com.yiwu.controllers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/add")
public String addUser(String userName,Integer userAge,@RequestParam("userSex") Integer s){
System.out.println("访问到了插入用户````");
System.out.println(userName);
System.out.println(userAge);
System.out.println(s);
return "success";
}
@RequestMapping("/delete")
public String deleteUser(){
System.out.println("访问到了删除用户");
return "success";
}
}
或使用类对象作为参数
@RequestMapping("/add3")
public String addUser2(User user){
System.out.println("访问到了插入用户````");
System.out.println(user);
return "success";
}
其中User类为
package com.yiwu.pojo;
public class User {
String userName;
Integer userAge;
Integer ueerSex;
//set方法
//get方法
}
2 多个简单数据类型
存在前端需要传递多个同名参数到服务器的情况,如传递一组ID值等。
1.1 提交
<form action="../user/info" method="post">
<input name="uid" value="1" type="checkbox">张三<br/>
<input name="uid" value="2" type="checkbox">李四<br/>
<input name="uid" value="3" type="checkbox">王二<br/>
<input type="submit" value="查询详情">
</form>
1.2 接收
接收方式一,以数组方式接收
@RequestMapping("/info")
public String info(String[] uid){
for (String id:uid){
System.out.println(id);
}
return null;
}
接收方式二,以集合List方式接收,需要使用注解@RequestParam
@RequestMapping("/info")
public String info(@RequestParam("uid") List<String> uid){
for (String id:uid){
System.out.println(id);
}
return null;
}
3 自定义类型
自定义数据类型,并且自定义类型的属性中有为List类型,属性为map,数组,集合的情况。
如实体用户更改为
public class User {
String userName;
Integer userAge;
Integer userSex;
IdCard idcard;
List<Order> orders;
List<Integer> orderIDs;
}
其中 IdCard为:
public class IdCard{
int id;
int idcardNum;
}
Order 为
public class Order {
int id;
int OrderNum;
}
3.1 提交
<form action="../user/info" method="post">
姓名:<input name="userName" value="1" type="text"><br/>
年龄:<input name="userAge" value="2" type="text"><br/>
姓别:<input name="userSex" value="3" type="text"><br/>
用户Id号:<input name="idcard.idcardNum" value="2" type="text"><br/>
订单Id:<input name="orderIDs" value="1" type="checkbox"><br/>
订单Id:<input name="orderIDs" value="2" type="checkbox"><br/>
订单Id: <input name="orderIDs" value="3" type="checkbox"><br/>
定单1:<input name="orders[0].OrderNum" value="3" type="text"><br/>
订单2:<input name="orders[1].OrderNum" value="3" type="text"><br/>
<input type="submit" value="提交数据">
</form>
若List泛型为基本数据类型,则name为属性名
若泛型为自定义类型,name名要与实体类的层级结构保持一致。
若属性为Map类型,如
HashMap<String,user> userInfo;其中user为自定义类型,有age,sex等属性。
则前端页面的name属性,应该为userInfo[“张三”].Age,userInfo[“张三”].Sex
3.2 接收
@RequestMapping("/info")
public String info(User user){
System.out.println(user);
return null;
}
4 JSON数据类型
JSON 是一种轻量级的数据交换格式。JSON 是 JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串。他由花括号括起来的逗号分割的成员构成,成员是字符串键和上文所述的值由逗号分割的键值对组成。
1.要实现从JSON字符串转换为JS对象,使用 JSON.parse() 方法:
var obj = JSON.parse('{"a": "Hello", "b": "World"}'); //结果是 {a: 'Hello', b: 'World'}
2.要实现从JS对象转换为JSON字符串,使用 JSON.stringify() 方法:
var json = JSON.stringify({a: 'Hello', b: 'World'}); //结果是 '{"a": "Hello", "b": "World"}'
4.1 提交
1使用jQuery,导入 jquery-3.3.1.min.js
,放至pages下的js文件夹内。(jquery下载地址https://jquery.com/download/)
2放行静态资源,<mvc:resources mapping="/pages/**" location="/pages/"/>
3请求行、请求头、请求体都可以用来传值
<script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
<form method="post">
<p>姓名</p><input type="text" id="userName" name="userName"/>
<p>年龄</p><input type="text" id="userAge" name="userAge"/>
<p>性别</p><input type="text" id="userSex" name="userSex"/>
<p><input type="button" value="提交" onclick="submitInfo()"></p>
</form>
<script>
function submitInfo(){
var obj={}
obj.userName = $("#userName").val();
obj.userAge = $("#userAge").val();
obj.userSex = $("#userSex").val();
console.log(JSON.stringify(obj))
console.log(obj)
$.ajax(
{
//请求行
url:"../user/add4",
//url:"../user/add4?userName=zhangsan&userAge=2&userSex=1",
type:"post",
//请求头
headers:{
token:"xxxx"
},
contentType:"application/json",
//请求体
data:JSON.stringify(obj),
success:function (res){
//打印响应数据
console.log(JSON.parse(res));
console.log(res);
}
}
)
}
</script>
4.2 接收
引入jackson依赖。用于序列化和反序列化json,也就是json与java数据之间的转换。
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.0</version>
</dependency>
🔴接收请求行中的数据,同表单或URL简单数据类型。
🔴**接收请求头中的数据,控制器形参使用RequestHeader("token") token
**修饰
@RequestMapping("/add")
public String addUser(@RequestHeader("token")String token, String userName, Integer userAge, @RequestParam("userSex") Integer s){
System.out.println(token);
System.out.println(userName);
System.out.println(userAge);
System.out.println(s);
return "success";
}
🔴接收请求体中的数据。
@RequestMapping("/add4")
@ResponseBody
public List<User> addUser4(@RequestBody User user){
System.out.println("访问到了插入用户````");
System.out.println(user);
//响应数据给前端
List<User> users = new ArrayList<User>();
users.add(new User("aaa",21,0));
users.add(new User("bbb",33,1));
return users;
}
5 控制器处理请求
5.1 转发、重定向
处理同步请求,如理URL,表单from,根据处理结果进行重定向或转发,处理器方法的返回类型为String或者ModelAndView
重定向不回自动加上前缀或后缀。
package com.yiwu.controllers;
import com.yiwu.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/test01")
public String test01(){
//两种写法
//return "forward:../success.jsp";
return "success";
}
@RequestMapping("/test02")
public String test02(){
return "redirect:../success.jsp";
}
@RequestMapping("/test03")
public ModelAndView test03(){
//两种写法
//ModelAndView modelAndView = new ModelAndView("success");
ModelAndView modelAndView = new ModelAndView("forward:../success.jsp");
return modelAndView;
}
@RequestMapping("/test04")
public ModelAndView test04(){
ModelAndView modelAndView = new ModelAndView("redirect:../success.jsp");
return modelAndView;
}
}
<a href="../user/test01">转发测试1</a><br/>
<a href="../user/test02">重定向测试1</a><br/>
<a href="../user/test03">转发测试2</a><br/>
<a href="../user/test04">重定向测试2</a><br/>
重定向地址栏会发生变化,转发地址栏不会发生变化;
请求转发(forward)整个过程是一个请求,一个响应。
过程:客户首先发送一个请求到服务器端,服务器端发现匹配的servlet,并指定它去执行,当这个servlet执行完之后,把请求转发给指定的test.jsp,整个流程都是在服务器端完成的,而且是在同一个请求里面完的,因此servlet和jsp共享的是同一个request,在servlet里面放的所有东西,在jsp中都能取出来,因此,jsp能把结果getAttribute()出来。
重定向(sendRedirect)两个请求,两个响应。
过程:客户发送一个请求到服务器,服务器匹配servlet,这和请求转发一样,当这个servlet处理完之后,立即向客户端返回这个响应,响应行告诉客户端你必须要再发送一个请求,去访问test.jsp,紧接着客户端受到这个请求后,立刻发出一个新的请求,去请求test.jsp,这里两个请求互不干扰,相互独立,两者的不同的适用场景:
请求转发只需要请求一次服务器,可以提高访问速度。
重定向可以跳转到任意服务器,可以用在系统间的跳转。
5.2 传递数据
对于同步请求的转发响应,我们可以传递参数到转发的页面
- 返回类型为String
- 在控制器方法中定义一个Model类型的参数
- 在return页面之前,向model中添加键值对,添加的键值对就会被传递到转发的页面
- 返回值为ModelAndView
- modelAndView.addObject(“key1”,“value”);
jsp页面:
<a href="../user/test06">返回值为String,参数为Model,传值测试1</a><br/>
<a href="../user/test07">返回值为ModelAndView,传值测试2</a><br/>
@RequestMapping("/test06")
public String test06(Model model) {
User temUser = new User("aaa",20,0);
model.addAttribute("key1","vvvvv");
model.addAttribute("user",temUser);
return "test";
}
@RequestMapping("/test07")
public ModelAndView test07() {
User temUser = new User("bbb",20,1);
ModelAndView modelAndView = new ModelAndView("test");
modelAndView.addObject("key1","xxxx");
modelAndView.addObject("user",temUser);
return modelAndView;
}
test.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${key1}
<br>
${user.userName}
${user.userAge}
</body>
</html>
5.3 处理异步请求
直接在控制器方法返回响应的对象
在对应的controller的方法上添加注解@ResponseBody,让这个方法返回值不走视图解析器,直接返回一个字符串;除了这个注解外,我们还可以使用注解@RestController代替类上的@Controller注解,它的作用就是设置这个controller类中的所有的处理方法返回的值都不走视图解析器,而是直接返回一个字符串
- 在控制器方法前添加一个 @ResponseBody 注解,将返回的对象转换成JSON格式返回给ajax请求,json的键为属性名,value为属性值。
- 也可以在控制器类前添加 @ResponseBody 注解,则所有方法都是响应ajax请求,
@RequestMapping("/test05")
@ResponseBody
public List<User> test05(){
List<User> users = new ArrayList<User>();
User user = new User();
user.setUserAge(22);
user.setUserSex(1);
user.setUserName("hahah");
users.add(user);
return users;
}
<input id = "btn3" type="button" value="处理异步请求测试"/><br>
<span>姓名: </span><p id = "userName"></p>
<span>年龄: </span><p id = "userAge"></p>
<span>性别: </span><p id = "userSex"></p>
<script type="text/javascript">
$("#btn3").click(function (){
$.ajax({
url:"../user/test05",
type:"post",
contentType:"application/json",
dataType:"json",
success:function (res){
console.log(res);
//写法一
//$("#userName").text(res[0]["userName"])
//写法2
$("#userName").text(res[0]["userName"])
$("#userAge").text(res[0]["userAge"])
$("#userSex").text(res[0]["userSex"])
}
});
});
</script>
6 RestFul风格
概念:
Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。互联网所有的事物都可以被抽象为资源。
资源操作:
可以通过不同的请求方式来实现不同的效果。例如请求地址一样,请求方式不一样,功能可能不一样;一般情况下
- POST表示添加
- DELETE表示删除
- PUT表示更新
- GET表示查询。
案例:查询id为3用户
- 传统方式下的访问路径可能是
- localhost:8080/demo2_war/user/getuser?id=3
- 使用RestFul风格,设置请求方式为GET
- localhost:8080/demo2_war/user/getuser/3
第一步,编写控制器
@RequestMapping(value = "/test09/{name}/{age}",method = {RequestMethod.GET})
public String test09(@PathVariable String name ,@PathVariable int age) {
System.out.println(name);
System.out.println(age);
return null;
}
第二步,编写前端页面
<input id = "btn4" type="button" value="restFul风格默认get请求"/><br>
<script type="text/javascript">
$("#btn4").click(function (){
$.ajax({
url:"../user/test09/abc/22",
type:"get",
contentType:"application/json",
dataType:"json",
success:function (res){
}
});
});
</script>
第四步、验证不同的请求方式,同样的请求地址,可以到达不同的处理器方法。
更改步骤3的请求方式进行验证。
@RequestMapping(value = "/test09/{name}/{age}",method = {RequestMethod.GET})
public String test09(@PathVariable String name ,@PathVariable int age) {
System.out.println("GET");
System.out.println(name);
System.out.println(age);
return null;
}
@RequestMapping(value = "/test09/{name}/{age}",method = {RequestMethod.PUT})
public String test10(@PathVariable String name ,@PathVariable int age) {
System.out.println("PUT");
System.out.println(name);
System.out.println(age);
return null;
}
@RequestMapping(value = "/test09/{name}/{age}",method = {RequestMethod.DELETE})
public String test11(@PathVariable String name ,@PathVariable int age) {
System.out.println("DELETE");
System.out.println(name);
System.out.println(age);
return null;
}
@RequestMapping(value = "/test09/{name}/{age}",method = {RequestMethod.POST})
public String test12(@PathVariable String name ,@PathVariable int age) {
System.out.println("POST");
System.out.println(name);
System.out.println(age);
return null;
}
注意点:
- 所有的地址栏请求默认都会是HTTP GET类型
- 使用下述注解可以代替 @RequestMapping,无须指定请求方式。
- @GetMapping
- @PostMapping
- @PutMapping
- @DeleteMapping
- 例如
@GetMapping(“/add1/{a}/{b}”)
等价于
@RequestMapping(value = “/add1/{a}/{str}”,method = {RequestMethod.GET})