SpringMVC
-
MVC是一种架构模式(软件架构设计思想)
-
- M:Model(模型)负责业务处理及数据的收集
- V:View(视图)负责数据的展示
- C:Controller(控制器)它是一个调度中心,负责调度Model和View
-
MVC将一个应用分为三块,优点:
- 低耦合,代码复用性强,可维护性强
- 高内聚,让程序员更加专注于业务开发
-
MVC 和三层模型都采用了分层结构来设计应用程序,都是降低耦合度,提高扩展力,提高组件复用性。区别在于:他们的关注点不同,三层模型更加关注业务逻辑组件的划分。
MVC架构模式关注的是整个应用程序的层次关系和分离思想。现代的开发方式大部分都是MVC架构模式结合三层模型一起用。 -
SpringMVC:
-
SpringMVC是一个实现了MVC架构模式的Web框架,底层基于Servlet实现。
-
SpringMVC帮我们做了什么:
- 入口控制:SpringMVC框架通过DispatcherServlet作为入口控制器,负责接收请求和分发请求。而在Servlet开发中,需要自己编写Servlet程序,并在web.xml中进行配置,才能接受和处理请求。
- 在SpringMVC中,表单提交时可以自动将表单数据绑定到相应的JavaBean对象中,只需要在控制器方法的参数列表中声明该JavaBean对象即可,无需手动获取和赋值表单数据。而在纯粹的Servlet开发中,这些都是需要自己手动完成的。
- IoC容器:SpringMVC框架通过IoC容器管理对象,只需要在配置文件中进行相应的配置即可获取实例对象,而在Servlet开发中需要手动创建对象实例。
- 统一处理请求:SpringMVC框架提供了拦截器、异常处理器等统一处理请求的机制,并且可以灵活地配置这些处理器。而在Servlet开发中,需要自行编写过滤器、异常处理器等,增加了代码的复杂度和开发难度。
- 视图解析:SpringMVC框架提供了多种视图模板,如JSP、Freemarker、Velocity等,并且支持国际化、主题等特性。而在Servlet开发中需要手动处理视图层,增加了代码的复杂度。
-
-
RequestMapping:
-
@RequestMapping
注解是 Spring MVC 框架中的一个控制器映射注解,用于将请求映射到相应的处理方法上。具体来说,它可以将指定 URL 的请求绑定到一个特定的方法或类上,从而实现对请求的处理和响应。 -
普通的请求路径:http://localhost:8080/springmvc/login?username=admin&password=123&age=20
RESTful风格的请求路径:http://localhost:8080/springmvc/login/admin/123/20 -
普通请求风格:/login?id=xxx&username=xxx&password=xxx
-
@RequestMapping(value="/login") public String testRESTful( @RequestParam("id") int id, @RequestParam("username") String username, @Requestv("age") int age){ System.out.println(id + "," + username + "," + age); return "testRESTful"; }
-
@RequestParam 这个注解是可以省略的,如果方法形参的名字和提交数据时的name相同,则 @RequestParam 可以省略。
-
-
如果使用RESTful风格的请求路径,在控制器中应该如何获取请求中的数据呢?可以在value属性中使用占位符,例如:/login/{id}/{username}/{password}
-
@RequestMapping(value="/testRESTful/{id}/{username}/{age}") public String testRESTful( @PathVariable("id") int id, @PathVariable("username") String username, @PathVariable("age") int age){ System.out.println(id + "," + username + "," + age); return "testRESTful"; }
-
-
@RequestMapping衍生注解
-
在SpringMVC中不仅提供了 PostMaping注解,像这样的注解还有四个,包括:
- GetMapping:要求前端必须发送get请求
- PutMapping:要求前端必须发送put请求
- DeleteMapping:要求前端必须发送delete请求
- PatchMapping:要求前端必须发送patch请求
-
前后端请求方式不一致会爆405错误
-
-
params属性的用法;
-
@RequestMapping(value=“/login”, params={“username”, “password”}) 表示:请求参数中必须包含 username 和 password,才能与当前标注的方法进行映射。
@RequestMapping(value=“/login”, params={“!username”, “password”}) 表示:请求参数中不能包含username参数,但必须包含password参数,才能与当前标注的方法进行映射。
@RequestMapping(value=“/login”, params={“username=admin”, “password”}) 表示:请求参数中必须包含username参数,并且参数的值必须是admin,另外也必须包含password参数,才能与当前标注的方法进行映射。
@RequestMapping(value=“/login”, params={“username!=admin”, “password”}) 表示:请求参数中必须包含username参数,但参数的值不能是admin,另外也必须包含password参数,才能与当前标注的方法进行映射。注意:如果前端提交的参数,和后端要求的请求参数不一致,则出现400错误!!!
HTTP状态码400的原因:请求参数格式不正确而导致的。
-
-
使用pojo类来接收请求参数:
- 当提交的数据非常多时,方法的形参个数会非常多,这不是很好的设计。在SpringMVC中也可以使用POJO类/JavaBean来接收请求参数。不过有一个非常重要的要求:
POJO类的属性名
必须和请求参数的参数名
保持一致 - 底层的实现原理:反射机制。先获取请求参数的名字,因为请求参数的名字就是JavaBean的属性名,通过这种方式给对应的属性赋值。
- 可见请求参数是否可以赋值到JavaBean对应的属性上,不是取决于属性名,而是setter方法名。
- 当提交的数据非常多时,方法的形参个数会非常多,这不是很好的设计。在SpringMVC中也可以使用POJO类/JavaBean来接收请求参数。不过有一个非常重要的要求:
-
@RequestHeader:和@RequestParam功能相似,将请求头信息映射到方法的形参上
-
@CookieValue:功能都类似,将请求的cookie数据映射到方法形参上
-
-
Restful编程风格:
-
RESTFul定义了一组约束条件和规范,可以让
WEB服务接口
更加简洁、易于理解、易于扩展、安全可靠。 -
REST对请求方式的约束是这样的:
- 查询必须发送GET请求
- 新增必须发送POST请求
- 修改必须发送PUT请求
- 删除必须发送DELETE请求
REST对URL的约束是这样的:
-
传统的URL:get请求,/springmvc/getUserById?id=1
-
REST风格的URL:get请求,/springmvc/user/1
-
传统的URL:get请求,/springmvc/deleteUserById?id=1
-
REST风格的URL:delete请求, /springmvc/user/1
-
RESTFul对URL的约束和规范的核心是:通过采用
**不同的请求方式**
**+ ****URL**
来确定WEB服务中的资源。RESTful 的英文全称是 Representational State Transfer(表述性状态转移)。简称REST。
表述性(Representational)是:URI + 请求方式。
状态(State)是:服务器端的数据。
转移(Transfer)是:变化。
表述性状态转移是指:通过 URI + 请求方式 来控制服务器端数据的变化。
-
-
HttpMessageConventer:转换的是
HTTP协议
与Java程序中的对象
之间的互相转换 -
@ReponseBody:
- return语句返回的字符串则不再是“逻辑视图名”了, 而是作为响应协议的响应体进行响应。
-
@RequestBody:
- 这个注解的作用是直接将请求体传递给Java程序,在Java程序中可以直接使用一个String类型的变量接收这个请求体的内容。
-
异常处理器:
-
@ControllerAdvice public class ExceptionController { @ExceptionHandler public String tip(Exception e, Model model){ model.addAttribute("e", e); return "tip"; } }
-
-
拦截器:
-
拦截器和过滤器的区别在于它们的作用层面不同。
- 过滤器更注重在请求和响应的流程中进行处理,可以修改请求和响应的内容,例如设置编码和字符集、请求头、状态码等。
- 拦截器则更加侧重于对控制器进行前置或后置处理,在请求到达控制器之前或之后进行特定的操作,例如打印日志、权限验证等。
-
定义拦截器:
-
实现
org.springframework.web.servlet.HandlerInterceptor
接口,共有三个方法可以进行选择性的实现:- preHandle:处理器方法调用之前执行
- 只有该方法有返回值,返回值是布尔类型,true放行,false拦截。
- postHandle:处理器方法调用之后执行
- afterCompletion:渲染完成后执行
- preHandle:处理器方法调用之前执行
-
-
在springmvc.xml中注册拦截器
-
加@Component
-
-
源码解读:
…
,true放行,false拦截。**
- postHandle:处理器方法调用之后执行
- afterCompletion:渲染完成后执行