前言:请先观看SpringMVC——快速入门之后再看此篇文章,方便理解。SpringMVC——快速入门_热爱编程的申同学的博客-CSDN博客SpringMVC的概述及工作原理,开发快速入门https://blog.csdn.net/select_myname/article/details/127542903?spm=1001.2014.3001.5501
目录
1、数据绑定
1.1、绑定servlet内置对象
1.2、@PathVariable
1.3、@RequestParam
1.4、@CookieValue
1.5、POJO对象绑定参数
1.6、基本数据类型绑定
1.7、解决乱码问题
1.8、通用页面跳转
1.9、数组类型
1.10、绑定复杂类型
1.11、jsp和jstl视图解析器
2、SpringMVC的异步交互
2.1、回顾ajax
2.2、@ResponseBody
2.3、@RequestBody
3、处理静态资源
3.1、测试前端代码
3.2、web.xml配置方式(三种解决方式之一)
3.3、springmvc-servlet.xml配置文件(三种解决方式之一)
3.4、springmvc-servlet.xml配置文件简化方式(三种解决方式之一)
4、SpringMVC拦截器
4.1、拦截器概述
4.2、拦截器的实现
4.3、拦截器链
5、过滤器和拦截器的区别
5.1、Filter过滤器
5.2、Interceptor拦截器
6、RESTfull风格
6.1、什么是RESTfull风格
6.2、RESTfull与传统URL对比
可以在controller控制类方法中获取request和response对象,以及session对象
@Controller
@RequestMapping("user")
//@RestController //相当于@Controller 和 @ResponseBody
public class UserController {
@RequestMapping("test1")
@ResponseStatus(HttpStatus.OK)
public void test1(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
System.out.println(request);
System.out.println(response);
System.out.println(session);
}
}
请求localhost:8080/user/test1.do路径
@Controller
@RequestMapping("user")
//@RestController //相当于@Controller 和 @ResponseBody
public class UserController {
@RequestMapping("test2/{id}/{name}")
public String test2(@PathVariable int id, @PathVariable String name) {
ModelAndView mv = new ModelAndView();
mv.addObject("id", id);
mv.addObject("name", name);
return "user";
}
}
将user页面存放在webapp包下,后缀为jsp文件
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
我是user页面
${id}
${user}
请求路径:localhost:8080/user/test2/12002/zhangsan.do
属性名 | 属性值 |
---|---|
value | 参数名 |
required | true(默认) false |
defultValue | 默认值,如果不给参数值,就走默认值 |
@Controller
@RequestMapping("user")
//@RestController //相当于@Controller 和 @ResponseBody
public class UserController {
@RequestMapping("test3")
@ResponseStatus(HttpStatus.OK)
public void test3(@RequestParam(value = "id", required = false, defaultValue = "222") int id, @RequestParam("name") String name) {
System.out.println(id);
System.out.println(name);
}
}
请求路径localhost:8080/user/test3.do?name=itssl,因为id给定了默认值且为不必要参数,所以没有写id参数
/**
* 通过后台跳转到cookie视图
*
* @return
*/
@RequestMapping("toCookie")
public String toCookie() {
return "cookie";
}
/**
* 获取cookie的值
*
* @param
*/
@RequestMapping("test5")
@ResponseStatus(HttpStatus.OK)
public void test5(@CookieValue(value = "name", required = false) String name) {
System.out.println("cookie的值为:" + name);
}
cookie.jsp页面,首先先请求toCookie到此页面,然后通过页面点击a标签请求test5接口
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
测试cookie
点击测试cookie ,idea控制台输出
创建实体类,这里使用lombok依赖进行set/get。
org.projectlombok
lombok
1.16.18
user实体类
@Data //set/get方法
@AllArgsConstructor //有参构造
@NoArgsConstructor //无参构造
public class User {
private int id;
private String name;
private int age;
private String address;
}
书写一个控制类,填写user对象参数,以及request对象用来把user对象放到request域中,让jsp页面进行获取数据。
@RequestMapping("test6")
public String test6(User user, HttpServletRequest request) {
request.setAttribute("user", user);
return "user";
}
user.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
我是user页面
${user}
注意:如果请求路径中没有填写相应的实体类属性,会以各个属性类型的默认值呈现。如:int类型为0,boolean类型为false...
//跳转到login页面
@RequestMapping("toUser")
public String toUser() {
return "login";
}
@PostMapping("test8")
@ResponseStatus(HttpStatus.OK)
public void test8(@RequestParam("name") String name,
@RequestParam("age") Integer age,
@RequestParam("income") Integer income,
@RequestParam("isMarried") Boolean isMarried,
@RequestParam("interests") String interests) {
System.out.println(name);
System.out.println(age);
System.out.println(income);
System.out.println(isMarried);
System.out.println(interests);
}
login.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
提交表单,ieda控制台输出
如果上面返回的数据存在乱码的话,那就是post请求乱码,在以往servlet学习中,直接对request对象进行设置utf-8就能解决,那么现在springMVC中如何解决这个问题呢?
需要在web.xml中通过过滤器来进行解决
encodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
utf-8
encodingFilter
/*
我们发现上面我们写了很多次页面跳转的方法,其实我们可以抽取统一
@Controller
@RequestMapping("toPage")
public class ToPage {
@RequestMapping("{page}")
public String toPage1(@PathVariable("page") String page){
return page;
}
}
@RequestMapping("test9")
@ResponseStatus(HttpStatus.OK)
public void test9(String[] addr) {
for (String s : addr) {
System.out.println(s);
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
数组
先通过通用页面跳转接口跳转到address.jsp页面
选择上海和北京提交
实体类中拥有很多类型,数组、包装类、Map、List等这种复杂实体类如何接收呢?
@Data
public class UserVO {
private String name;
private Integer age;
private User user;
private List list;
private Map map;
private String[] addr;
}
控制类代码
@RequestMapping("test10")
@ResponseStatus(HttpStatus.OK)
public void test10(UserVO userVO) {
System.out.println(userVO);
}
list.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
使用jstl核心标签库需要导入依赖坐标
javax.servlet
jstl
1.2
@GetMapping("test11")
public ModelAndView test11(ModelAndView mv) {
List list=new ArrayList<>();
User user = new User();
user.setId(1);
user.setName("张三");
user.setAge(23);
user.setAddress("郑州");
User user1 = new User();
user1.setId(2);
user1.setName("李四");
user1.setAge(22);
user1.setAddress("上海");
User user2=new User();
user2.setId(3);
user2.setName("王五");
user2.setAge(24);
user2.setAddress("杭州");
list.add(user);
list.add(user1);
list.add(user2);
mv.addObject("list",list);
mv.setViewName("list2");
return mv;
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
Title
ID
Name
Age
Address
${user.id}
${user.name}
${user.age}
${user.address}
在之前我们讲的请求响应都是同步的,但是在实际开发中我们都是使用异步请求,所以下面我们使用ajax发送异步请求!
在异步请求中数据传输的格式我们都是使用josn来进行传输,速度快,小巧,使用方便!!
在响应的同时,我们也是响应json字符串,在前端解析json字符串即可!
1、发送ajax请求:$.ajax() / $.get() / $.post() / $.load()
2、响应json数据:new ObjectMapper().writeValueAsString()
我们学习完SpringMVC之后,就不用像之前那么麻烦了,还要创建ObjectMapper对象来转换成josn数据进行响应。
SpringMVC已经帮我们做这些事情了。SpringMVC提供了两个注解@RequestBody和@ResponseBody实现josn数据的转换
用于将controller方法返回的对象通过转换器转换为指定的格式(通常为json)之后,写入到response对象的响应体中。
把js文件放到webapp包下的js文件夹中,下面链接即为jquery-3.4.1的文件
链接:https://pan.baidu.com/s/1IFfhWAQs023LK-_9eu0tPw
提取码:ppdf
创建一个html页面,发送ajax异步请求,请求控制类获取数据
Title
name
age
控制类
@PostMapping("ajaxResponse")
@ResponseBody
public User ajaxTest(){
User user = new User();
user.setName("jack");
user.setAge(99);
return user;
}
用于接收前端请求体中的json数据,使用@RequestBody注解就可以自动的封装指定的对象中
Title
/**
* 接受json串
* @param user
*/
@PostMapping("ajaxRequest")
public void test(@RequestBody User user){
//User(name=jack, age=99)
System.out.println(user);
}
SpringMVC在默认情况下,所有的静态资源都会被拦截(js,css。html,图片、视频、音频),在web.xml文件中,我们配置的拦截路径是/
这种形式除了jsp都会被拦截。
springmvc
/
把拦截路径设置为 / 时,会发现连html静态页面都无法访问
对于静态资源,需要手动配置静态资源过滤。有三种形式可以选择:
springmvc
/
default
*.jpg
default
*.js
default
*.css
default
*.html
SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。开发者可以自己定义一些拦截器来实现特定的功能。
preHandle | 执行目标方法之前进行拦截; true 放行 false 拦截不放行 |
postHandle | 在目标方法执行之后,进行增强 |
afterCompletion | 在视图渲染完毕后,进行资源释放 |
自定义拦截器:使用自定义拦截器,SpringMVC提供了 HandlerInterceptor 接口。我们重写 preHandle
、postHandle
、afterCompletion
这三个方法!
创建一个interceptor包,在包中创建一个类去实现拦截器接口HandlerInterceptor
public class MyInterceptor implements HandlerInterceptor {
//方法执行之前进行拦截
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("执行方法前进行拦截1111111111");
//放行
return true;
}
//方法执行之后,进行增强
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("目标方法执行之后,进行增强1111111111");
}
//视图渲染完毕后,进行资源释放
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("在视图渲染完毕后,进行资源释放11111111111");
}
}
配置springmvc-config.xml文件
多个拦截器,拦截同一个目标资源,形成一个链条,就是拦截器链!
拦截方法的执行顺序:先进先出
拦截器的执行顺序
跟springmvc配置文件中的配置顺序有关系
mvc:interceptor 谁先配置谁先执行!
再创建一个类实现拦截器接口
public class MyInterceptor2 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("执行方法前进行拦截22222222222");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("目标方法执行之后,进行增强22222222");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("在视图渲染完毕后,进行资源释放222222222");
}
}
1、实现Filter接口
2、通过web.xml或注解方式完成配置
3、重写的方法 init doFilter destroy
4、过滤器过滤的是所有请求,不分controller和页面
1、实现HandlerInterceptor接口
2、需要在springmvc核心配置文件中配置3、重写的方法
preHandle 调用handler方法之前执行,true表示放行,false表示不放行
postHandle 调用handler方法之后执行
afterCompletion 视图渲染之后执行
4、只拦截controller请求
REST(英文:Representational State Transfer,简称REST,意思:表述性状态转换,描述了一个架构样式的网络系统,比如web应用)。
Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
应用场景:前后端分离开发的架构中
传统url
请求路径处理名字 表明 是做什么操作
请求路径时 也告 请求方式 (addUser + post) (deleteUserById + delete)
前端 | 后台 | 描述 |
---|---|---|
http://localhost:8080/user/findAllUsers | @RequestMapping(/user/findAllUsers) public List |
查询所有用户 |
http://localhost:8080/user/findUserById?id=1 | @RequestMapping(/user/findUserById) public User findUserById(int id) | 查询指定用户 |
http://localhost:8080/user/addUser | @RequestMapping(/user/addUser) public void addUser(User user) | 添加用户 |
http://localhost:8080/user/updateUser | @RequestMapping(/user/updateUser) public void updateUser(User user) | 修改用户 |
http://localhost:8080/user/deleteUserById?id=1 | @RequestMapping(/user/deleteUserById) public User deleteUserById(int id) | 删除用户 |
RESTfull风格
Restful风格的请求是使用==“url+请求方式”(名饲+动词)==表示一次请求目的的,HTTP 协议里面四个表示操作方式的动词如下:
请求方式 | 描述 |
---|---|
GET | 用于获取资源 |
POST | 用于新建资源 |
PUT | 用于更新资源 |
DELETE | 用于删除资源 |
前端 | 后台 | 描述 |
---|---|---|
http://localhost:8080/user/ | @RequestMapping(/user,method=GET) public List |
GET查询所有用户 |
http://localhost:8080/user/1 | @RequestMapping(/user/{id},method=GET) public User findUserById(@PathVariable int id) | GET查询id为1用户 |
http://localhost:8080/user/ | @RequestMapping(/user,method=POST) public void addUser(User user) | POST添加用户 |
http://localhost:8080/user/1 | @RequestMapping(/user/{id},method=PUT) public void updateUser(@PathVariable int id) | PUT修改id为1用户 |
http://localhost:8080/user/1 | @RequestMapping(/user/{id},method=DELETE) public User deleteUserById(@PathVariable int id) | DELETE删除id为1的用户 |
上述url地址/user/1中的1就是要获得的请求参数,在SpringMVC中可以使用占位符进行参数绑定。RequestMapping中/user/1可以写成/user/{id},占位符{id}对应的就是1的值。在业务方法中我们可以使用@PathVariable注解进行占位符的匹配获取工作。
@RequestMapping("user")
@RestController // @Controller + @ResponseBody
public class RestFulController {
/**
* 查询所有 get
*/
@GetMapping("users")
public String findAll(){
return "查询所有";
}
/**
* 指定查询 get
* @param id
* @return
*/
@GetMapping("users/{id}")
public String findUserByid(@PathVariable Integer id){
return "根据id进行查询,id为:"+id;
}
/**
* 添加用户 post
* @return
*/
@PostMapping("users")
public String addUser(){
return "添加用户";
}
/**
* 修改用户 put
* @return
*/
@PutMapping("users/{id}")
public String updateUser(@PathVariable Integer id){
return "修改用户,id为:"+id;
}
/**
* 删除用户 delete
*/
@DeleteMapping("users/{id}")
public String deleteUserById(@PathVariable("id") Integer id){
return "删除用户,id为:"+id;
}
}