实践-Spring升级改造

2018年在公司负责了一段时间老项目改造升级工作。因此记录下折腾的过程。

  • Spring boot 最近挺火的,之前的工作并没有机会去实战。但是即使不使用Spring boot 也是可以做零配置的。

约定大于配置

  • servlet3.*的规范已经支持不使用web.xml了。
  • annotation的配置方式在Spring其实也存在很久了。

直奔主题

代码配置web.xml

1
org.springframework.web.WebApplicationInitializer
  • 实现这个接口,Override onStartup方法,就拿到钥匙了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package cn.z201.learn.config;


import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.HiddenHttpMethodFilter;
import org.springframework.web.servlet.DispatcherServlet;

import cn.z201.learn.config.app.WebAppConfig;

/**
* 基于代码可以不使用web.xml
* @author z201
*/
public class WebProjectConfigInitializer implements WebApplicationInitializer {

public static final String CHARACTER_ENCODING = "UTF-8";

private final static String DISPATCHER_SERVLET_NAME = "dispatcher";

private final static String DISPATCHER_SERVLET_MAPPING = "/";

private final static String ENCODEING_FILTER_NAME = "encodefilter";

private final static String ENCODEING_FILTER_MAPPING = "/*";

@Override
public void onStartup(ServletContext servletContext) throws ServletException {
initializeSpringMVCConfig(servletContext); //启动spring mvc
}

/**
* 注册spring mvc
* @param container
*/
private void initializeSpringMVCConfig(ServletContext container) throws ServletException {

// 编码过滤器
CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
encodingFilter.setForceEncoding(true);
encodingFilter.setEncoding(CHARACTER_ENCODING);
//配置Spring提供的字符编码过滤器
//第一个参数 指定字符编码编码
//第二个参数 是否强制要求响应包编码与请求包相同,false表示如果响应包设置了自己编码则不强制修改
FilterRegistration.Dynamic filter = container.addFilter(ENCODEING_FILTER_NAME, encodingFilter);
// 解决HTTP PUT请求Spring无法获取请求参数的问题
filter = container.addFilter("hiddenHttpMethodFilter", new HiddenHttpMethodFilter());
//配置过滤器的过滤路径
filter.addMappingForUrlPatterns(null, true, ENCODEING_FILTER_MAPPING);

// Create the spring rest servlet's Spring application context
AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
dispatcherContext.register(WebAppConfig.class);
// Register and map the spring rest servlet
ServletRegistration.Dynamic dispatcher = container.addServlet(DISPATCHER_SERVLET_NAME,
new DispatcherServlet(dispatcherContext));
//启动顺序
dispatcher.setLoadOnStartup(1);
dispatcher.setAsyncSupported(true);
//配置映射路径
dispatcher.addMapping(DISPATCHER_SERVLET_MAPPING);
}

}

解决Maven War提示找不到web.xml编译错误。

  • 注意如果你是Mavan项目,默认情况下war项目是需要找到web.xml的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<!-- failOnMissingWebXml false 可以没有web.xml -->
<failOnMissingWebXml>false</failOnMissingWebXml>
<!-- 暂时不适用其他模板页面
<overlays>
<overlay>
<groupId>org.cn.z201.views</groupId>
<artifactId>ssh-views</artifactId>
</overlay>
</overlays>
-->
</configuration>
</plugin>
  • 诺,在war打包插件中配置下就好了。

主角WebAppConfig SpringMVC配置启动类。

1
org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
  • 继承这个类,里面有很多方法给你重写。这其实跟xml配置非常相似了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package cn.z201.learn.config.app;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;

import cn.z201.learn.config.app.support.BeetlConfiguration;
import cn.z201.learn.config.app.support.DataSourceConfiguration;
import cn.z201.learn.config.app.support.EhCacheConfiguration;
import cn.z201.learn.config.app.support.MultipartResolverConfiguration;
import cn.z201.learn.config.app.support.SchedulingConfiguration;
import cn.z201.learn.config.app.support.SwaggerConfiguration;
import cn.z201.learn.config.app.support.ValidatorConfiguration;
import cn.z201.learn.core.interceptor.LoginInterceptor;

import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
* @Configuration,用于表示这个类是一个配置类,用于配置Spring的相关信息
* 类似于spring配置文件,负责注册bean,对应的提供了@Bean注解。
* 需要org.springframework.web.context.support.AnnotationConfigWebApplicationContext注册到容器中。
* @EnableWebMvc 启用MVC Java配置(@Controller等各种注解)
* @ComponentScan : 注解类查找规则定义 <context:component-scan/> 组件扫描,
* 在basePackages指定的目录下扫描被@Controller@Service@Component等注解注册的组件
* @EnableAsync 注解的意思是可以异步执行,就是开启多线程的意思。
* @EnableAspectJAutoProxy,启用切面自动代理,用于AOP 激活Aspect自动代理 <aop:aspectj-autoproxy/>
* @EnableCaching :启用缓存注解 <cache:annotation-driven/>
* @EnableScheduling 启动定时任务注解
* @EnableTransactionManagement : 启用注解式事务管理 <tx:annotation-driven /> 启用注解事务,即可以使用@Transactional注解来控制事务
* @EnableWebMvcSecurity : 启用springSecurity安全验证
* @Import@ImportResource 引入指定的配置类,我们引入了Spring容器配置类和数据源事务配置类
* @PropertySource,加载指定的配置文件,配置文件内容会加载入Environment中等待调用
*/

@Configuration
@EnableWebMvc
@EnableAsync
@EnableScheduling
@EnableTransactionManagement
@EnableAspectJAutoProxy(proxyTargetClass = true)
@Import( { DataSourceConfiguration.class ,
BeetlConfiguration.class,
MultipartResolverConfiguration.class,
SwaggerConfiguration.class ,
EhCacheConfiguration.class ,
SchedulingConfiguration.class,
ValidatorConfiguration.class})
@PropertySource(value = {"classpath:config.properties"},ignoreResourceNotFound = true)
@ComponentScan(basePackages = { "cn.z201" })
public class WebAppConfig extends WebMvcConfigurerAdapter {

private static final Logger LOGGER = LogManager.getLogger(WebAppConfig.class);


public WebAppConfig() {
LOGGER.info("[Initialize WebAppConfig]");
Locale.setDefault(Locale.US);
}

/**
* 静态资源映射
* addResourceHandler()方法指定url,该url后连接静态文件,对应着addResourceLoaction()方法目录所对应的静态文件
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
LOGGER.info("[Initialize addResourceHandlers]");
registry.addResourceHandler("/static/**")
.addResourceLocations("/static/")
.setCachePeriod(5000);
}

/**
* 将对于静态资源的请求转发到Servlet容器的默认处理静态资源的servlet
* 因为将spring的拦截模式设置为"/"时会对静态资源进行拦截
*/
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}

/**
* 添加拦截器
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 多个拦截器组成一个拦截器链
// addPathPatterns 用于添加拦截规则
// excludePathPatterns 用户排除拦截
registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/login");
super.addInterceptors(registry);
}


/**
* 本地国际化
* @return
*/
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LOGGER.info("[Initialize LocaleChangeInterceptor]");
return new LocaleChangeInterceptor();
}

/**
* json、Jsonp消息转换适配器,用于支持RequestBody、ResponseBody
* Json、Jsonp Message Converter , Support For RequestBody、ResponseBody
* @return
*/
@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
LOGGER.info("[Initialize MappingJackson2HttpMessageConverter]");
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
List<MediaType> mediaType = new ArrayList<MediaType>();
mediaType.add(MediaType.APPLICATION_JSON_UTF8);
mappingJackson2HttpMessageConverter.setSupportedMediaTypes(mediaType);
return mappingJackson2HttpMessageConverter;
}

}
  • 恩,我这里的其他配置是使用其他的Bean单独配置的。一个一个来吧。

其他配置

1. DataSourceConfiguration 数据源 没有使用ORM框架直接用jdbcTemplate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package cn.z201.learn.config.app.support;

import java.sql.SQLException;

import javax.sql.DataSource;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import com.alibaba.druid.pool.DruidDataSource;


@Configuration
public class DataSourceConfiguration {

private static final Logger LOGGER = LogManager.getLogger(DataSourceConfiguration.class);

@Value("${db.url}")
private String url;

@Value("${db.username}")
private String username;

@Value("${db.password}")
private String password;

@Value("${db.maxActive}")
private int maxActive;

@Value("${db.initialSize}")
private Integer initialSize;

@Value("${db.minIdle}")
private Integer minIdle;

@Value("${db.maxWait}")
private Integer maxWait;

@Value("${db.timeBetweenEvictionRunsMillis}")
private Integer timeBetweenEvictionRunsMillis;

@Value("${db.minEvictableIdleTimeMillis}")
private Integer minEvictableIdleTimeMillis;

@Value("${db.validationQuery}")
private String validationQuery;

@Value("${db.testWhileIdle}")
private Boolean testWhileIdle;

@Value("${db.testOnBorrow}")
private Boolean testOnBorrow;

@Value("${db.testOnReturn}")
private Boolean testOnReturn;

@Value("${db.poolPreparedStatements}")
private Boolean poolPreparedStatements;

@Value("${db.maxPoolPreparedStatementPerConnectionSize}")
private Integer maxPoolPreparedStatementPerConnectionSize;

@Value("${db.filters}")
private String filters;

/**
* 事务管理器
*/
@Bean
public DataSourceTransactionManager dataSourceTransactionManager() {
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
dataSourceTransactionManager.setDataSource(dataSource());
return dataSourceTransactionManager;
}

/**
* SpringJDBC Template
*/
@Bean
public JdbcTemplate jdbcTemplate() {
return new JdbcTemplate(dataSource());
}

@Bean
public DataSource dataSource(){
LOGGER.info("[Initialize DataSourceConfiguration]");
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUsername(this.username);
dataSource.setPassword(this.password);
dataSource.setUrl(this.url);

dataSource.setInitialSize(initialSize); //定义初始连接数
dataSource.setMinIdle(minIdle); //最小空闲
dataSource.setMaxActive(maxActive); //定义最大连接数
dataSource.setMaxWait(maxWait); //最长等待时间

// 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);

// 配置一个连接在池中最小生存的时间,单位是毫秒
dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
// 用来检测连接是否有效的sql,要求是一个查询语句。 如果validationQuery为null,testOnBorrow、testOnReturn、
// testWhileIdle都不会其作用。在mysql中通常为select 'x',在oracle中通常为 select 1 from dual -->
dataSource.setValidationQuery(validationQuery);

// 建议配置为true,不影响性能,并且保证安全性。 申请连接的时候检测,如果空闲时间大于 timeBetweenEvictionRunsMillis,
// 执行validationQuery检测连接是否有效。
dataSource.setTestWhileIdle(testWhileIdle);
// 申请连接时执行validationQuery检测连接是否有效, 做了这个配置会降低性能。
dataSource.setTestOnBorrow(testOnBorrow);
//归还连接时执行validationQuery检测连接是否有效, 做了这个配置会降低性能
dataSource.setTestOnReturn(testOnReturn);

// 是否缓存preparedStatement,也就是PSCache。 PSCache对支持游标的数据库性能提升巨大,比如说oracle。
//在mysql5.5以下的版本中没有PSCache功能,建议关闭掉。 5.5及以上版本有PSCache,建议开启。
dataSource.setPoolPreparedStatements(poolPreparedStatements);
dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
try {
dataSource.setFilters(filters);
} catch (SQLException e) {
LOGGER.error("[Error DataSourceConfiguration ] {}",e.getSQLState());
}
return dataSource;
}

}
2. BeetlConfiguration 页面模板引擎
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package cn.z201.learn.config.app.support;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.beetl.ext.spring.BeetlGroupUtilConfiguration;
import org.beetl.ext.spring.BeetlSpringViewResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;


@Configuration
public class BeetlConfiguration{

private static final Logger LOGGER = LogManager.getLogger(BeetlConfiguration.class);

/**
- * 配置试图模板引擎
- */
@Bean(initMethod = "init", name = "beetlConfig")
public BeetlGroupUtilConfiguration beetlConfig() {
LOGGER.info("[Initialize BeetlGroupUtilConfiguration]");
BeetlGroupUtilConfiguration beetlGroupUtilConfiguration = new BeetlGroupUtilConfiguration();
// 如果需要配置 beetl 相关功能,就传入beetl的配置文件
// 模板的位置就在 beetl.properties 中配置
beetlGroupUtilConfiguration.setConfigFileResource(new ClassPathResource("beetl.properties"));
// 或简单的方式就是使用默认配置文件,用下面的代码设置模板位置
beetlGroupUtilConfiguration.setRoot("/");
return beetlGroupUtilConfiguration;
}

@Bean(name = "beetlSpringViewResolver")
public BeetlSpringViewResolver beetlViewResolver(BeetlGroupUtilConfiguration beetlConfig) {
BeetlSpringViewResolver beetlSpringViewResolver = new BeetlSpringViewResolver();
beetlSpringViewResolver.setContentType("text/html;charset=UTF-8"); // 设置编码
beetlSpringViewResolver.setOrder(0);
beetlSpringViewResolver.setSuffix(".html");
beetlSpringViewResolver.setConfig(beetlConfig);
return beetlSpringViewResolver;
}

}
3. MultipartResolverConfiguration 上传插件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package cn.z201.learn.config.app.support;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

@Configuration
public class MultipartResolverConfiguration {

private static final Logger LOGGER = LogManager.getLogger(MultipartResolverConfiguration.class);

@Bean(name="multipartResolver")
public CommonsMultipartResolver commonsMultipartResolver(){
LOGGER.info("[Initialize CommonsMultipartResolver]");
CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver();
commonsMultipartResolver.setDefaultEncoding("utf-8"); //<!--编码为uft-8 -->
commonsMultipartResolver.setMaxUploadSize(104666600); //<!-- 设置最大上传文件大小为 -->
commonsMultipartResolver.setMaxInMemorySize(1046666000); //<!-- 设置最大上传文件在内存中的大小 -->
return commonsMultipartResolver;
}

}
5 .SwaggerConfiguration API
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package cn.z201.learn.config.app.support;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.google.common.collect.Sets;

import io.swagger.annotations.ApiOperation;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class SwaggerConfiguration {

private static final Logger LOGGER = LogManager.getLogger(SwaggerConfiguration.class);

@Bean
public Docket createApi() {
LOGGER.info("[Initialize SwaggerConfiguration]");
return new Docket(DocumentationType.SWAGGER_2)
.produces(Sets.newHashSet("application/json", "application/xml"))
.consumes(Sets.newHashSet("application/json", "application/xml"))
.protocols(Sets.newHashSet("http", "https"))
.forCodeGeneration(true)
.apiInfo(apiInfo())
.select() // 选择那些路径和api会生成document
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) //扫描注解
// .apis(RequestHandlerSelectors.basePackage(ApiPackage.class.getPackage().getName().trim())) //扫描包路
.paths(PathSelectors.any()) // 对所有路径进行监控
.build();
}

private ApiInfo apiInfo() {
ApiInfo apiInfo= new ApiInfoBuilder()
.title("API管理")
.description("https://my.oschina.net/z201/blog")
.termsOfServiceUrl("https://my.oschina.net/z201/blog")
.contact(new Contact("自己动手丰衣足食","","https://my.oschina.net/z201/blog"))
.version("1.0")
.build();
return apiInfo;
}
}
6. EhCacheConfiguration 缓存配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package cn.z201.learn.config.app.support;

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;

import net.sf.ehcache.CacheManager;



@Configuration
@EnableCaching
public class EhCacheConfiguration {

/**
* EhCache的配置
*/
@Bean
public EhCacheCacheManager cacheManager(CacheManager cacheManager) {
return new EhCacheCacheManager(cacheManager);
}

/**
* EhCache的配置
*/
@Bean
public EhCacheManagerFactoryBean ehcache() {
EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean();
ehCacheManagerFactoryBean.setConfigLocation(new ClassPathResource("ehcache.xml"));
return ehCacheManagerFactoryBean;
}

}
7 . SchedulingConfiguration 启动定时任务 Spring task
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package cn.z201.learn.config.app.support;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;

@Configuration
public class SchedulingConfiguration implements SchedulingConfigurer{

@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(taskExecutor());
}

@Bean(destroyMethod="shutdown")
public Executor taskExecutor() {
return Executors.newScheduledThreadPool(10);
}

}
8 . ValidatorConfiguration 验证框架配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package cn.z201.learn.config.app.support;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;

@Configuration
public class ValidatorConfiguration {

private static final Logger LOGGER = LogManager.getLogger(ValidatorConfiguration.class);
/**
* 支持校验 HibernateValidator
* @return ValidatorConfiguration
*/
@Bean("validator")
public LocalValidatorFactoryBean localValidatorFactoryBean(){
LOGGER.info("[Initialize ValidatorConfiguration]");
LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
localValidatorFactoryBean.setProviderClass(HibernateValidator.class);
localValidatorFactoryBean.setValidationMessageSource(reloadableResourceBundleMessageSource());
return new LocalValidatorFactoryBean();
}

@Bean("messageSource")
public ReloadableResourceBundleMessageSource reloadableResourceBundleMessageSource(){
ReloadableResourceBundleMessageSource reloadableResourceBundleMessageSource = new ReloadableResourceBundleMessageSource();
reloadableResourceBundleMessageSource.setBasename("classpath:messages");
reloadableResourceBundleMessageSource.setDefaultEncoding("UTF-8");
reloadableResourceBundleMessageSource.setCacheSeconds(120);
return reloadableResourceBundleMessageSource;
}

}

POM文件配置信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
	<properties>
<!-- 项目框架组合版本号 -->
<java.version>1.8</java.version>
<javax.el-api.version>3.0.0</javax.el-api.version>
<javax.servlet-api.version>3.1.0</javax.servlet-api.version>
<spring.version>4.3.8.RELEASE</spring.version>
<!-- 页面模板引擎ibeetl -->
<com.ibeetl.version>2.7.15</com.ibeetl.version>
<!-- org.ehcache 2.* -->
<org.ehcache.version>2.10.2.2.21</org.ehcache.version>
<!-- LOG框架 -->
<org.log4j2.version>2.8.1</org.log4j2.version>
<!-- org.hibernate.validator -->
<org.hibernate-validator.version>5.2.4.Final</org.hibernate-validator.version>
<!-- jackson框架 组合-->
<com.fasterxml.jackson.version>2.8.1</com.fasterxml.jackson.version>
<net.sf.json-lib.version>2.4</net.sf.json-lib.version>
<!-- MYSQL 数据库驱动 -->
<mysql.driver.version>5.1.28</mysql.driver.version>
<!-- springfox-swagger -->
<springfox.swagger.version>2.7.0</springfox.swagger.version>
<!-- 阿里巴巴 Druid连接 -->
<alibaba.druid.version>1.0.31</alibaba.druid.version>
<!-- AOP 组合-->
<org.aspectj.version>1.8.8</org.aspectj.version>
<cglib.nodep.version>3.1</cglib.nodep.version>
<!-- 上传组件 -->
<apache.commons.fileupload>1.3.1</apache.commons.fileupload>
<!-- lang3-->
<apache.commons.lang3>3.4</apache.commons.lang3>
<!-- io-->
<apache.commons.io>2.4</apache.commons.io>
<!-- collections-->
<apache.commons.collections>3.2.1</apache.commons.collections>
<!-- lombok 语法糖 -->
<projectlombok.version>1.16.16</projectlombok.version>
<!-- 单元测试 -->
<junit.version>4.12</junit.version>
<!-- 指定Maven编译项目编译格式 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>cn.z201.web.common</groupId>
<artifactId>web.common </artifactId>
<version>${project.version}</version>
</dependency>
<!-- Spring 4.* -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
<exclusions>
<!-- 排除通用日志 改支持SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
<exclusions>
<!-- 排除通用日志 改支持SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>

<!-- hibernate validator -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${org.hibernate-validator.version}</version>
</dependency>
<!-- 增强 AOP -->
<!-- quartz配置 -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>${org.quartz.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${org.aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj.version}</version>
</dependency>
<!-- 待定 -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>${cglib.nodep.version}</version>
</dependency>
<!-- AOP end-->
<!-- ibeetl -->
<dependency>
<groupId>com.ibeetl</groupId>
<artifactId>beetl</artifactId>
<version>${com.ibeetl.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.ehcache/ehcache -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>${org.ehcache.version}</version>
</dependency>
<!-- Druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${alibaba.druid.version}</version>
</dependency>
<!-- mysql driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.driver.version}</version>
</dependency>
<!-- 添加Swagger2依赖 ${springfox.swagger.version}-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox.swagger.version}</version>
</dependency>
<!--
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
-->
<dependency>
<groupId>com.drore.cloud</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.0</version>
</dependency>
<!-- Logging配置:Log4j2 -->
<!-- log4j2 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${org.log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${org.log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jcl</artifactId>
<version>${org.log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-1.2-api</artifactId>
<version>${org.log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${org.log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
<version>${org.log4j2.version}</version>
</dependency>
<!-- 待定 -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>${cglib.nodep.version}</version>
</dependency>
<!-- 使用jsonLayout必须依赖jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${com.fasterxml.jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${com.fasterxml.jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>${com.fasterxml.jackson.version}</version>
</dependency>
<!--json-lib -->
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>${net.sf.json-lib.version}</version>
<classifier>jdk15</classifier>
</dependency>
<!-- Test 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<!-- 上传 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${apache.commons.fileupload}</version>
</dependency>
<!-- H2 driver
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.database.version}</version>
</dependency>
-->
<!-- commons -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${apache.commons.lang3}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${apache.commons.io}</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>${apache.commons.collections}</version>
</dependency>
<!-- http://projectlombok.org/ -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${projectlombok.version}</version>
</dependency>
<!-- WAR相关jar -->
<!-- javax -->
<!-- https://mvnrepository.com/artifact/javax.el/javax.el-api -->
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>${javax.el-api.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${javax.servlet-api.version}</version>
</dependency>

</dependencies>

结束语

自己动手丰衣足食