springboot Web
WEB开发
如何使用SpringBoot
- 创建SpringBoot应用,选择我们需要的模块
- SpringBoot已经将场景默认配置好了,只需在配置文件中配置少量配置就可以运行起来
- 自己编写业务代码
怎么知道配置什么?
SpringBoot帮助我们配置了什么?怎么修改?能修改什么?能不能扩展?
- xxxxAutoConfiguration:帮我们给容器中自动配置组件
- xxxxProperties配置文件封装配置文件的内容
示例:
springBoot静态资源映射
@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));
}
}
-
所有/webjars/**都去classpath:/META-INF/resources/webjars/找资源;
webjars: 以jar包的方式引入静态资源
webjars官网中引入pom文件
http://localhost:8080/webjars/jquery/3.3.1-2/jquery.js就可以访问该路径
-
spring.resources可以设置静态资源有关的参数
springboot还会去以下文件夹找任何资源
"classpath:/META-INF/resources/"
"classpath:/resources/"
"classpath:/static/"
"classpath:/public/"
"/" 当前项目的根路径
一般把静态资源放到static下,访问时直接localhost:8080/ + static下的路径即可
3. 欢迎页
静态资源文件夹下的所有index.html页面
4. 图标
静态资源文件夹下的所有favicon.ico页面
5. 模板引擎(Springboot推荐使用thymeleaf)
内嵌式tomcat,无法使用JSP
thymeleaf语法简单,功能强大。
thymeleaf使用
- 引入thymeleaf
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--提供非严格HTML支持-->
<dependency>
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
<version>1.9.22</version>
</dependency>
- thymeleaf默认配置
spring:
thymeleaf:
cache: false # 开发时关闭缓存,不然没法看到实时页面
mode: LEGACYHTML5 # 用非严格的 HTML
encoding: UTF-8
servlet:
content-type: text/html
默认前后缀已定,只要把html页面放在classpath:/templates/下就能自动渲染
3. thymeleaf语法和使用
eclipse的thymeleaf插件安装
1. 导入thymeleaf的语法空间xmlns:th="http://www.thymeleaf.org"
2 使用thymeleaf语法规则
1.th:text;改变当前元素的文本内容
2.th:id(th:属性可以替换属性值)
详情参考下
thymeleaf语法与表达式
示例:
SpringMVC自动配置
- 视图解析器
springBoot有默认的视图解析器,且会扫描容器中的所有视图解析器。(直接向容器添加就行) - 类型转换器和格式化器(Converter,Formatter)
在配置文件中配置格式化器才会起作用,不配不使用。
如果修改SpringBoot的默认配置? - 自己配置到容器中,使用@Bean @Component
- 在SpringBoot中有很多xxxConfiguration,配置到配置文件中
可以有以下配置,使请求资源转到index页面
/**
* 1. @Configuration标注是一个配置类
* 2. 实现WebMvcConfigurer,可以扩展mvc的功能
*/
@Configuration
public class MvcConfig implements WebMvcConfigurer {
@Bean
public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("login");
registry.addViewController("/login.html").setViewName("login");
registry.addViewController("/index.html").setViewName("index");
registry.addViewController("/jqgrid.html").setViewName("emp/jqgrid");
}
};
}
}
- 更换资源映射
1. 导入相应的webjars
2. 修改表达式
修改前
修改后
官方的自己找webjars,下载的直接拉即可
防止表单重复提交
配置拦截器
/**
* 1. @Configuration标注是一个配置类
* 2. 类型为WebMvcConfigurerAdapter,可以扩展mvc的功能
*/
@Configuration
public class MvcConfig implements WebMvcConfigurer {
@Bean
public LoginInterceptor loginInterceptor(){
return new LoginInterceptor();
}
@Bean
public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("login");
registry.addViewController("/login.html").setViewName("login");
registry.addViewController("/index.html").setViewName("index");
registry.addViewController("/jqgrid.html").setViewName("emp/jqgrid");
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(LoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/","/login.html","/user/login","/asserts/**","/webjars/**");
}
};
}
}
页面取值
thymeleaf抽取公共片段和使用
<div th:fragment="copy">
...
</div>
引入
th:insert 插入指定元素(div)内部
th:replace 替换
th:include 将被引入片段内容包含进去(不带最外层div)
<div th:insert="~{templatename::selector}"></div>
~{templatename::selector} 模板名::选择器
~{templatename::fragmentname} 模板名::片段名
传参激活高亮
SpringBoot错误信息显示
- 浏览器显示
- 客户端
- 定制错误页面
修改默认配置,去找templates/error下的错误页面,可以配置4xx等,页面可以获取的信息:
` 1. timestamp 时间戳- status 状态码
- error 错误提示
- exception 异常对象
- message 异常消息
- errors JSR303校验数据错误
使用方式[[${status}]],在static静态资源下也可以找到页面,但无法使用模板引擎表达式
没有配置时,使用SpringBoot默认配置
`
- 定制错误JSON数据
需要配置errorAttributes
嵌入式Servlet
SpringBoot默认使用tomcat嵌入式servlet
修改servlet属性
-
配置文件修改(ServerProperties)
application.properties中修改servr的属性 -
编写一个WebServerFactoryCustomizer
@Bean
public WebServerFactoryCustomizer<ConfigurableWebServerFactory> embeddedServletContainerCustomizer(){
return new WebServerFactoryCustomizer<ConfigurableWebServerFactory>() {
@Override
public void customize(ConfigurableWebServerFactory factory) {
factory.setPort(8083);
}
};
}
factory就是嵌入的servlet容器
注册Servlet的三大组件(Servlet,Filter,Listener)
spring boot使用嵌入式tomcat,注册三大组件方式:
- ServletRegistrationBean
- FilterRegistrationBean
- ServletListenerRegistrationBean
@Bean
public ServletRegistrationBean myServlet(){
return new ServletRegistrationBean(new MyServlet(),"/myServlet");
}
@Bean
public FilterRegistrationBean myFilter(){
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new MyFilter());
//设置拦截的请求
filterRegistrationBean.setUrlPatterns(Arrays.asList("/hello","/myServlet"));
return filterRegistrationBean;
}
@Bean
public ServletListenerRegistrationBean myListener(){
return new ServletListenerRegistrationBean(new MyListener());
}
嵌入式容器启动原理
- SpringBoot根据导入的依赖关系,给容器添加相应的ServletWebServerFactory【TomcatServletWebServerFactory】
- 容器中组件创建对象就要惊动后置处理器WebServerFactoryCustomizerBeanPostProcessor
- 后置处理器调用ServletWebServerFactoryCustomizer的customize方法,将serverProperties的配置设置给容器,并启动容器
外置Servlet配置(War包用tomcat启动SpringBoot)
- 必须建立war项目
- tomcat指定为provided
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
- 编写SpringBootServletInitializer的子类,调用configure方法
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(SpringBootWebJspApplication.class);
}
}
JDBC配置
SpringBoot2.0默认使用HikariDatasource
HikariDatasource配置
application.yml
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://192.168.40.130:3307/mybatis?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull
driver-class-name: com.mysql.jdbc.Driver
type: com.zaxxer.hikari.HikariDataSource
hikari:
minimum-idle: 5
maximum-pool-size: 15
auto-commit: true
idle-timeout: 30000
pool-name: DatebookHikariCP
max-lifetime: 1800000
connection-timeout: 30000
connection-test-query: SELECT 1
DruidDatasource配置
要添加druid依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.17</version>
</dependency>
application.yml
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://192.168.40.130:3307/jdbc?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull
driver-class-name: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
#上半区公共部分对应的是 org.springframework.boot.autoconfigure.jdbc.DataSourceProperties 中的属性
#下半区属性对应的是 com.alibaba.druid.pool.DruidDataSource 中的属性,Spring Boot 默认是不注入不了这些属性值的,需要自己绑定
#druid 数据源专有配置
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
#配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入
#如果允许时报错 java.lang.ClassNotFoundException: 带上日志
filters: stat,wall,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
DruidConfig配置监控
package com.shyb.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
* @author wzh
* @date 2019/3/27 - 15:08
*/
@Configuration
public class DruidConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource druidDataSource(){
return new DruidDataSource();
}
//配置Druid监控
//1.配置管理后台的Servlet
@Bean
public ServletRegistrationBean statViewServlet(){
ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
Map<String, String> initParams = new HashMap<>();
initParams.put("loginUsername","root");
initParams.put("loginPassword","123456");
initParams.put("allow","");//默认允许所有访问
//map.put("allow","localhost");
initParams.put("deny","");//拒绝某IP访问
bean.setInitParameters(initParams);
return bean;
}
//2.配置监控的Filter
@Bean
public FilterRegistrationBean webStatFilter(){
FilterRegistrationBean bean = new FilterRegistrationBean(new WebStatFilter());
Map<String, String> initParams = new HashMap<>();
initParams.put("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
bean.setInitParameters(initParams);
bean.setUrlPatterns(Arrays.asList("/*"));
return bean;
}
}
Mybatis整合SpringBoot
- 添加Mybatis的starter依赖
- 主动启动类上扫描mapper接口所在的包
@MapperScan(value = "com.shyb.mapper")
@SpringBootApplication
public class SpringBootMybatisApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootMybatisApplication.class, args);
}
}
- 配置Mybatis
mybatis:
mapper-locations: classpath:mappers/*.xml