一. SpringMVC
1. 相关概念
mvc 模式
springmvc 原理
- 用户发送请求到前端控制器,即 DispatcherServlet
- DispatcherServlet 收到请求调用 HandlerMapping 处理器映射器
- HandlerMapping 将处理器对象及处理器拦截器返回给 DispatcherServlet
- DispatcherServlet 调用 HandlerAdapter 处理器适配器
- HandlerAdapter 经过适配调用具体的处理器
- Controller 执行完成返回 ModelAndView
- HandlerAdapter 将 ModelAndView 返回给 DispatcherServlet
- DispatcherServlet 将 ModelAndView 传给 ViewReslover 视图解析器
- ViewReslover 解析后返回具体 View
- DispatcherServlet 根据 View 进行渲染视图
- DispatcherServlet 响应用户
springmvc 九大组件
关于 Handler:
@RequestMapping 标注的所有方法都可以看成是一个Handler,只要可以实际处理请求就可以是Handler
public class DispatcherServlet extends FrameworkServlet {
...
/*multipartResolver:
用于处理上传请求,将普通request包装成MultipartHttpServletRequest,
MultipartHttpServletRequest可以直接调用getFile方法获取File,
如果上传多个文件,还可以调用getFileMap得到FileName->File结构的Map
multipartResolver有三个方法:
判断是不是上传请求;
将request包装成MultipartHttpServletRequest;
处理完后清理上传过程中产生的临时资源。
*/
@Nullable
private MultipartResolver multipartResolver;
/*localeResolver:
用于从request解析出Locale
Locale就是如zh-CN、en-US之类,表示一个区域,有了这个就可以对不同区域的用户显示不同的结果
用处:
一是ViewResolver视图解析的时候;
二是用到国际化资源或者主题的时候
*/
@Nullable
private LocaleResolver localeResolver;
/*themeResolver:
用于解析主题,SpringMVC中一个主题对应一个properties文件
里面存放着跟当前主题相关的所有资源、如图片、css样式等
要得到一个主题的资源,首先要得到资源的名称,这就是themeResolver的工作
*/
@Nullable
private ThemeResolver themeResolver;
/*handlerMappings:
是用来查找对应Handler,每个请求都需要一个Handler处理
handlerMappings来判断具体接收到一个请求之后,使用哪个Handler进行处理
*/
@Nullable
private List<HandlerMapping> handlerMappings;
/*handlerAdapters:
SpringMVC中以Handler处理请求,可以是任意的形式
Servlet需要的处理方法的结构是固定的,都是以request和response为参数的方法
handlerAdapters把Handler与Servlet进行了适配
*/
@Nullable
private List<HandlerAdapter> handlerAdapters;
/*handlerExceptionResolvers:
对异常情况进行处理
再根据异常设置ModelAndView,之后再交给render方法进行渲染
*/
@Nullable
private List<HandlerExceptionResolver> handlerExceptionResolvers;
/*viewNameTranslator:
有的Handler处理完后并没有设置View也没有设置ViewName,这时就需要从request获取ViewName了
RequestToViewNameTranslator在一个Translator里面实现了所有request到ViewName的转换规则
*/
@Nullable
private RequestToViewNameTranslator viewNameTranslator;
/*flashMapManager:
用来管理FlashMap的,FlashMap主要用在redirect中传递参数
*/
@Nullable
private FlashMapManager flashMapManager;
@Nullable
private List<ViewResolver> viewResolvers;
...
2. DispatcherServlet(前端控制器)
DispatcherServlet 拦截所有 web 请求并进行匹配、转发、数据处理
在 web.xml 中配置 DispatcherServlet 等,完整版 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name>Archetype Created Web Application</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!--SpringMVC的相关配置,目的:把表现层交给SpringMVC管理-->
<!--SpringMVC-配置前端控制器-->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--加载dispatcher-servlet.xml配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:dispatcher-servlet.xml</param-value>
</init-param>
<!--启动服务器时创建该servlet,值越小优先级越高-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--配置监听器把applicationContext.xml加入到配置文件中-->
<!--ContextLoadListener默认只加载WEB-INF目录下的配置文件,所以要设置一个路径参数传入-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--设置路径参数-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--配置解决中文乱码的过滤器,且一定要放在所有过滤器之前-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!--解决post请求乱码-->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<!--解决响应乱码-->
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
加载指定的初始化配置文件 dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--此文件负责整个SpringMVC的核心配置-->
<!--开启注解扫描,负责表现层controller-->
<context:component-scan base-package="com.codfish">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 模型视图解析器,即在模型视图名称添加前后缀(如果最后一个还是文件夹,则最后的斜杠不要漏了) 使用JSP-->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/><!--前缀,即JSP文件的目录位置-->
<property name="suffix" value=".jsp"/><!--后缀-->
</bean>
<!--静态资源映射-->
<!--本项目把静态资源放在了webapp的statics目录下,资源映射如下-->
<mvc:resources mapping="/css/**" location="/statics/css/"/>
<mvc:resources mapping="/js/**" location="/statics/js/"/>
<mvc:resources mapping="/image/**" location="/statics/images/"/>
<mvc:default-servlet-handler/> <!--这句要加上,要不然可能会访问不到静态资源,具体作用自行百度-->
<!--开启SpringMVC注解的支持,可以将request参数与绑定到controller参数上 -->
<mvc:annotation-driven/>
</beans>
二. Springboot 中的 SpringMVC
1. @RequestMapping 注解
源码:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
String name() default "";
@AliasFor("path")
String[] value() default {};
@AliasFor("value")
String[] path() default {};
RequestMethod[] method() default {};
String[] params() default {};
String[] headers() default {};
String[] consumes() default {};
String[] produces() default {};
}
- method:指定HTTP协议中的请求方式,如GET、POST(PUT、DELETE)等,指定后如果不按规定的请求方式请求会报错,不指定则接收任何方式的请求
@RequestMapping(method = RequestMethod.POST)
@GetMaping //相当于@RequestMapping(method = RequestMethod.GET)
@PostMaping //相当于@RequestMapping(method = RequestMethod.POST)
@PutMapping //相当于@RequestMapping(method = RequestMethod.PUT)
@DeleteMapping //相当于@RequestMapping(method = RequestMethod.DELETE)
- params:请求时必须(不)包含指定的一个或多个参数以及对应参数值,否则报错
@RequestMapping(params = {"username", "age!=28"})
- headers:请求时必须包含指定的header(请求头)中的值,否则报错
@RequestMapping(headers = {"User-Agent = Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:80.0) Gecko/20100101 Firefox/80.0"})
- consumes:指定请求时的 Content-Type ,如 text/html
@RequestMapping(consumes = "text/html")
- produces:指定响应的 Content-Type,请求头中的 Accept 中必须包含该类型才能返回
@RequestMapping(produces = "application/json;charset=utf-8")
- value:指定请求的实际地址
@RequestMapping(value = "/project")
可搭配 ANT 风格实现 URL 的模糊匹配
通配符 | 说明 |
---|---|
? | 匹配任意单个字符 |
* | 匹配0或多个任意字符 |
** | 匹配0或多层目录 |
2. REST (REpresentational State Transfer)
核心思想:URL 用名词定位资源,用 HTTP动词 描述操作
- GET:获取资源
- POST:新建资源
- PUT:更新资源
- DELETE:删除资源
目的:
- 看 url 就知道要什么
- 看 http method 就知道干什么
- 看 http status code 就知道结果如何
3. @RequestParam 和 @RequestBody(获取前端请求的数据)
源码:
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
@AliasFor("name")
String value() default "";
@AliasFor("value")
String name() default "";
boolean required() default true;
String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
}
- value:请求参数名,即后台获取 .html 中设置的变量名(必须配置)
- required:请求中必须包含该参数,默认为 true,如果没包含则会抛出异常(可选配置)
- defaultValue:为获取的参数赋默认值,设置后无论是否配置了 required ,都自动设为 false(可选配置)
Thymeleaf(Springboot 推荐的视图解析器)
要使用 Thymeleaf 语法必须引入空间名称
<html lang="en" xmlns:th="http://www.thymeleaf.org"></html>
IDEA 中通过 Thymeleaf 语法读取变量时爆红色波浪线问题
在 Thymeleaf 模板引擎下的error文件夹里可以定制错误信息面页
4. Model(回显数据)
常规绑定数据的方式,给handle方法传入Map、Model、ModelMap参数
- Map:JDK提供的接口
- Model:Spring提供的接口,最常用
- ModelMap:Map接口下的一个类
三种方式最终都是实现了 BindingAwareModelMap
- 使用SpringMVC的 ModelAndView 对象也可以给面页传递数据
以上四种方式,返回的数据都在 request域 中
//方式一
@RequestMapping("/echo")
public String echo(Model model){
model.addAttribute("message", "回显的信息");
return "echopage";
}
//方式二
@RequestMapping("/echo")
public String echo(ModelMap modelMap){
modelMap.addAttribute("message", "回显的信息");
return "echopage";
}
//方式三
@RequestMapping("/echo")
public String echo(Map<String, Object> map){
map.put("message", "回显的信息");
return "echopage";
}
//方式四
@RequestMapping("/echo")
public ModelAndView echo(){
ModelAndView mav = new ModelAndView("echopage");
mav.addObject("massage", "回显的信息");
return mav;
}
@ModelAttribute 该注解已淘汰