在上一篇中已经介绍了如何创建一个springboot项目https://blog.csdn.net/IT_CREATE/article/details/86681538,在上一篇中我们选择了组件web、mybatis、freemarker,接着讲关于项目的配置。
pom.xml配置文件:
4.0.0
org.springframework.boot
spring-boot-starter-parent
1.5.19.RELEASE
com.ge
springboot
1.0
springboot
This is a springboot demo!
1.8
com.alibaba
druid
1.0.11
com.alibaba
druid-spring-boot-starter
1.1.0
mysql
mysql-connector-java
org.springframework.boot
spring-boot-configuration-processor
true
org.springframework.boot
spring-boot-starter-aop
org.springframework.boot
spring-boot-starter-freemarker
org.springframework.boot
spring-boot-starter-web
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.3
org.springframework.boot
spring-boot-starter-test
test
spring-snapshots
Spring Snapshots
https://repo.spring.io/snapshot
true
spring-milestones
Spring Milestones
https://repo.spring.io/milestone
false
spring-snapshots
Spring Snapshots
https://repo.spring.io/snapshot
true
spring-milestones
Spring Milestones
https://repo.spring.io/milestone
false
org.springframework.boot
spring-boot-maven-plugin
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n
${LOG_PATH}/debug.log
${LOG_PATH}/debug-%d{yyyyMMdd}.log.%i
50MB
5
DEBUG
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n
${LOG_PATH}/info.log
${LOG_PATH}/info-%d{yyyyMMdd}.log.%i
50MB
5
INFO
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n
${LOG_PATH}/warn.log
${LOG_PATH}/warn-%d{yyyyMMdd}.log.%i
50MB
5
WARN
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n
${LOG_PATH}/error.log
${LOG_PATH}/error-%d{yyyyMMdd}.log.%i
50MB
5
ERROR
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n
、
static文件夹放置页面的静态文件css、js、image等静态文件
templates文件夹放置页面
src/main/java文件夹放置java核心代码
src/test/java文件夹放置java测试代码
application.properties同级目录(src/main/resources)放置一些配置文件
#tomcat configure
server.port=80
server.session.timeout=1800
server.context-path=/boots
server.tomcat.uri-encoding=UTF-8
#springmvc configure
spring.mvc.view.prefix=/templates/
spring.mvc.view.suffix=.ftl
spring.freemarker.cache=true
spring.freemarker.charset=utf-8
spring.freemarker.allow-request-override=true
spring.freemarker.request-context-attribute=req
#logback configure
logging.config=classpath:logback.xml
logging.path=/logs
#datasource configure
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF8
spring.datasource.username=root
spring.datasource.password=1234
spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=20
spring.datasource.maxWait=60000
spring.datasource.timeBetweenEvictionRunsMillis=60000
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=select now() from dual
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
spring.datasource.filters=stat,wall,log4j
spring.datasource.logSlowSql=true
#mybatis configure
mybatis.type-aliases-package=com.ge.springboot.bean
4.1 新建一个ApplicationContextConfig.java类用于配置业务层以下
package com.ge.springboot.configure;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
//import org.springframework.context.annotation.ImportResource;
import org.springframework.stereotype.Controller;
/**
* @Configuration 将该类声明为一个配置类,用来替代applicationContext.xml
* @ComponentScan 开启容器的自动扫描, 并使用Filter排除一些不必要的组件
* 下面利用guolv器过滤了含有@controller的组件,也就是表现层的部分
* @author Administrator
*
* 假如写了一些xml的配置文件,还可以使用@ImportResource({"classpath*:XXX.xml"})
* 导入配置文件的内容
*/
@Configuration
@ComponentScan(basePackages= {"com.ge.springboot"},excludeFilters= {
@ComponentScan.Filter(
type=FilterType.ANNOTATION,value={Controller.class})})
public class ApplicationContextConfig {
}
4.2 新建一个SpringMVCConfig.java类用于配置表现层
package com.ge.springboot.configure;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
//import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
//import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
* 利用注解过滤器排除了业务层层以下
* SpringMVCConfig 配置类,用来替代springmvc-servlet.xml
* @author Administrator
*
* @EnableWebMvc 将该类定义为一个WEB层的配置类,需要extends WebMvcConfigurationSupport
* 取代springboot框架针对WEBMVC的默认配置
*
*
* WebMvcConfigurerAdapter 可以替代 @EnableWebMvc + WebMvcConfigurationSupport
* 并且还支持我们自定义一些配置
*
*/
@Configuration
@ComponentScan(basePackages= {"com.ge.springboot"},excludeFilters= {
@ComponentScan.Filter(
type=FilterType.ANNOTATION,value={Service.class,Repository.class})})
public class SpringMVCConfig extends WebMvcConfigurerAdapter{
/**
* 注册url -- 页面之间的跳转关系
* 比较适合于:从登陆页面上,跳转到"忘记密码","如无账号,请注册"
* 从注册页面上,跳转到"已有账号,马上登录"
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// TODO Auto-generated method stub
//配置系统首页http://ip:port/项目名/
registry.addViewController("/").setViewName("index");
// registry.addViewController("/toLogin").setViewName("index");
}
/**
* 指定静态资源文件目录
*
* 还可以在application.properties使用
* spring.mvc.static-path-pattern=/static/**
* spring.resources.static-locations=classpath:/static/
*
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// TODO Auto-generated method stub
registry.addResourceHandler(new String[]{"/static/**","/resource/**"}).addResourceLocations("classpath:/static/");
}
}
4.3 新建一个DruidDataSourceConfig.java类配置数据源
package com.ge.springboot.configure;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
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 com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
/**
* @Configuration 该注解的作用:描述该JAVA类是一个配置类
* @author Administrator
*
*/
@Configuration
public class DruidDataSourceConfig {
private Logger logger = LoggerFactory.getLogger(DruidDataSourceConfig.class);
@Value("${spring.datasource.url}")
private String dbUrl;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
@Value("${spring.datasource.driver-class-name}")
private String driverClassName;
@Value("${spring.datasource.initialSize}")
private int initialSize;
@Value("${spring.datasource.minIdle}")
private int minIdle;
@Value("${spring.datasource.maxActive}")
private int maxActive;
@Value("${spring.datasource.maxWait}")
private int maxWait;
@Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
private int timeBetweenEvictionRunsMillis;
@Value("${spring.datasource.minEvictableIdleTimeMillis}")
private int minEvictableIdleTimeMillis;
@Value("${spring.datasource.validationQuery}")
private String validationQuery;
@Value("${spring.datasource.testWhileIdle}")
private boolean testWhileIdle;
@Value("${spring.datasource.testOnBorrow}")
private boolean testOnBorrow;
@Value("${spring.datasource.testOnReturn}")
private boolean testOnReturn;
@Value("${spring.datasource.filters}")
private String filters;
@Value("${spring.datasource.logSlowSql}")
private String logSlowSql;
@Bean
public ServletRegistrationBean druidServlet() {
ServletRegistrationBean reg = new ServletRegistrationBean();
reg.setServlet(new StatViewServlet());
reg.addUrlMappings("/druid/*");
reg.addInitParameter("loginUsername", username);
reg.addInitParameter("loginPassword", password);
reg.addInitParameter("logSlowSql", logSlowSql);
return reg;
}
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new WebStatFilter());
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
filterRegistrationBean.addInitParameter("profileEnable", "true");
return filterRegistrationBean;
}
@Bean
public DataSource druidDataSource() {
DruidDataSource datasource = new DruidDataSource();
datasource.setUrl(dbUrl);
datasource.setUsername(username);
datasource.setPassword(password);
datasource.setDriverClassName(driverClassName);
datasource.setInitialSize(initialSize);
datasource.setMinIdle(minIdle);
datasource.setMaxActive(maxActive);
datasource.setMaxWait(maxWait);
datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
datasource.setValidationQuery(validationQuery);
datasource.setTestWhileIdle(testWhileIdle);
datasource.setTestOnBorrow(testOnBorrow);
datasource.setTestOnReturn(testOnReturn);
try {
datasource.setFilters(filters);
} catch (SQLException e) {
logger.error("druid configuration initialization filter", e);
}
return datasource;
}
}
package com.ge.springboot.filter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import org.springframework.core.annotation.Order;
/**
* 中文乱码过滤器
* 既可以处理POST乱码,又可以处理GET乱码
* @author
* @Order(1) 过滤器的执行顺序,值越小,越在前
* 例外,过滤器需要在启动类,或者配置类身上 ,使用@ServletComponentScan完成过滤器的扫描
*/
@Order(1)
@WebFilter(urlPatterns="/*",filterName="encodingFilter",initParams= {
@WebInitParam(name="encoding",value="utf-8"),
@WebInitParam(name="forceEncoding",value="true")
})
public class CharacterEncodingFilter implements Filter {
private String encoding;
private boolean forceEncoding = false;
public CharacterEncodingFilter() {
// TODO Auto-generated constructor stub
}
public void destroy() {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String method = req.getMethod();
if (forceEncoding) {
res.setCharacterEncoding(encoding);
}
if ("GET".equals(method.toUpperCase())) {
HttpServletRequest wrapper = new EncodingHttpServletRequestWrapper(req, encoding);
chain.doFilter(wrapper, res);
} else {
req.setCharacterEncoding(encoding);
chain.doFilter(req, res);
}
}
public void init(FilterConfig config) throws ServletException {
// TODO Auto-generated method stub
encoding = config.getInitParameter("encoding");
forceEncoding = Boolean.valueOf(config.getInitParameter("forceEncoding"));
}
private static class EncodingHttpServletRequestWrapper extends HttpServletRequestWrapper {
private HttpServletRequest request;
private String encoding;
public EncodingHttpServletRequestWrapper(HttpServletRequest request, String encoding) {
super(request);
// TODO Auto-generated constructor stub
this.request = request;
this.encoding = encoding;
}
@Override
public String getQueryString() {
// TODO Auto-generated method stub
String content = request.getQueryString();
if (content != null) {
try {
content = URLDecoder.decode(content, encoding);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return content;
}
@Override
public Map getParameterMap() {
// TODO Auto-generated method stub
String content = getQueryString();
//userName=阿斯蒂芬&loginName=1223&pwd=&gender=0&income=2342342342&marry=true&birthday=&hobby=0&hobby=1
Map params = new HashMap();
// 处理多值的情况
Map> multiValues = new HashMap>();
if (content != null) {
String[] tem = content.split("&");
for (String str : tem) {
String[] kvs = str.split("=");// userName=撒旦法
// 需要处理一个提交项有多个值的情况发生
if (params.containsKey(kvs[0])) {
// 需要处理checkbox的多值情况,例如:ck=111&ck=222&ck=333
List valuesList;
if (multiValues.containsKey(kvs[0])) {// 如果多值集合中已经包含某个键
valuesList = multiValues.get(kvs[0]);
if (kvs.length >= 2) {// ck=111
valuesList.add(kvs[1]);
} else {
valuesList.add("");// ck=
}
} else {// 如果多值集合中尚未包含某个键
valuesList = new ArrayList();
valuesList.add(params.get(kvs[0])[0]);// 初始加入
if (kvs.length >= 2) {// ck=111
valuesList.add(kvs[1]);
} else {// ck=
valuesList.add("");
}
multiValues.put(kvs[0], valuesList);
}
} else {
if (kvs.length >= 2) {// userName=撒旦法
params.put(kvs[0], new String[] { kvs[1] });
} else {// userName=
params.put(kvs[0], new String[] { "" });
}
}
} // for循环结束
// --------------将多值情况,同样添加到params集合中去-------------
if (multiValues != null && !multiValues.isEmpty()) {
Iterator its = multiValues.keySet().iterator();
while (its.hasNext()) {
String key = (String) its.next();
List strs = multiValues.get(key);
int size = strs.size();// 获得值的个数
String[] arrays = new String[size];
for (int i = 0; i < size; i++) {
arrays[i] = strs.get(i);
}
params.put(key, arrays);// 将多值的情况也处理到Map集合中去
}
}
}
return params;
}
@Override
public String getParameter(String name) {
// TODO Auto-generated method stub
Map params = getParameterMap();
String val = "";
if (params != null && params.containsKey(name)) {
val = params.get(name)[0];
}
return val;
}
@Override
public Enumeration getParameterNames() {
// TODO Auto-generated method stub
return Collections.enumeration(getParameterMap().keySet());
}
@Override
public String[] getParameterValues(String name) {
// TODO Auto-generated method stub
return (String[]) getParameterMap().get(name);
}
}
}
package com.ge.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import com.gezhi.springboot.configure.ApplicationContextConfig;
@SpringBootApplication
@ServletComponentScan
public class SpringbootApplication {
public static void main(String[] args) {
//将ApplicationContextConfig配置类的配置信息,交给spring容器
SpringApplication.run(ApplicationContextConfig.class, args);
}
}
在 SpringBootApplication 上使用@ServletComponentScan 注解后,Servlet、Filter、Listener 可以直接通过 @WebServlet、@WebFilter、@WebListener 注解自动注册,无需其他代码。