Springboot配置文件与web开发

参考博客:

https://mp.weixin.qq.com/s?__biz=MzI4Njc5NjM1NQ==&mid=2247488811&idx=2&sn=0d054027651bef114ae6bec5a8f62359 >SpringBoot内容聚合

https://zhuanlan.zhihu.com/p/57693064 >SpringBoot配置文件详解


配置文件

当我们构建完Spring Boot项目后,会在resources目录下给我们一个默认的全局配置文件;

application.properties,这是一个空文件,因为Spring Boot在底层已经把配置都给我们自动配置好了,当在配置文件进行配置时,会修改SpringBoot自动配置的默认值。

配置文件名是固定的:application.properties,但我们可以修改为:application.yml

这两个文件本质是一样的,区别只是其中的语法略微不同。

值的写法

application.properties 配置文件比较简单,形式如下

key = value

application.yml 配置文件使用YMAL语言,YMAL不是如XML般的标记语言,更适合作为配置文件。

数字,字符串,布尔

  1. 直接写

name=zhangsan

  1. 双引号

不会转义字符串里面的特殊字符,特殊字符会作为本身想表示的意思

name: "zhangsan n lisi"

输出:

zhangsan
lisi
  1. 单引号

会转义特殊字符,特殊字符最终只是一个普通的字符串数据

name: ‘zhangsan n lisi’

输出:

zhangsan n lisi

对象、Map(属性和值)(键值对)

例如配置类中的字段为

Map<String,String> maps;

在yml配置文件中,行内写法

person.maps: {key1: value1,key2: value2}

需要注意:号后的空格,或者

person:
  maps:
   key: value

在properties配置文件中

person.maps.key=value

数组(List、Set)

在yml配置文件中

person:
 list:
 - 1
 - 2
 - 3

行内写法

person:
  list: [1,2,3]

在properties配置文件中

person.list[0]=1
person.list[1]=2
person.list[2]=3

自定义配置属性

Spring Boot提供自定义配置组件,拿前面举例的属性来写一个规范的配置文件

@Component // 或者@Configuration
@ConfigurationProperties(prefix = "person")
public class Person {
	private Map<String,String> maps;
	private List<String> list;
	private String name;

	public Map<String, String> getMaps() {
		return maps;
	}

	public void setMaps(Map<String, String> maps) {
		this.maps = maps;
	}

	public List<String> getList() {
		return list;
	}

	public void setList(List<String> list) {
		this.list = list;
	}
 
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

@ConfigurationProperties 注解向Spring Boot声明该类中的所有属性和配置文件中相关的配置进行绑定。

prefix = “person”:声明配置前戳,将该前戳下的所有属性进行映射。
@Component 或者@Configuration:将该组件加入Spring Boot容器,只有这个组件是容器中的组件,配置才生效。

配置自动提示

在配置自定义属性时,如果想要获得和配置Spring Boot属性自动提示一样的功能,则需要加入下面的依赖:

<!--导入配置文件处理器,配置文件进行绑定就会有提示-->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-configuration-processor</artifactId>
	<optional>true</optional>
</dependency>

若是依旧无法自动提示,可以尝试开启IDE的Annonation Processing
在这里插入图片描述

开发Web应用程序

Spring Boot 适合于 Web 应用程序开发。可以使用嵌入式Tomcat,Jetty,Undertow 或 Netty 创建独立的 HTTP 服务器。大多数 Web 应用程序都使用 spring-boot-starter-web 来快速启动和运行。还可以选择使用spring-boot-starter-webflux来构建响应式Web应用程序。

静态资源

默认情况下,Spring Boot从类路径中名为/static(/public或/resources或/META-INF/resources)的目录中或从的根中提供静态内容ServletContext。使用ResourceHttpRequestHandler读取文件。可以通过添加自己WebMvcConfigureraddResourceHandlers方法并覆盖该方法来修改该行为。

默认情况下,资源映射到 / * * ,可以使用 spring.mvc.static-path-pattern属性对其进行调整。例如,将所有资源重新定位到以下位置 / resources / * * 可以实现:

spring.mvc.static-path-pattern=/resources/**

路径中名为/static(/public或/resources或/META-INF/resources)可以访问。

路径优先级排序:/META-INF/resources > /resources > /static > /public

欢迎页支持

url输入,会先将输入的信息定义为字符串,去controller寻找。没有找到后再去静态资源目录下寻找。

静态资源路径下index.html

  • 可以配置静态资源路径
  • 但是不可以配置静态资源的访问前缀。否则导致 index.html不能被默认访问
spring:
  mvc:
    static-path-pattern: /res/**   这个会导致welcome page功能失效

  resources:
    static-locations: [classpath:/haha/]
  • controller能处理/index

自定义 Favicon.ico

介绍
这里指的favicon是指在这里插入图片描述(就是在 页面搜索栏和最上面标头显示图标)

步骤:

  1. 百度favicon制作所需要的favicon
  2. 将制作的favicon放置于项目中,有两个可放位置:resource/resource/static/,static下的优先级高于resource
<link href="/facicon.ico" />

静态资源配置原理

https://blog.csdn.net/MrYushiwen/article/details/112478441 >SpringBoot静态资源配置原理

WebMvcAutoConfigurationAdapter静态内部类

一.配置文件前缀
WebMvcAutoConfiguration类中的WebMvcAutoConfigurationAdapter静态内部类:
在这里插入图片描述
这是一个配置类,配置文件的属性和xxx进行了绑定。
再看@EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class, WebProperties.class})
我们来看当中的WebMvcProperties、ResourceProperties和WebProperties的字节码文件
分别点进这三个类的字节码文件中:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以看到WebMvcProperties它是与配置文件前缀spring.mvc相关联的。
ResourceProperties它是与配置文件前缀spring.resources相关联。
WebProperties它是与配置文件前缀spring.web相关联。

二.只有一个有参构造器

WebMvcAutoConfigurationAdapter静态内部配置类只有一个有参数的构造器,那它会带来什么特性呢?

它的有参构造器中所有参数的值都会从容器中确定

    //有参构造器所有参数的值都会从容器中确定
//ResourceProperties resourceProperties;获取和spring.resources绑定的所有的值的对象
//WebMvcProperties mvcProperties 获取和spring.mvc绑定的所有的值的对象
//ListableBeanFactory beanFactory Spring的beanFactory
//HttpMessageConverters 找到所有的HttpMessageConverters
//ResourceHandlerRegistrationCustomizer 找到 资源处理器的自定义器。=========
//DispatcherServletPath  
//ServletRegistrationBean   给应用注册Servlet、Filter....
    public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties, WebMvcProperties mvcProperties,
                ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider,
                ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider,
                ObjectProvider<DispatcherServletPath> dispatcherServletPath,
                ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) {
            this.resourceProperties = resourceProperties;
            this.mvcProperties = mvcProperties;
            this.beanFactory = beanFactory;
            this.messageConvertersProvider = messageConvertersProvider;
            this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
            this.dispatcherServletPath = dispatcherServletPath;
            this.servletRegistrations = servletRegistrations;
        }
  • 第一个参数是ResourceProperties resourceProperties 就是上面提到的@EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class, WebProperties.class})中注册开启的第二个类,获取和spring.resources绑定的所有的值的对象
  • 第二个参数是WebProperties webProperties 就是上面提到的@EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class, WebProperties.class})中注册开启的第三个类,获取和spring.web绑定的所有的值的对象
  • 第三个参数是WebMvcProperties mvcProperties 就是上面提到的@EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class, WebProperties.class})中注册开启的第一个类,获取和spring.mvc绑定的所有的值的对象
  • 第四个参数是ListableBeanFactory beanFactory ,这个是Spring的beanFactory,也就是我们的容器。
  • 第五个参数是ObjectProvider messageConvertersProvider,找到所有的HttpMessageConverters
  • 第六个参数是ObjectProvider<WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider,找到资源处理器的自定义器
  • 第七个参数是ObjectProvider dispatcherServletPath,相当与找dispatcherServlet能处理的路径
  • 第八个参数是ObjectProvider<ServletRegistrationBean<?>> servletRegistrations ,给应用注册原生的Servlet、Filter等等

三.addResourceHandlers方法

所有的资源处理默认规则都在addResourceHandlers方法中

public void addResourceHandlers(ResourceHandlerRegistry registry) {
            if (!this.resourceProperties.isAddMappings()) {
                logger.debug("Default resource handling disabled");
            } else {
                Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
                CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
                if (!registry.hasMappingForPattern("/webjars/**")) {
                    this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl).setUseLastModified(this.resourceProperties.getCache().isUseLastModified()));
                }

                String staticPathPattern = this.mvcProperties.getStaticPathPattern();
                if (!registry.hasMappingForPattern(staticPathPattern)) {
                    this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl).setUseLastModified(this.resourceProperties.getCache().isUseLastModified()));
                }
            }
        }

禁用掉静态资源的路径映射

我们打上断点看它的默认规则是怎么起作用的,首先调用resourcePropertoes的isAddMappings()方法:
在这里插入图片描述
判断this.resourcePropertoes的isAddMappings()方法是不是不为true,

this.resourcePropertoes我们刚才在2中讲构造器时讲到的ResourceProperties resourceProperties 就是我们上面提到的@EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class, WebProperties.class})中注册开启的第二个类,获取和spring.resources绑定的所有的值的对象
isAddMappings()方法返回的是this.addMappings的值,如下:
在这里插入图片描述
也就是说我们可以通过设置addMappings的值是false还是true来让这个if语句是否执行
我们可以在配置文件中进行设置:

在这里插入图片描述
默认它是true,如果是false,那么他就进入if语句中,执行logger.debug(“Default resource handling disabled”);后结束该方法,else中的所有配置都不生效

在这里插入图片描述
else中的什么配置/webjars/**去哪找等等一些规则都不生效了。
也就是说我们通过设置add-mappings: false 来禁用掉了静态资源的路径映射。
禁用后所有的静态资源都访问不了了。

addMappings的值如果是true,那么他就不会进入if语句中,而是进入到else语句中,那么else语句的内容都得到了执行。

请求参数处理

https://blog.csdn.net/T_james/article/details/80322414 >Http请求之GET,POST,PUT,DELETE方法详解

请求映射

rest使用与原理

  • @xxxMapping;
  • Rest风格支持(使用HTTP请求方式动词来表示对资源的操作)
    • 以前:/getUser 获取用户 /deleteUser 删除用户 /editUser 修改用户 /saveUser 保存用户
    • 现在: /user GET-获取用户 DELETE-删除用户 PUT-修改用户 POST-保存用户
    • 核心Filter:HiddenHttpMethodFilter
    • 用法: 表单method=post,隐藏域 _method=put
    • SpringBoot中手动开启
    • 扩展:如何把_method 这个名字换成我们自己喜欢的。

@RequestMapping(value = "/user",method = RequestMethod.GET)可以改成@GetMapping(value="/user"),两者效果是相同的。

同样POST、PUT、DELETE也一样@PostMapping@PutMappingDeleteMapping

    @RequestMapping(value = "/user",method = RequestMethod.GET)
    public String getUser(){
        return "GET-张三";
    }

    @RequestMapping(value = "/user",method = RequestMethod.POST)
    public String saveUser(){
        return "POST-张三";
    }


    @RequestMapping(value = "/user",method = RequestMethod.PUT)
    public String putUser(){
        return "PUT-张三";
    }

    @RequestMapping(value = "/user",method = RequestMethod.DELETE)
    public String deleteUser(){
        return "DELETE-张三";
    }

    @Bean
    @ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
    @ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter", name = "enabled", matchIfMissing = false)
    public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
        return new OrderedHiddenHttpMethodFilter();
    }

	//发现PUT和DELETE无法访问到
	//自定义filter(不定义的话就是_method)
    @Bean
    public HiddenHttpMethodFilter hiddenHttpMethodFilter(){
        HiddenHttpMethodFilter methodFilter = new HiddenHttpMethodFilter();
        methodFilter.setMethodParam("_m");
        return methodFilter;
    }

Rest原理(表单提交要使用REST的时候)

  • 表单提交会带上_method=PUT
  • 请求过来被HiddenHttpMethodFilter拦截
    – 请求是否正常,并且是POST
    – 获取到_method的值。
    – 兼容以下请求:PUT.DELETE.PATCH
    原生request(post),包装模式requesWrapper重写了getMethod方法,返回的是传入的值。
    过滤器链放行的时候用wrapper。以后的方法调用getMethod是调用requesWrapper的。

Rest使用客户端工具:

  • 如PostMan直接发送Put、delete等方式请求,无需Filter。(PostMan需要去官网下载安装)
spring:
  mvc:
    hiddenmethod:
      filter:
        enabled: true   #开启页面表单的Rest功能

请求映射原理

https://blog.csdn.net/wokewoke/article/details/114991289 >SpringBoot --请求映射原理分析
在这里插入图片描述
SpringMVC功能分析都从 org.springframework.web.servlet.DispatcherServlet -> doDispatch()

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
		HttpServletRequest processedRequest = request;
		HandlerExecutionChain mappedHandler = null;
		boolean multipartRequestParsed = false;

		WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

		try {
			ModelAndView mv = null;
			Exception dispatchException = null;

			try {
				processedRequest = checkMultipart(request);
				multipartRequestParsed = (processedRequest != request);

				// 找到当前请求使用哪个Handler(Controller的方法)处理
				mappedHandler = getHandler(processedRequest);
                
                //HandlerMapping:处理器映射。/xxx->>xxxx

在这里插入图片描述
RequestMappingHandlerMapping:保存了所有@RequestMapping 和handler的映射规则。
在这里插入图片描述
所有的请求映射都在HandlerMapping中。

• SpringBoot自动配置欢迎页的 WelcomePageHandlerMapping 。访问 /能访问到index.html;

• SpringBoot自动配置了默认 的 RequestMappingHandlerMapping

• 请求进来,挨个尝试所有的HandlerMapping看是否有请求信息。

  • 如果有就找到这个请求对应的handler
  • 如果没有就是下一个 HandlerMapping

• 我们需要一些自定义的映射处理,我们也可以自己给容器中放HandlerMapping。自定义 HandlerMapping

	protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
		if (this.handlerMappings != null) {
			for (HandlerMapping mapping : this.handlerMappings) {
				HandlerExecutionChain handler = mapping.getHandler(request);
				if (handler != null) {
					return handler;
				}
			}
		}
		return null;
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值