SpringBoot 页面请求处理的源码入门

静态/动态资源访问

优先找动态资源,再找静态资源

静态资源访问前缀

	spring:
		mvc:
			#这个是静态资源访问的前缀,所有需要访问的前缀都需要拼这个才能访问
			static-path-pattern: /res/**
		resources:
			#这个是静态资源的规定文件夹,配置后只有该文件夹下才能被访问
			static-location: classpath:/res/

欢迎页支持

  • 方式一: 建一个index.html
  • 方式二: 建一个@RequestMapping(“index”) return “/xxx”;

ICON支持

在静态资源文件夹下,放入favicon.ico就可以有图标

静态资源配置原理

  • SpringMVC自动配置类WebMvcAutoConfiguration,生效

1、一个配置类(@Configration修饰的类)只有一个有参构造器时,那么所有参数都会从容器中确定

WebMvcAutoConfiguration.class

// 相当于给WebMvc自动装载的适配器从IOC中获取资源

// WebProperties 获取和spring.resources绑定的所以的值的对象
// WebMvcProperties 绑定了spring.mvc的所有的值的对象
// ListableBeanFactory Spring的bean工厂
// HttpMessageConverters 参数处理器
// ResourceHandlerRegistrationCustomizer 资源处理器的自定义器
// DispatcherServletPath DispatcherServlet 路径
// ServletRegistrationBean 给应用注册的 Servlet Filter

public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties,
				WebMvcProperties mvcProperties, ListableBeanFactory beanFactory,
				@Lazy HttpMessageConverters messageConverters,
				ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider) {
			this.resourceProperties = resourceProperties;
			this.mvcProperties = mvcProperties;
			this.beanFactory = beanFactory;
			this.messageConverters = messageConverters;
			this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider
					.getIfAvailable();
		}

2、静态资源能够生效的真正原因

@Override
	protected void addResourceHandlers(ResourceHandlerRegistry registry) {
		super.addResourceHandlers(registry);
		/** 这里第一个IF 判断IOC(配置文件中可配置,默认为true)中
		 		spring.web.add-mapping :true/false
				true:允许使用静态资源
				false:禁用静态资源,所有的静态页,图片全部404
		**/
		if (!this.resourceProperties.isAddMappings()) {
			logger.debug("Default resource handling disabled");
			return;
		}
		ServletContext servletContext = getServletContext();
		/**
		两个addResourceHanlder 就是增加两个静态资源处理器
		第一个addRe……说的是给IOC注册webjars/**等两个路径的静态资源
		第二个addRe……说的是给spring.mvc.staticPathPattern配置的静态资源
		新版默认值为/**,可以.properties或.yml配置 【图1】
		**/
		addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
		addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
			registration.addResourceLocations(this.resourceProperties.getStaticLocations());
			if (servletContext != null) {
				registration.addResourceLocations(new ServletContextResource(servletContext, SERVLET_LOCATION));
			}
		});
	}

图1
![图1](https://img-blog.csdnimg.cn/2021021916334553.png

3、欢迎页的原理

@Bean
		public WelcomePageHandlerMapping welcomePageHandlerMapping(
				ApplicationContext applicationContext) {
			return new WelcomePageHandlerMapping(
					new TemplateAvailabilityProviders(applicationContext),
					applicationContext, getWelcomePage(),
					this.mvcProperties.getStaticPathPattern());
		}

//进入new WelcomePageHandlerMapping

WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders,
			ApplicationContext applicationContext, Optional<Resource> welcomePage,
			String staticPathPattern) {
		//第一个if判断,是否存在欢迎页,如果存在就转发到index.html中
		if (welcomePage.isPresent() && "/**".equals(staticPathPattern)) {
			logger.info("Adding welcome page: " + welcomePage.get());
			setRootViewName("forward:index.html");
		}
		//第一个if失败的话,就去寻找是否有处理器能够处理index请求,如果有,就请求index方法
		else if (welcomeTemplateExists(templateAvailabilityProviders,
				applicationContext)) {
			logger.info("Adding welcome page template: index");
			setRootViewName("index");
		}
	}

【源码分析】Rest请求处理原理

WebMvcAutoConfiguration中
OrderedHiddenHttpMethodFilter
继承HiddenHttpMethodFilter

在这里插入图片描述
如果是表单访问PUT或者DELETE方法时
需要
1、表单需要是POST方式
2、需要配置一个隐藏域
<input type="hidden" name = "_method" value = "PUT"> 声明配置一下,因为源码中

原因如下:
在这里插入图片描述
在这里插入图片描述
如果不想要_method,自定义的话:
需要自己写一个配置类@Configuration,并且再其中@Bean一个方法,在方法中重新set一下HiddenHttpMethodFilter中的methodParam

@Bean
public HiddenHttpMethodFilter hiddenHttpMethodFilter(){
	HiddenHttpMethodFilter filter = new ……;
	filter.setMethodParam("自定义的name名");
	return filter;
}

【源码分析】请求映射原理

在WebMvcAutoConfiguration发现,底层是SpringMVC的DispatchServlet。

DispatchServlet的底层其实也是一个HttpServlert
在这里插入图片描述

其中FramworkSerlet重写了doGet doPost等方法
并且他们的核心方法都用了processRequest->doService在这里插入图片描述在这里插入图片描述

而doSerivce是由DispatchServlet实现的
其核心又是用了一个doDispatch方法
而doDispatch方法中:

  • 1、先获取了HandlerMapping 返回了多个HandlerMapping组成执行链HanlerExecutionChain
  • 2、其中最核心的是RequestHandlerMapping:它能够找到对应的@Request注解和对应Controller对应方法的关联关系
  • 3、根据HandlerAdapter关联关系去匹配当前请求的url的对应方法
  • 4、返回对应的Controller里的对应方法去处理
    在这里插入图片描述
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值