目录
[Spring Web MVC](#Spring Web MVC)
Spring Web MVC
Spring Web MVC:是基于Servlet API构建的原始web框架,实现了mvc设计模式的思想,通常被称为spring mvc
Servlet:是一套Java Web开发的规范(技术标准),是一种实现动态页面的技术
MVC的定义:Model Controller View
注解
@RestController
这是一个类注解,加了这个注解,spring才会对该类进行扫描。@RestController = @Controller(返回视图) + @ResponseBody(返回数据),所以最后返回的就是数据
@RequestMapping
URL路由映射,是用来注册接口的路由映射的
访问路径=类路径+方法路径,路径不能重复
可以修饰类,也可以修饰方法
支持GET请求,也支持POST请求
@RequestParam
@RequestParam进行参数重命名时,参数就变成了必传参数(required默认为true),将required改为false就为非必传了(方法参数)
@RequestParam
传递集合参数和传递数组类似,只是集合需要使用@RequestParam绑定参数关系。默认情况下,请求中参数名相同的多个值,封装到数组;要封装到集合,则需要使用@RequestParam绑定参数关系(集合)
@RequestBody
@RequestBody 作用在请求正文的数据绑定,请求参数必须秀在请求正文中(json)
@PathVariable
@PathVariable 路径变量,作用在请求URL路径上的数据绑定,默认传递参数写在URL上,SpringMVC就可以获取到(url)
@RequestPart
@RequestPart 可用于文件重命名(文件)
参数传递
接收参数。对于包装类型,如果不传对应参数,Spring接收到的数据则是null;对于基本类型,如果不传对应参数,会报500错误

注意事项
使用基本类型接收参数时,参数必须传(除了boolean类型),否则会报500错误,类型不匹配时会报400错误
参数重命名
@RequestParam
@RequestParam进行参数重命名时,参数就变成了必传参数(required默认为true),将required改为false就为非必传了

传递集合
@RequestParam
传递集合参数和传递数组类似,只是集合需要使用@RequestParam绑定参数关系。默认情况下,请求中参数名相同的多个值,封装到数组;要封装到集合,则需要使用@RequestParam绑定参数关系
传递JSON数据
JSON:是一种轻量级的数据交互格式,JSON本质是字符串,主要负责在不同的语言中数据传递和交换
JSON字符串和Java对象互转:可以通过jackson、fastjson1、fastjson2、gson...在Spring MVC框架中集成了JSON转换工具jackson
jackson工具:使用ObjectMapper对象提供的两个方法,JSON和Java对象可以互转
writeValueAsString():把对象转为JSON字符串
readValue():把JSON字符串转为对象(需要有无参构造方法)
@RequestBody
@RequestBody 作用在请求正文的数据绑定,请求参数必须在请求正文中
获取URL中的参数
@PathVariable
@PathVariable 路径变量,作用在请求URL路径上的数据绑定,默认传递参数写在URL上,SpringMVC就可以获取到
上传文件
@RequestPart
@RequestPart 可用于文件重命名

Cookie和Session
Cookie和Session的区别
Cookie是保存在客户端的用户信息的一种机制,Session是保存在服务器端的用户信息一种机制,sessionId是两者之间的桥梁。
cookie是不安全的,可以伪造cookie;session是安全的。
session默认是保存在内存中,如果重启服务器session数据就会丢失。
Cookie和Session的关系

设置session(2种方式)
java
// 设置Session
@RequestMapping("/setSession1")
public String setSession1(HttpServletRequest request) {
HttpSession session = request.getSession();
session.setAttribute("name", "value1");
session.setAttribute("age", 200);
return "设置session成功 key1:value1 key2:200";
}
// 设置Session
@RequestMapping("/setSession2")
public String setSession2(HttpServletRequest request, String value3, Integer value4) {
HttpSession session = request.getSession();
session.setAttribute("name", value3);
session.setAttribute("age", value4);
return "设置session成功! name:" + value3 + " age:" + value4;
}
// 设置Session
@RequestMapping("/setSession3")
public String setSession3(HttpSession session, String name, Integer age) {
session.setAttribute("name", name);
session.setAttribute("age", age);
return "设置session成功! name:" + name + " age:" + age;
}
设置完一条Session就会自动生成一个Cookie

获取cookie(2种方式)
1:通过接口HttpServletRequest
2:通过注解@CookieValue
java
@RequestMapping("/getCookie1")
public String getCookie1(HttpServletRequest request) {
Cookie[] cookies = request.getCookies();
if(cookies == null) {
System.out.println("没有Cookie");
return "没有Cookie";
}
for (Cookie cookie : cookies) {
System.out.println("getCookie-》" + cookie.getName() + ":" + cookie.getValue());
}
return "获取Cookie成功";
}
@RequestMapping("/getCookie2")
public String getCookie2(@CookieValue("key3") String value) {
return "获取Cookie成功! key:" + value;
}
获取session(3种方式)
1:通过接口HttpServletRequest
2:通过接口HttpSession
3:通过注解SessionAttribute
此处获取需要进行对象转换,将Object对象转换成替他类型(String、Integer)
java
// 获取Session
@RequestMapping("/getSession1")
public String getSession1(HttpServletRequest request) {
HttpSession session = request.getSession();
String name = (String)session.getAttribute("name");
Integer age = (Integer)session.getAttribute("age");
return "获取session成功 key1:" + name + " key2:" + age;
}
// 获取Session
@RequestMapping("/getSession2")
public String getSession2(HttpSession session) {
String name = (String)session.getAttribute("name");
Integer age = (Integer)session.getAttribute("age");
return "获取session成功 key1:" + name + " key2:" + age;
}
// 获取Session
@RequestMapping("/getSession3")
public String getSession3(@SessionAttribute("name") String name, @SessionAttribute("age") Integer age) {
return "获取session成功 key1:" + name + " key2:" + age;
}
获取header(2种方式)
java
// 获取header
@RequestMapping("/getHeader1")
public String getHeader1(HttpServletRequest request) {
String connection = request.getHeader("Connection");
return "获取header成功! header:" + connection;
}
// 获取header
@RequestMapping("/getHeader2")
public String getHeader2(@RequestHeader("Connection") String connection) {
return "获取header成功! header:" + connection;
}
返回响应
响应静态页面
@RestController = @Controller(返回视图) + @ResponseBody(返回数据),所以最后返回的就是数据
@ResponseBody 作用在类上,该类上的所有方法返回都是数据;作用在方法上返回的都是数据
java
@RequestMapping("/data")
public String response() {
return "index.html"; // 这是一个相对路径,就找不到这个页面
}
@RequestMapping("/static_page_data")
public String responseStaticPage() {
return "/index.html";
// 但是此处被是被为了字符串,原因是加了@RestController
// @RestController = @Controller(返回视图) + @ResponseBody(返回数据),所以返回的是字符串,而不是视图,所以会找不到这个页面
// 在类上使用@Controller注解,就会返回视图,就可以找到这个页面了
}
响应html代码片段
java
// 响应html代码片段
@RequestMapping("/responseHtml")
@ResponseBody
// 不加@ResponseBody就找不到这个字符串
// 因为@Controller返回的是视图
// @RestController(返回数据) = @Controller(返回视图) + @ResponseBody(返回数据)
public String responseHtml() {
return "<h1>Hello World</h1>";
}
响应JSON对象
java
// 响应JSON对象
@RequestMapping("/json")
@ResponseBody
public Person responseJSON() {
Person person = new Person();
person.setName("张三");
person.setAge(20);
person.setGender("男");
return person;
}
设置Connect-Type
// 设置connect-type
@ResponseBody
@RequestMapping("/connect_type")
public void setConnectType1(HttpServletResponse response) throws IOException {
response.setContentType("text/plain"); // text/plain,返回的是纯文本
response.getOutputStream().write("<h1>Hello World</h1>".getBytes(StandardCharsets.UTF_8));
}
// 设置connect-type
@ResponseBody
@RequestMapping(value = "/setConnectType" , produces = "text/plain")
public String setConnectType2 (HttpServletResponse response) throws IOException {
// response.getOutputStream().write("<h1>Hello World</h1>".getBytes(StandardCharsets.UTF_8));
return "<h1>hello word</h1>";
}
小结练习:
登录练习和留言练习
API的实现
java
@RestController
@RequestMapping("/test")
public class TestController {
@PostMapping("/login")
public Boolean login(@RequestBody User user, HttpSession session) {
System.out.println("参数到达后端:user " + user.toString());
/**
* 校验参数
* TODO 校验密码是否正确
*/
if(!StringUtils.hasLength(user.getUserName()) || !StringUtils.hasLength(user.getPassword())) {
System.out.println("用户名或密码不规范");
return false;
}
if("admin".equals(user.getUserName()) && "admin".equals(user.getPassword())) {
// 存储用户
session.setAttribute("userName", user.getUserName());
session.setAttribute("password", user.getPassword());
return true;
}
return false;
}
@GetMapping("/loginUser")
public String loginUser(HttpServletRequest request) {
System.out.println("登录用户的获取!");
HttpSession session = request.getSession(false);
// 判断Session是否有数据
if(session != null) {
String userName = (String)session.getAttribute("userName");
return "登录用户:" + userName;
}
return "没用用户登录";
}
List<Message> messages = new ArrayList<>();
@PostMapping("publishMessage")
public Boolean publishMessage(@RequestBody Message message) {
System.out.println("留言参数到达后端 message:" + message);
/**
* 校验参数
* 存储数据
*/
if(!StringUtils.hasLength(message.getContent())
|| !StringUtils.hasLength(message.getReceiver())
|| !StringUtils.hasLength(message.getContent())) {
System.out.println("请正确填写留言板!");
return false;
}
messages.add(message); // 存储数据
return true;
}
@GetMapping("/messageList")
public List<Message> messageList() {
System.out.println("所有留言展现!");
return messages;
}
}
进行前后端交互


html
<body>
<div class="container">
<h1 style="color: #333;">留言板</h1>
<p class="grey">输入后点击提交, 会将信息显示下方空白处</p>
<div class="row">
<span>谁:</span> <input type="text" name="" id="from">
</div>
<div class="row">
<span>对谁:</span> <input type="text" name="" id="to">
</div>
<div class="row">
<span>说什么:</span> <input type="text" name="" id="say">
</div>
<input type="button" value="提交" id="submit" onclick="submit()">
<!-- <div>A 对 B 说: hello</div> -->
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script>
$.ajax({
url:"/test/messageList",
type:"get",
success:function (messages) {
// 遍历结果数组,将每个留言显示在页面上
for(let message of messages) {
var msg = message.commenter + " 对 " + message.receiver + " 说: " + message.content;
var messageElement = $("<div>" + msg + "</div>");
$(".container").append(messageElement);
}
}
});
function submit() {
// 获取数据
var commenter = $('#from').val();
var receiver = $('#to').val();
var content = $('#say').val();
// 调用后端接口
$.ajax({
url:"/test/publishMessage",
type:"post",
contentType:"application/json",
data:JSON.stringify({
commenter:commenter,
receiver:receiver,
content:content
}),
success:function (result) {
if(result) {
// 在留言板上显示留言
var message = commenter + " 对 " + receiver + " 说: " + content;
var messageElement = $("<div>" + message + "</div>");
$(".container").append(messageElement);
// 清空输入框的值
$('#from').val("");
$('#to').val("");
$('#say').val("");
} else {
alert("留言失败!")
}
}
});
}
</script>
</body>