一、Web开发
1.简单功能
1.1静态资源访问
(1)类路径下: /static或/public或/resources 或/META-INF/resources
(2)访问:更路径/+资源名
(3)原理:静态资源映射为/**:当请求发出后,会先去Controller寻找处理器,未找到时,会交给静态资源处理器处理,如果存在符合要求的静态资源,则返回,不存在,报404错误
(4)静态资源访问前缀设置:
spring:
mvc:
static-path-pattern: /res/**
(5)设置静态资源默认路径:
spring:
resources:
static-locations: classpath:/haha/
1.2欢迎页支持
(1)静态资源路径下:index.html
- 在设置静态资源访问前缀的情况下不生效
(2)controller可以处理index请求
2.rest使用原理
2.1rest风格支持
- 以前:/getUser 获取用户 /deleteUser 删除用户 /editUser 修改用户 /saveUser 保存用户
- 现在: /user GET-获取用户 DELETE-删除用户 PUT-修改用户 POST-保存用户
2.2核心filter:HiddenHttpMethodFilter
(1)用法:表单提交时,添加隐藏参数_method=,因为表单只支持GET,POST请求。
(2)隐藏参数名自定义配置:
package com.zj.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.HiddenHttpMethodFilter;
/**
* 概述:
* 作者:zhujie
* 创建时间:2021/11/16 15:23
*/
@Configuration
public class WebMVCConfig {
@Bean
public HiddenHttpMethodFilter hiddenHttpMethodFilter(){
HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter();
hiddenHttpMethodFilter.setMethodParam("myName");
return hiddenHttpMethodFilter;
}
}
(3)手动开启Filter配置:
spring:
mvc:
hiddenmethod:
filter:
enabled: true
二、请求处理原理
1.第一步:从处理器映射HandlerMapping获取Handler处理器
(1)SpringMVC功能分析都从 org.springframework.web.servlet.DispatcherServlet中的doDispatch()开始
(2)获取HandlerMapping处理器映射(5种处理器映射):
- RequestMappingHandlerMapping:保存了所有@RequestMapping和Handler的映射规则
- BeanNameUrlHandlerMapping
- RouterFunctionMapping
- SimpleUrlHandlerMapping
- WelcomePageHandlerMapping
(3)最终获取到处理请求的Handler处理器
2.第二步:获取Handler处理器的适配器HandlerAdapter
(1)根据处理器适配器遍历匹配Handler处理器(4种处理器适配器)
(2)获取最终的HandlerAdapter处理器适配器
(3)处理器适配器HandlerAdapter真正执行处理器Handler
3.第三步:参数解析器HandlerMethodArgumentResolver解析参数
3.1基本注解获取参数
(1)@PathVariable:获取路径变量
(2)@RequestHeader:获取请求头
(3)@RequestAttribute:获取request域中的值
(4)@RequestParam:获取请求参数
(5)@CookieValue:获取cookie的值
(6)@RequestBody:获取请求体的值
(7)@MatrixVariable:获取矩阵变量,该注解需要SpringBoot手动开启矩阵变量功能:
/**
* 概述:配置类实现WebMvcConfigurer接口,重写configurePathMatch方法开启矩阵变量
*/
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
UrlPathHelper urlPathHelper = new UrlPathHelper();
urlPathHelper.setRemoveSemicolonContent(false);
configurer.setUrlPathHelper(urlPathHelper);
}
3.2参数解析
(1)处理器适配器HandlerAdapter执行处理器Handler,会进行参数解析(参数解析器HandlerMethodArgumentResolver:26种):
(2)先判断是否存在可以解析该参数的解析器
(3)找到该参数的参数解析器后,解析参数
(4)然后根据参数解析器的不同,去调用不同参数解析器的参数解析方法,解析参数后,执行目标方法,获取到返回值
4.第四步:获取返回值后,调用返回值处理器处理返回值
(1)调用方法准备处理返回值
(2)查找适配返回值的返回值处理器(15种):
(3)处理器处理返回值,底层调用消息转换器的方法
(4)消息转换器处理返回值数据,(消息转换器MessageConveter有10种)
5.第五步:返回值处理完成后,获得ModelAndView对象
(1)调用processDispatchResult()方法
(2)渲染视图
(3)使用视图解析器解析视图,获取View对象
三、拦截器
1.拦截器使用
- 编写拦截器,实现HandlerIntercptor接口
package com.zj.interceptor;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 概述:
* 作者:zhujie
* 创建时间:2021/11/19 9:49
*/
public class InterceptorDemo implements HandlerInterceptor {
/**
* 概述:在目标方法前执行
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object loginUser = request.getSession().getAttribute("loginUser");
if (StringUtils.isEmpty(loginUser)){
return false;
}
return true;
}
/**
* 概述:在目标方法后执行
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
/**
* 概述:在目标方法返回结果后执行
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
- 注册拦截器,创建配置类实现WebMvcConfigurer接口,实现addInterceptors方法
package com.zj.config;
import com.zj.interceptor.InterceptorDemo;
import com.zj.po.Pet;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.filter.HiddenHttpMethodFilter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.util.UrlPathHelper;
/**
* 概述:
* 作者:zhujie
* 创建时间:2021/11/16 15:23
*/
@Configuration
public class WebMVCConfig implements WebMvcConfigurer {
/**
* 概述:开启矩阵变量
*/
@Bean
public HiddenHttpMethodFilter hiddenHttpMethodFilter(){
HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter();
hiddenHttpMethodFilter.setMethodParam("myName");
return hiddenHttpMethodFilter;
}
/**
* 概述:开启矩阵变量
*/
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
UrlPathHelper urlPathHelper = new UrlPathHelper();
urlPathHelper.setRemoveSemicolonContent(false);
configurer.setUrlPathHelper(urlPathHelper);
}
/**
* 概述:拦截器注册
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new InterceptorDemo())
.addPathPatterns("/**")//设置拦截路径
.excludePathPatterns("/","/login");//设置放行路径
}
}
2.拦截器原理
(1) 根据当前请求找到Handler以及所有拦截器
(2)执行目标方法之前,执行拦截器preHandle方法
(3)顺序执行拦截器链中拦截器的preHandle方法,如果当前拦截器的preHandle方法返回true,则执行下一个拦截器的preHandle方法;如果返回false,直接倒序执行已执行preHandle方法的拦截器的afterCompletion方法,并且有任何一个拦截器返回false,直接跳出不执行目标方法。
(4)目标方法执行完成之后,倒序执行拦截器链中的postHandle方法
(5)页面渲染完成之后倒序执行afterCompletion方法,并且以上所有步骤出现异常,已经执行成功的拦截器都会立即倒序执行afterCompletion
四、文件上传原理
1.文件上传自动配置
(1)自动配置类:MultipartAutoConfiguration
(2)文件上传解析器:StandardServletMultipartResolver
2.文件上传原理步骤
(1)使用文件上传解析器判断(isMultipart方法判断)请求是否为文件上传请求,并封装文件上传请求(封装为StandardMultipartHttpServletRequest)
(2)使用参数解析器RequestPartMethodArgumentResolver解析参数
五、Web原生组件注入(Servlet,Filter,Listener)
第一种方式:在启动类上添加@ServletComponentScan注解
(1)创建Servlet类继承HttpServlet类,并在类上添加注解@WebServlet
(2)创建Filter类实现Filter接口,并在类上添加@WebFilter注解
(2)创建Listener类实现Listener相关接口,并在类上添加@WebListener注解
第二种方式:创建配置类,注册ServletRegistrationBean,FilterRegistrationBean,ServletListenerRegistrationBean组件形式
package com.zj.config;
import com.zj.filter.MyFilter;
import com.zj.listener.MyListener;
import com.zj.servlet.MyServlet;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Arrays;
/**
* 概述:
* 作者:zhujie
* 创建时间:2021/11/19 14:35
*/
@Configuration
public class MyRegistConfig {
@Bean
public ServletRegistrationBean servletRegistrationBean(){
return new ServletRegistrationBean(new MyServlet(),"/servlet");
}
@Bean
public FilterRegistrationBean filterRegistrationBean(){
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new MyFilter());
filterRegistrationBean.setUrlPatterns(Arrays.asList("/user"));
return filterRegistrationBean;
}
@Bean
public ServletListenerRegistrationBean servletListenerRegistrationBean(){
return new ServletListenerRegistrationBean(new MyListener());
}
}