10

SpringBoot与Web开发(超详细)【篇一】

 3 years ago
source link: https://blog.csdn.net/weixin_43883917/article/details/114375472
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

使用SpringBoot的步骤:

1、创建SpringBoot应用,选中我们需要的模块。
2、SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可以运行起来。
3、自己编写业务代码。

自动配置原理:

xxxxAutoConfiguration:帮我们给容器中自动配置组件
xxxxProperties:配置类来封装配置文件的内容

二、SpringBoot对静态资源的映射规则

@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
public class ResourceProperties implements ResourceLoaderAware {
  //可以设置和静态资源有关的参数,缓存时间等
WebMvcAuotConfiguration:
	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		if (!this.resourceProperties.isAddMappings()) {
			logger.debug("Default resource handling disabled");
			return;
		}
		Integer cachePeriod = this.resourceProperties.getCachePeriod();
		if (!registry.hasMappingForPattern("/webjars/**")) {
			customizeResourceHandlerRegistration(
					registry.addResourceHandler("/webjars/**")
							.addResourceLocations(
									"classpath:/META-INF/resources/webjars/")
					.setCachePeriod(cachePeriod));
		}
		String staticPathPattern = this.mvcProperties.getStaticPathPattern();
         	//静态资源文件夹映射
		if (!registry.hasMappingForPattern(staticPathPattern)) {
			customizeResourceHandlerRegistration(
					registry.addResourceHandler(staticPathPattern)
							.addResourceLocations(
									this.resourceProperties.getStaticLocations())
					.setCachePeriod(cachePeriod));
		}
	}

       //配置欢迎页映射
	@Bean
	public WelcomePageHandlerMapping welcomePageHandlerMapping(
			ResourceProperties resourceProperties) {
		return new WelcomePageHandlerMapping(resourceProperties.getWelcomePage(),
				this.mvcProperties.getStaticPathPattern());
	}

      //配置喜欢的图标
	@Configuration
	@ConditionalOnProperty(value = "spring.mvc.favicon.enabled", matchIfMissing = true)
	public static class FaviconConfiguration {

		private final ResourceProperties resourceProperties;

		public FaviconConfiguration(ResourceProperties resourceProperties) {
			this.resourceProperties = resourceProperties;
		}

		@Bean
		public SimpleUrlHandlerMapping faviconHandlerMapping() {
			SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
			mapping.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
             	//所有  **/favicon.ico 
			mapping.setUrlMap(Collections.singletonMap("**/favicon.ico",
					faviconRequestHandler()));
			return mapping;
		}

		@Bean
		public ResourceHttpRequestHandler faviconRequestHandler() {
			ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
			requestHandler
					.setLocations(this.resourceProperties.getFaviconLocations());
			return requestHandler;
		}

	}

1、所有 /webjars/** ,都去 classpath:/META-INF/resources/webjars/ 找资源

webjars:以jar包的方式引入静态资源。WebJars

在这里插入图片描述
访问localhost:8080/webjars/jquery/3.3.1/jquery.js的结果:
在这里插入图片描述

2、"/**" 访问当前项目的任何资源,都去静态资源的文件夹找映射

"classpath:/META-INF/resources/", 
"classpath:/resources/",
"classpath:/static/", 
"classpath:/public/" 
"/":当前项目的根路径

例子:访问localhost:8080/abc 就是去静态资源文件夹里面找abc

例如我们访问js文件夹下的Chart.min.js:
在这里插入图片描述
访问结果:
在这里插入图片描述

3、欢迎页: 静态资源文件夹下的所有index.html页面,被"/**"映射

编写index.html文件。
在这里插入图片描述
访问结果:
在这里插入图片描述

三、模板引擎

常见的模板引擎:JSP、Velocity、Freemarker、Thymeleaf(springboot推荐,语法更简单,功能更强大)
在这里插入图片描述

1、引入Thymeleaf

Thymeleaf官网

在pom.xml中添加以下依赖:

 <dependency>
   <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-thymeleaf</artifactId>
 </dependency>

2、Thymeleaf的使用

@ConfigurationProperties(prefix = "spring.thymeleaf")
public class ThymeleafProperties {

	private static final Charset DEFAULT_ENCODING = Charset.forName("UTF-8");

	private static final MimeType DEFAULT_CONTENT_TYPE = MimeType.valueOf("text/html");

	public static final String DEFAULT_PREFIX = "classpath:/templates/";

	public static final String DEFAULT_SUFFIX = ".html";

只要我们把HTML页面放在classpath:/templates/,thymeleaf就能自动渲染。

success.html:
在这里插入图片描述
HelloController:

package com.keafmd.springboot.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * Keafmd
 *
 * @ClassName: HelloController
 * @Description:
 * @author: 牛哄哄的柯南
 * @date: 2021-03-04 19:54
 */

@Controller
public class HelloController {

    @ResponseBody
    @RequestMapping("/hello")
    public String hello(){
        return "Hello World";
    }

    @RequestMapping("/success")
    public String success() {
        return "success";
    }
}

访问success的结果:
在这里插入图片描述

1、导入thymeleaf的名称空间

<html lang="en" xmlns:th="http://www.thymeleaf.org">

2、使用thymeleaf语法

HelloController:

package com.keafmd.springboot.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Map;

/**
 * Keafmd
 *
 * @ClassName: HelloController
 * @Description:
 * @author: 牛哄哄的柯南
 * @date: 2021-03-04 19:54
 */

@Controller
public class HelloController {

    @ResponseBody
    @RequestMapping("/hello")
    public String hello(){
        return "Hello World";
    }

    /**
     * 查出一些数据在页面显示
     * @param map
     * @return
     */
    @RequestMapping("/success")
    public String success(Map<String,Object> map) {
        map.put("hello","你好");
        return "success";
    }
}

success.html:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>成功</h1>
    <!--th:text 将div里面的文本内容设置为-->
    <div th:text="${hello}"></div>
</body>
</html>

运行结果:
在这里插入图片描述

3、Thymeleaf的语法规则

1、th:任意html属性,来替换原生属性的值

th:text — 改变当前元素里面的文本内容
更多参考下图:
在这里插入图片描述
2、表达式

Simple expressions:(表达式语法)
    Variable Expressions: ${...}:获取变量值;OGNL;
    		1)、获取对象的属性、调用方法
    		2)、使用内置的基本对象:
    			#ctx : the context object.
    			#vars: the context variables.
                #locale : the context locale.
                #request : (only in Web Contexts) the HttpServletRequest object.
                #response : (only in Web Contexts) the HttpServletResponse object.
                #session : (only in Web Contexts) the HttpSession object.
                #servletContext : (only in Web Contexts) the ServletContext object.
                
                ${session.foo}
            3)、内置的一些工具对象:
#execInfo : information about the template being processed.
#messages : methods for obtaining externalized messages inside variables expressions, in the same way as they would be obtained using #{…} syntax.
#uris : methods for escaping parts of URLs/URIs
#conversions : methods for executing the configured conversion service (if any).
#dates : methods for java.util.Date objects: formatting, component extraction, etc.
#calendars : analogous to #dates , but for java.util.Calendar objects.
#numbers : methods for formatting numeric objects.
#strings : methods for String objects: contains, startsWith, prepending/appending, etc.
#objects : methods for objects in general.
#bools : methods for boolean evaluation.
#arrays : methods for arrays.
#lists : methods for lists.
#sets : methods for sets.
#maps : methods for maps.
#aggregates : methods for creating aggregates on arrays or collections.
#ids : methods for dealing with id attributes that might be repeated (for example, as a result of an iteration).

    Selection Variable Expressions: *{...}:选择表达式:和${}在功能上是一样;
    	补充:配合 th:object="${session.user}:
   <div th:object="${session.user}">
    <p>Name: <span th:text="*{firstName}">Sebastian</span>.</p>
    <p>Surname: <span th:text="*{lastName}">Pepper</span>.</p>
    <p>Nationality: <span th:text="*{nationality}">Saturn</span>.</p>
    </div>
    
    Message Expressions: #{...}:获取国际化内容
    Link URL Expressions: @{...}:定义URL;
    		@{/order/process(execId=${execId},execType='FAST')}
    Fragment Expressions: ~{...}:片段引用表达式
    		<div th:insert="~{commons :: main}">...</div>
    		
Literals(字面量)
      Text literals: 'one text' , 'Another one!' ,…
      Number literals: 0 , 34 , 3.0 , 12.3 ,…
      Boolean literals: true , false
      Null literal: null
      Literal tokens: one , sometext , main ,…
Text operations:(文本操作)
    String concatenation: +
    Literal substitutions: |The name is ${name}|
Arithmetic operations:(数学运算)
    Binary operators: + , - , * , / , %
    Minus sign (unary operator): -
Boolean operations:(布尔运算)
    Binary operators: and , or
    Boolean negation (unary operator): ! , not
Comparisons and equality:(比较运算)
    Comparators: > , < , >= , <= ( gt , lt , ge , le )
    Equality operators: == , != ( eq , ne )
Conditional operators:条件运算(三元运算符)
    If-then: (if) ? (then)
    If-then-else: (if) ? (then) : (else)
    Default: (value) ?: (defaultvalue)
Special tokens:
    No-Operation: _ 

注意内容过多,详细内容参考官方文档

示例:↓

HelloController:

package com.keafmd.springboot.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Arrays;
import java.util.Map;

/**
 * Keafmd
 *
 * @ClassName: HelloController
 * @Description:
 * @author: 牛哄哄的柯南
 * @date: 2021-03-04 19:54
 */

@Controller
public class HelloController {

    @ResponseBody
    @RequestMapping("/hello")
    public String hello(){
        return "Hello World";
    }

    /**
     * 查出一些数据在页面显示
     * @param map
     * @return
     */
    @RequestMapping("/success")
    public String success(Map<String,Object> map) {
        map.put("hello","你好");
        map.put("hello1","<h1>你好</h1>");
        map.put("users", Arrays.asList("柯南","小兰","基德"));
        return "success";
    }
}

success.html:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>成功</h1>
    <!--th:text 将div里面的文本内容设置为-->
    <div id="div01" class="myDiv" th:id="${hello}" th:class="${hello}" th:text="${hello}">这里的内容被覆盖</div>

    <hr/>
    <div th:text="${hello1}"></div>
    <div th:utext="${hello1}"></div>
    <hr/>
    <!--th:each 每次遍历都会生成当前这个标签-->
    <h4 th:text="${user}" th:each="user:${users}"></h4>
    <hr/>
    <h4>
        <span th:each="user:${users}"> [[${user}]] </span>
    </h4>
</body>
</html>

效果:
在这里插入图片描述
在这里插入图片描述

四、SpringMVC自动配置

1、Spring MVC auto-configuration

参考官方文档:点这里

Spring Boot 自动配置好了SpringMVC

以下是SpringBoot对SpringMVC的默认配置:(WebMvcAutoConfiguration)

  • Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.

    • 自动配置了ViewResolver(视图解析器:根据方法的返回值得到视图对象(View),视图对象决定如何渲染(转发?重定向?))
    • ContentNegotiatingViewResolver:组合所有的视图解析器的。
    • 如何定制:我们可以自己给容器中添加一个视图解析器;自动的将其组合进来。
  • Support for serving static resources, including support for WebJars (see below).静态资源文件夹路径,webjars

  • Static index.html support. 静态首页访问

  • Custom Favicon support (see below). favicon.ico

  • 自动注册了 of Converter, GenericConverter, Formatter beans.

    • Converter:转换器; public String hello(User user):类型转换使用Converter
    • Formatter :格式化器; 2017.12.17===Date
@Bean
@ConditionalOnProperty(prefix = "spring.mvc", name = "date-format")//在文件中配置日期格式化的规则
public Formatter<Date> dateFormatter() {
    return new DateFormatter(this.mvcProperties.getDateFormat());//日期格式化组件
}

自己添加的格式化器转换器,我们只需要放在容器中即可

  • Support for HttpMessageConverters (see below).

    • HttpMessageConverter:SpringMVC用来转换Http请求和响应的;User—Json

    • HttpMessageConverters 是从容器中确定;获取所有的HttpMessageConverter

自己给容器中添加HttpMessageConverter,只需要将自己的组件注册容器中(@Bean,@Component)

  • Automatic registration of MessageCodesResolver (see below):定义错误代码生成规则

  • Automatic use of a ConfigurableWebBindingInitializer bean (see below).

我们可以配置一个ConfigurableWebBindingInitializer来替换默认的(添加到容器)

初始化WebDataBinder
请求数据=====JavaBean

org.springframework.boot.autoconfigure.web:web的所有自动场景

If you want to keep Spring Boot MVC features, and you just want to add additional MVC configuration (interceptors, formatters, view controllers etc.) you can add your own @Configuration class of type WebMvcConfigurerAdapter, but without @EnableWebMvc. If you wish to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter or ExceptionHandlerExceptionResolver you can declare a WebMvcRegistrationsAdapter instance providing such components.

如果你想保持Spring Boot MVC 功能,你只是想添加额外的(MVC配置)(https://docs.spring.io/spring/docs/4.3.14.RELEASE/spring-framework-reference/htmlsingle MVC)(拦截器,格式器,视图控制器等)您可以添加自己的@ configuration类WebMvcConfigurerAdapter类型,但没有@EnableWebMvc。如果你想提供RequestMappingHandlerMapping, RequestMappingHandlerAdapter或ExceptionHandlerExceptionResolver的自定义实例,你可以声明一个WebMvcRegistrationsAdapter实例来提供这样的组件。

If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.

如果你想完全控制Spring MVC,你可以添加你自己的@Configuration注解@EnableWebMvc。

2、扩展SpringMVC

实现如下功能:

<mvc:view-controller path="/hello" view-name="success"></mvc:view-controller>

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/hello"/>
        <bean></bean>
    </mvc:interceptor>
</mvc:interceptors>

做法:编写一个配置类(@Configuration),是WebMvcConfigurerAdapter类型;不能标注@EnableWebMvc

特点:既保留了所有的自动配置,也能用我们扩展的配置。

在config包下创建个MyMvcConfig。
在这里插入图片描述
代码实现:

package com.keafmd.springboot.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;


/**
 * Keafmd
 *
 * @ClassName: MyMvcConfig
 * @Description:
 * @author: 牛哄哄的柯南
 * @date: 2021-03-17 20:26
 */
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //浏览器发送 /keafmd 请求 来到success页面
        registry.addViewController("/keafmd").setViewName("success");
    }
}

1、WebMvcAutoConfiguration是SpringMVC的自动配置类。
​ 2、在做其他自动配置时会导入,@Import(EnableWebMvcConfiguration.class)。

   @Configuration
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration {
     private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();

     //从容器中获取所有的WebMvcConfigurer
     @Autowired(required = false)
     public void setConfigurers(List<WebMvcConfigurer> configurers) {
         if (!CollectionUtils.isEmpty(configurers)) {
             this.configurers.addWebMvcConfigurers(configurers);
           	//一个参考实现;将所有的WebMvcConfigurer相关配置都来一起调用;  
           	@Override
            // public void addViewControllers(ViewControllerRegistry registry) {
             //    for (WebMvcConfigurer delegate : this.delegates) {
              //       delegate.addViewControllers(registry);
              //   }
             }
         }
}

3、容器中所有的WebMvcConfigurer都会一起起作用。
​ 4、我们的配置类也会被调用。

效果:SpringMVC的自动配置和我们的扩展配置都会起作用。

3、全面接管SpringMVC

SpringBoot对SpringMVC的自动配置不需要了,所有都是我们自己配置,所有的SpringMVC的自动配置都失效了。

做法:我们需要在配置类中添加@EnableWebMvc即可。

@EnableWebMvc
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //浏览器发送 /keafmd 请求 来到success页面
        registry.addViewController("/keafmd").setViewName("success");
    }
}

全面接管后,静态资源失效。
不推荐这样全面接管。
在这里插入图片描述

加了@EnableWebMvc自动配置就失效了。

1、@EnableWebMvc的核心:

@Import({DelegatingWebMvcConfiguration.class})
public @interface EnableWebMvc {
}

2、DelegatingWebMvcConfiguration

@Configuration(
    proxyBeanMethods = false
)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {

3、WebMvcAutoConfiguration

@Configuration(
    proxyBeanMethods = false
)
@ConditionalOnWebApplication(
    type = Type.SERVLET
)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
//容器中没有这个组件的时候,这个自动配置类才生效
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
@AutoConfigureOrder(-2147483638)
@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})
public class WebMvcAutoConfiguration {

4、@EnableWebMvc将WebMvcConfigurationSupport组件导入进来,自动配置类失效了。

5、导入的WebMvcConfigurationSupport只是SpringMVC最基本的功能。

五、如何修改SpringBoot的默认配置

​ 1、SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(@Bean、@Component)如果有就用用户配置的,如果没有,才自动配置;如果有些组件可以有多个(ViewResolver)将用户配置的和自己默认的组合起来。
​ 2、在SpringBoot中会有非常多的xxxConfigurer帮助我们进行扩展配置。
​ 3、在SpringBoot中会有很多的xxxCustomizer帮助我们进行定制配置。

以上就是SpringBoot与Web开发(超详细)篇一的全部内容。

看完如果对你有帮助,感谢点赞支持!
如果你是电脑端的话,看到右下角的 “一键三连” 了吗,没错点它[哈哈]

在这里插入图片描述

加油!

共同努力!

Keafmd


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK