SpringMVC简介
- SpringMVC,控制! Control
- SpringMVc是控制层的框架(Model,View,Control),主要是一种思想
- 前台请求发过来,控制层Control调用Model去处理
- 处理的结果以json字符串的形式返回,也有在浏览器处理后返回页面的,不多
get请求
get请求
- get请求,GetMapping接收,用PostMapping接收报错
- get请求的信息显示在浏览器的地址栏中,不安全
post请求
- post请求,PostMapping接收,用PostMapping接收报错
- post请求的信息不会显示在浏览器的地址栏中
get请求和post请求都可以用RequestMapping接收
static目录下index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>Get</h1>
<form action="/reg1" method="get">
<input type="text" name="username">
<input type="text" name="pwd">
<input type="submit" value="put">
</form>
<h1>Post</h1>
<form action="/reg2" method="post">
<input type="text" name="username">
<input type="text" name="pwd">
<input type="submit" value="put">
</form>
<h1>Get|Post</h1>
<form action="/reg3" method="Get">
<input type="text" name="username">
<input type="text" name="pwd">
<input type="submit" value="put">
</form>
<h1>Get|Post</h1>
<form action="/reg3" method="post">
<input type="text" name="username">
<input type="text" name="pwd">
<input type="submit" value="put">
</form>
</body>
</html>
必须是在controller包下才能通过注解RestController访问里面的方法
package com.tedu.springb.controller;
@RestController
public class UseController {
//被@RestController注解的类必须在 包路径.control 下才能起作用
//每个@RestController注解的类都是单例,项目运行时自动执行方法创建唯一对象
public UseController() {
System.out.println("无参构造方法");
}
//get请求,GetMapping接收,用PostMapping接收报错,多个人访问对象地址值不变,单例
@GetMapping("/reg1")
public String register1(String username,String pwd) {
return username+","+pwd+"注册成功"+"|"+this.toString();
}
//post请求,PostMapping接收,用GetMapping接收报错
@PostMapping("reg2")
public String register2(String username,String pwd) {
return username+","+pwd+"注册成功";
}
//RequestMapping可以接收get和post两种请求
@RequestMapping("reg3")
public String register3(String username,String pwd) {
return username+","+pwd+"注册成功";
}
//新建对象User,添加get、set方法,传入对象参数
//http://localhost:8088/reg5?username=iu&pwd=18
@RequestMapping("reg4")
public String register4(User user){
return user.getUsername()+","+user.getPwd();
}
}
Request,response对象
- 请求与响应
package com.tedu.springb.controller;
@RestController
public class UseController {
//模拟网页版请求
@RequestMapping("/reg5") //http://localhost:8088/reg5?username=iu&pwd=18
public String register5(HttpServletRequest request) {
String name = request.getParameter("username");
String pwd = request.getParameter("pwd");
//获得请求主机地址
String id = request.getRemoteAddr();
return name+","+pwd+","+id ;
}
//模拟响应
@RequestMapping("/reg6")
public void register6(HttpServletRequest request,HttpServletResponse response)throws Throwable {
String name = request.getParameter("username");
String pwd = request.getParameter("pwd");
String id = request.getRemoteAddr();
String string = name+","+pwd+","+id ;
//告诉浏览器返回数据类型
response.setContentType("text/html");
//告诉浏览器返回数据的字符集是utf-8
response.setCharacterEncoding("UTF-8");
PrintWriter printWriter = response.getWriter();
printWriter.println(string);
}
}
Cookie
cookie是你访问某个网站的身份证,每次你访问网站都会把你本地的所有cookie传给网站,当你是第一次访问网站时,网站给你写入cookie
添加cookie
服务器往浏览器写入cookie,response
@RestController public class UseController { @RequestMapping("/login") public String login(String name,HttpServletResponse response) { Cookie cookie = new Cookie("baidu_id", "429004**"); response.addCookie(cookie); return "设置了cookie"; } }
展示cookie信息
浏览器请求,cookie传到服务器,request
@RestController public class UseController { @RequestMapping("/list") public String list(String name,HttpServletRequest request) { //获得全部cookie,是个数组 Cookie cookies[] = request.getCookies(); String string = ""; if(cookies != null) { //遍历cookie数组 for (Cookie cookie : cookies) { string = cookie.getName()+":"+cookie.getValue(); } } return string; } }
Cookie生存周期
@RestController public class UseController { @RequestMapping("/setLive") public String setCookielive(HttpServletResponse response) { //不设置浏览器关闭就消失 Cookie cookie1 = new Cookie("bai_du", "429004***"); response.addCookie(cookie1); Cookie cookie2 = new Cookie("tao_bao", "888888***"); cookie2.setMaxAge(60*2); response.addCookie(cookie2); return "设置cookie存活时间"; } }
Session
session使用
session是存在于服务器端的信息,相当于小型数据库
- 需求:商城购物车
- 业务逻辑
- 当添加商品时,用户的请求首先到session中查找,首先在session第一层hashmap结构中(cookie值,hashmap)比较,比较cookie,找不到,就给浏览器设置cookie在进行添加,找到了就就进入第二层hashmap(购物车标识,购物车商品集合),添加进入购物车集合
- 展示商品时,浏览器的cookie会跟着用户的请求传给服务器,让服务器知道这是哪个人,
- 添加到购物车,服务器先分cookie过来,是response
- 请求显示商品,浏览器cookie全部跟着请求传到了服务器,是request
- 111 和 222是cookie值 ```java package com.tedu.mvcDemo.controller;
import java.util.ArrayList; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;
@RestController
public class CartController {
@RequestMapping(“/add”)
//添加商品到购物车,因此添加时会服务器会设置cookie到浏览器,response
public String addCart(String itemName,HttpSession session) {
//session内部是有hashmap,用来存放数据
//查看session内部有没有键cartList对应的集合,没有就建立这个集合cartLists
////这个集合就是购物车
ArrayList
“+item;
}
}
return string;
}
}
- 不同的浏览器就像不同的用户一样,访问时服务器会重新分配身份证--cookie
<a name="YwRd7"></a>
### Cookie与sessoin的关系
- Session的数据是存在服务器内存中,服务器重启数据就没了。
- Session是用临时cookie实现的,浏览器一关数据就没有了。如何实现在浏览器中添加购物车,在手机端查看呢?解决思路把购物商品放到数据库中,通过用户名从数据库查找购物商品。
- Cookie的数据是存在浏览器中的
<a name="s1CMe"></a>
## Controller
<a name="Lk16v"></a>
### @RestController返回json字符串
- 业务逻辑
- 发过来的请求被后台处理后变成对象返回给springmvc,在返回前台之前,SpringMVC框架将调用它里面的jackson框架处理对象为json字符串返回前台
![image.png](https://cdn.nlark.com/yuque/0/2021/png/358364/1610804808027-0a2bbb0d-ddfc-49f4-bb43-e6d6d4cd5fc7.png#align=left&display=inline&height=344&margin=%5Bobject%20Object%5D&name=image.png&originHeight=688&originWidth=979&size=57013&status=done&style=none&width=489.5)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/358364/1610804828967-c7741875-4647-4257-ac79-e8c6fdac6222.png#align=left&display=inline&height=308&margin=%5Bobject%20Object%5D&name=image.png&originHeight=616&originWidth=1072&size=88702&status=done&style=none&width=536)
```java
package com.tedu.mvcDemo.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UseController {
//加了@RestController后,框架会自动创建对象
@RequestMapping("find")
public Item find() {
//模拟返回数据库中的数据
Item item = new Item();
item.setName("oppo Ace");
item.setPrice(66);
//返回的是对象,框架会自动调用 jackson把对象转成json
return item;
}
}
Jsp显示商品信息
返回页面JSP(html页面) (@Controller)
1、添加依赖
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
2、创建Item类,商品名称、商品价格添加get、set方法,构造方法
3、创建Jsp页面
- 在src\main下创建文件夹webapp\WEB-INF\jsp
右键创建list.jsp,修改字符集为UTF-8
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> jsp </body> </html>
4、修改application.properties
设置jsp的前缀和后缀。强制把jsp放在/WEB-INF/jsp文件夹中。设置后在controller通过文件名list就可以访问/WEB-INF/jsp/list.jsp
spring.mvc.view.prefix=/WEB-INF/jsp/ spring.mvc.view.suffix=.jsp
5、创建controller
//@restController返回json @Controller//返回jsp public class ItemJspController { @RequestMapping("/listItem") public ModelAndView listItem() { //返回web-inf/jsp/list.jsp,View指的是界面,就是jsp ModelAndView modelAndView=new ModelAndView("list"); return modelAndView; } }
@Controller配合ModelAndView返回Jsp
Jstl展现商品信息的jsp页面(@Controller)
- JSTL(Java server pages standarded tag library,即JSP标准标签库),使用jstl可以很方便的在jsp中显示java数据,拷贝taglib标签。
- JSTL使用
- 在list.jsp中加入就可以使用JSTL了
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
```java package com.tedu.springb.controller;<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!--导入即可使用jstl语法 --> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <table border="2"> <tr> <td>商品名称</td><td>商品价格</td> </tr> <!--jstl语法,获得商品列表集合itemList,给每个商品一个变量指代item ,遍历 --> <c:forEach items="${itemList }" var="item"> <tr> <td>${item.name }</td><td>${item.price }</td> </tr> </c:forEach> </table> </body> </html>
- 在list.jsp中加入就可以使用JSTL了
import java.util.ArrayList; import java.util.List;
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView;
//返回json字符串用@RestController
//返回jsp用@Controller
@Controller
public class UseController {
@RequestMapping(“/listItem”)
public ModelAndView backJsp() {
//创建商品列表集合
List
- 将控制层的商品信息集合信息通过键itemList传给JSP页面渲染,然后返回整个页面给浏览器
<a name="tWWX1"></a>
### @Controller返回json(@Controller和@ResponseBody)
- @Controller+@ResponseBody 返回Json字符串
```java
package com.tedu.springb.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
//@Controller+@ResponseBody 返回Json字符串
@Controller
public class UseController {
@RequestMapping("/backJson")
@ResponseBody
public ArrayList<Item> backJson(){
ArrayList<Item> itemList = new ArrayList<Item>();
Item item1 = new Item("oppi", 66);
Item item2 = new Item("mate10", 88);
itemList.add(item1);
itemList.add(item2);
//SpringMVC自动调用Jackson框架处理对象数组,返回
return itemList;
}
}
@Controller与@RestController比较
- 修饰的类都是唯一实例对象(单例模式),都可以在浏览器上访问类里方法
@RestController注解相当于是@Controller注解 + @ResponseBody 合在一起的作用
新技术
- 使用vue,浏览器先请求html,网页加载完之后,再用axios发请求,浏览器请求的数据以json的形式返回给浏览器渲染,用数据绑定把数据显示在网页上。这种方式大大减轻了服务器的处理压力。分清了服务器处理数据,浏览器渲染数据二者工作区别。
- 老技术前后不分
- 老技术是把浏览器请求的数据 在服务器上渲染到页面上,然后返回处理好的的jsp、html页面给浏览器
状态码
- 404:你找的资源不存在
- 原因是地址写错了
- 服务器没有启动
- 新加的方法没有生效
- 地址写错了
- 500:服务器处理失败,抛出异常
- 302:重定向状态码
- 200:服务器处理成功,一般用于POST和GET请求
跳转
重定向
- 重定向返回的是页面,跳转到页面,用@Controller
- 重定向浏览器的地址栏变为 之后 的地址
重定向状态码 302
浏览器请求,服务器会告诉浏览器改变的新地址,然后浏览器再次发送请求,请求新的地址 ```java package com.tedu.springb.controller;
//重定向返回的是页面,用@Controller @Controller public class UseController { @RequestMapping(“/nextAddr”) public String nextAddr() { return “redirect:http://www.baidu.com“;
}
}
<a name="OTVEd"></a>
### 转发
- 转发后浏览器地址栏还是原来的地址。所以转发前请求的参数在转发后仍然可以读取到,loginByNamePwd里的name,pwd参数会获得loginByCode 的name,pwd参数值
![image.png](https://cdn.nlark.com/yuque/0/2021/png/358364/1610854184552-52cf9b3f-c7f7-4544-9187-4f9f7627fa08.png#align=left&display=inline&height=297&margin=%5Bobject%20Object%5D&name=image.png&originHeight=297&originWidth=589&size=19729&status=done&style=none&width=589)
```java
package com.tedu.springb.controller;
//转发返回的是页面,用@Controller
@Controller
public class UseController {
//第一输入用户名和密码
@RequestMapping("/ByNamePwd")
//注意:返回的是字符串,加上注解 @ResponseBody
@ResponseBody
public String loginByNamePwd(String name,String pwd) {
return "登录成功";
}
//再次登录时,还要输入验证码
@RequestMapping("/Bycode")
public String loginByCode(String name,String pwd,String code) {
return "forward:/ByNamePwd";
}
}
重定向redirect和转发forward的区别
1, 重定向浏览器地址栏显示新的地址,转发地址栏不变
2, 重定向可以重定向别的网站,转发只能转发到本网站中的方法。
RESTFul架构
- RESTFul要求通过url传输数据
- @PathVariable用于将请求URL中的模板变量映射到功能处理方法的参数上形成RUSTFul形式,这将是未来的发展趋势。它更加简洁,安全。强化URL GET访问方式。
- 普通传递参数的方法是 url?name=iu&pwd=18
- RESTFul传递参数 url/iu/18 ```java package com.tedu.springb.controller;
@RestController public class UseController { //RESTFul参数路径 @RequestMapping(“/select/{name}/{pwd}”) //@PathVariable用于将请求URL中的 模板变量 映射到 功能处理方法的参数上 形成RUSTFul形式 public String select(@PathVariable String name,@PathVariable String pwd) { return “查找”+name+”,”+pwd+”success”; } } ```
- http://localhost:8088/select/iu/18
- 找到画画的baby iu