📝个人主页:五敷有你
🔥系列专栏:SpringBoot
⛺️稳重求进,晒太阳
Wbe开发
使用Springboot
1)、创建SpringBoot应用,选中我们需要的模块;
2)、SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可以运行起来3)、自己编写业务代码;
自动配置原理?这个场景SpringBoot帮我们配置了什么?能不能修改?能修改哪些配置?能不能扩展?xxx
SpringBoot对静态资源的映射规则
创建好了项目之后,我们先来讲解一下SpringBoot对于静态资源的相关配置规则,因为我们现在暂时来开发一个前后端没有分离的很彻底的应用(如果前后端分离的很彻底,我们只用SpringBoot来做后端接口),所以必须要知道怎么使用SpringBoot的静态资源。
使用webjars
首先SpringBoot的有个叫webjars的东西,所有通过pom.xml引入的静态资源,都在/webjars/**下(这个在静态资源的自动配置类中可以找到),也就是说SpringBoot会自动去classpath:/META-INF/resources/webjars/找资源,webjars以jar包的方式引入静态资源(也就是说,我们都可以通过http://localhost:8080/webjars/xx访问对应的静态资源)
怎么通过pom.xml引入静态资源呢?我们可以去webjars的资源库中找,需要什么静态资源的jar基本都可以在这里找到(指的是框架依赖),里面长这样子
各种静态资源jar都可以通过pom.xml依赖的方式引入 ,我们引入JQuery看看,引入的JQuery的依赖包下边,可以看到webjars内容长这样
现在我们引入了jQuery的静态资源,我们启动项目,来试一下能不能通过对应的路径访问,我这里使用的路径是http://localhost:8080/webjars/jquery/3.4.1/jquery.js
所以发现了没有,我通过SpringBoot来开发相关的静态资源,非常方便,我们只要引入对应的webjars就可以了,SpringBoot不需要我们进行过多的配置,有自己默认配置的规则。
使用resources
然如果我们想要用自己的静态资源,不想使用webjars的东西,怎么做呢?这个时候就需要另外一个映射规则就是/**(也就是说,我们通过http://localhost:8080/xxx.js访问静态资源,如果我们没有配置相关,就会默认去下面这几个文件夹中找)用来配置映射,即可访问当前项目下的任何资源
- classpath:/META-INF/resources/
- classpath:/resources/
- classpath:/static/
- classpath:/public/
即通过“/**”访问的静态资源,SpringBoot会去上面这几个找资源,这些也就是SpringBoot默认的静态资源文件夹
这里我们可以随便将jquery.js放置在三个文件夹中的一个,然后通过http://localhost:8080/jquery.js可以访问到。
配置欢迎页映射
静态资源文件夹下的所有index.html页面,会被/映射;
也就是说我们直接访问http://localhost:8080/就直接访问静态资源文件夹中的index.html,相当于我们以前SpringMVC下面的index.jsp,比如我们现在随机选public的静态资源文件夹下创建index.html
同样的所有的/favicon.ico默认都是在静态资源下找,当然,如果我们不想要使用SpringBoot默认的静态资源文件夹,我们还可以定义静态资源的映射,如下
要注意了,如果自己定义了静态资源映射之后,默认的文件夹就都不生效了,相当于原来的那些访问方式都不生效了。
模板引擎
JSP、Velocity、Freemarker、Thymeleaf等等,模板引擎的本质思想是一样的,只是语法不大一致而已。比如说以freemarker为例,如下图。
SpringBoot推荐的Thymeleaf,不用JSP,因为Thymeleaf语法更加简单,功能更加强大,如何导入呢,其实对于SpringBoot不就是一个引入依赖的事情嘛,很简单,依赖包如下
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
使用Thymeleaf
在使用Thymeleaf语法之前,我们先来实验一下,我们只要把HTML页面放在templates目录下就可以了,Thymeleaf就会自动渲染
templates下的页面是不能直接访问的,需要使用控制器
正式使用
我们先编写一个控制器,用来跳转渲染,控制器中,加入我们待会儿要在HTML通过Thymeleaf获取的一个变量值,如下
在HTML编写代码之前,现在HTML的头标签中导入thymeleaf的名称空间,这样我们在使用Thymeleaf语法的时候,Idea就会提示相关代码。
编写好之后启动项目,我们通过访问http://localhost:8080/success来访问success.html页面,访问之后结果如下
常用的thymeleaf标签
关键字 | 功能介绍 | 案例 | |
th:id | 替换id | ||
th:text | 文本替换 | description | |
th:utext | 支持html的文本替换 | conten | |
th:object | 替换对象 | ||
th:value | 属性赋值 | ||
th:onclick | 点击事件 | th:οnclick="'getCollect()'" | |
th:each | 属性赋值 | tr th:each="user,userStat:${users}"> | |
th:if | 判断条件 | ||
th:unless | 和th:if判断相反 | Login | |
th:href | 链接地址 | Login /> | |
th:switch | 多路选择 配合th:case 使用 | ||
th:case | th:switch的一个分支 | User is an administrator | |
th:fragment | 布局标签,定义一个代码片段,方便其它地方引用 | ||
th:include | 布局标签,替换内容到引入的文件 | /> |
SpringBoot自动配置MVC
- 中央转发器
- 控制器
- 视图解析器
- 静态资源访问
- 消息转换器
- 格式化
- 静态资源管理
SpringBoot集成了SpringMVC,所以里面自然自动配置了SpringMVC运行的相关基本依赖,那么SpringBoot引入了SpringMVC那些依赖呢?这里我大致进行一下介绍。Spring Boot为Spring MVC提供了自动配置,可与大多数应用程序完美配合。其中自动配置在Spring的默认值之上添加了以下功能:
- 包含ContentNegotiatingViewResolver和BeanNameViewResolver
- 支持服务静态资源,包括对WebJars的支持
- 自动注册Converter,GenericConverter和Formatter的beans。
- 支持HttpMessageConverters。
- 自动注册MessageCodesResolver
- 静态index.html支持
- 定制Favicon支持
- 自动使用ConfigurableWebBindingInitializerbean
如果要保留这些Spring Boot MVC定制并进行更多的MVC定制(拦截器,格式化程序,视图控制器和其他功能),则可以添加自己@Configuration的type类,WebMvcConfigurer但不添加 @EnableWebMvc(因为@EnableWebMvc会关闭Spring Boot MVC的默认配置,而转向需要读取我们自己添加的配置)。
/*** 配置MVC*/
@Configuration
public class MVCConfig implements WebMvcConfigurer {@AutowiredStringRedisTemplate stringRedisTemplate;public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new RefreshInterceptor(stringRedisTemplate)).addPathPatterns("/**").order(1);registry.addInterceptor(new LoginInterceptor(stringRedisTemplate)).addPathPatterns("/**").excludePathPatterns("/user/login","/user/register","/uploadAvatar").order(2);}@Overridepublic void extendMessageConverters(List<HttpMessageConverter<?>> converters) {MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();ObjectMapper objectMapper = jackson2HttpMessageConverter.getObjectMapper();// 不显示为null的字段objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);SimpleModule simpleModule = new SimpleModule();
// 解决Long类型的精度丢失问题simpleModule.addSerializer(Long.class, ToStringSerializer.instance);simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);//解决时间格式问题simpleModule.addSerializer(LocalDateTime.class,new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)));simpleModule.addDeserializer(LocalDateTime.class,new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)));objectMapper.registerModule(simpleModule);//处理不同的时区偏移格式objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);jackson2HttpMessageConverter.setObjectMapper(objectMapper);// 放到第一个converters.add(0, jackson2HttpMessageConverter);}}
如果你想提供的定制情况RequestMappingHandlerMapping,RequestMappingHandlerAdapter或者ExceptionHandlerExceptionResolver,仍然保持弹簧引导MVC自定义,你可以声明类型的beans WebMvcRegistrations,并用它来提供这些组件的定制实例。
如果你想对Spring MVC中的完全控制,你可以添加自己的@Configuration注解为@EnableWebMvc,或者添加自己的@Configuration-annotated DelegatingWebMvcConfiguration中的Javadoc中所述@EnableWebMvc。
中央转发器
Xml无需配置
<servlet> <servlet-name>chapter2</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping> <servlet-name>chapter2</servlet-name> <url-pattern>/</url-pattern>
</servlet-mapping>
中央转发器被springboot自动接管,不再需要我们在web.xml中配置,我们现在的项目也不是web项目,也不存在web.xml,
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
控制器
视图解析器自动管理
曾经的配置文件无需再配
<bean id="de" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value="*.jsp"></property>
</bean>
当我们做文件上传的时候我们也会发现multipartResolver是自动被配置好的
文件上传大小可以通过配置来修改
打开application.properties, 默认限制是10MB,我们可以任意修改
消息转换和格式化
Springboot自动配置了消息转换器
格式化转换器的自动注册
时间类型我们可以在这里修改
在配置文件中指定好时间的模式我们就可以输入了
拦截器
写一个拦截器类
们需要对所有请求进行拦截,写一个LoginHandlerInterceptor实现HandlerInterceptor的接口的拦截器
public class MyInterceptor implements HandlerInterceptor{@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("前置登录拦截");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("后置拦截");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("最终拦截");}
}
添加到springmvc中
字符串转换日期格式
我们在提交日期格式的字符串的时候,SpringBoot有着自己默认的字符串转换日期格式的方法,
而这个默认方法是需要日期通过“/”进行分离的,如果我们先想要通过“-”进行分离,那么我们还是需要在主配置文件中设置日期格式的配置,如下
spring: mvc: date-format: yyyy-MM-dd
默认访问首页
接上一篇博文创建的项目,我们先在properties配置文件中添加一个这个配置
#/接随便啥名,我这里用了dbc
server.servlet.context-path=/dbc
意思是应用的上下文路径,也可以称为项目路径,是构成url地址的一部分。也就是说server.servlet.context-path不配置时,默认为 / ,如:localhost:8085/xxxxxx。当server.servlet.context-path有配置时,比如 /dbc,此时的访问方式为localhost:8085/aaa/xxxxxx,这样我们就配置好了默认首页路径。
拓展MVC
在实际开发中springboot并非完全自动化,很多跟业务相关我们需要自己扩展,springboot给我提供了接口。我们可以来通过实现WebMvcConfigurer接口来扩展
在容器中注册视图控制器(请求转发)
创建一个MyMVCCofnig实现WebMvcConfigurer接口,实现一下addViewControllers方法,我们完成通过/tx访问,转发到success.html的工作
@Configurationpublic class MyMVCCofnig implements WebMvcConfigurer{ @Override public void addViewControllers(ViewControllerRegistryregistry) { registry.addViewController("/tx").setViewName("success"); }
}
注册格式化器
用来可以对请求过来的日期格式化的字符串来做定制化。当然通过application.properties配置也可以办到。
@Override
public void addFormatters(FormatterRegistry registry) {registry.addFormatter(new Formatter<Date>() {@Overridepublic String print(Date date,Locale locale) {return null; }@Overridepublic Date parse(String s, Locale locale) throws ParseException {return new SimpleDateFormat("yyyy-MM-dd").parse(s);
}
消息转换器扩展fastjson
在pom.xml中引入fastjson
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
配置消息转换器,添加fastjson
@Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { FastJsonHttpMessageConverter fc = new FastJsonHttpMessageConverter(); FastJsonConfig fastJsonConfig = new FastJsonConfig(); fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat); fc.setFastJsonConfig(fastJsonConfig); converters.add(fc); }
@EnableWebMvc
上面我们可以自己编写类扩展SpringMVC的相关配置,如果我们再在配置类上加上@EnableWebMvc注解,是啥意思呢,也就是说我们将全面接管SpringMVC在SpringBoot中的配置,在SpringBoot中有关SpringMVC所有的默认配置都会失效,需要我们自行配置,比如上面我们默认webjars进行访问静态资源等等,都会失效
也就是说原本我们不使用@EnableWebMvc,SpringBoot会自动配置SpringMVC的默认依赖,如果我们使用@EnableWebMvc,则@EnableWebMvc就会将WebMVCConfigurationSupport组件导入进来,而导入的WebMVCConfigurationSupport组件里面只有SpringMVC一些最基本的功能。
配置嵌入式容器
修改和server有关的配置(ServerProperties);
server.port: 8081
server.context‐path: /tx
server.tomcat.uri‐encoding: UTF‐8
注册Servlet三大组件
Servlet三大组件分别是Servlet、Filter、Listener,如果我们原先熟悉SpringMVC开发的应该知道,我们在Webapp下面的web.xml中,经常需要配置这三大组件用来过滤监听相关的请求,
而在SpringBoot中,由于SpringBoot默认是以jar包的方式启动嵌入式的Servlet容器来启动SpringBoot的web应用,所以并没有没有web.xml文件。但是我们依旧可以通过SpringBoot特有的相关注册Bean进行注册,分别是
ServletRegistrationBean
//注册三大组件
@Bean
public ServletRegistrationBean myServlet(){
ServletRegistrationBean registrationBean = new ServletRegistrationBean(new MyServlet(),"/myServlet");
return registrationBean;
}
FilterRegistrationBean
@Bean
public FilterRegistrationBean myFilter(){
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new MyFilter());
registrationBean.setUrlPatterns(Arrays.asList("/hello","/myServlet"));
return registrationBean;
}
ServletListenerRegistrationBean
@Bean
public ServletListenerRegistrationBean myListener(){
ServletListenerRegistrationBean<MyListener> registrationBean = new ServletListenerRegistrationBean<>(new MyListener());
return registrationBean;
}
SpringBoot帮我们自动配置SpringMVC的时候,会自动的注册SpringMVC的前端控制器,即DIspatcherServlet,我们通过查阅DispatcherServletAutoConfiguration发现,会默认拦截,“/”的所有请求,包括静态资源,但是不拦截jsp请求,/*会拦截jsp,可以通过server.servletPath来修改SpringMVC前端控制器默认拦截的请求路径