1
0
mirror of https://gitee.com/incloudcode/yexuejc-springboot.git synced 2025-10-15 14:31:19 +08:00

first commit

This commit is contained in:
2018-04-09 15:11:25 +08:00
commit a27ee11b35
28 changed files with 2358 additions and 0 deletions

View File

@@ -0,0 +1,463 @@
package com.yexuejc.springboot.base.autoconfigure;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties.Cluster;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties.Sentinel;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnection;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
@Configuration
@ConditionalOnClass({ JedisConnection.class, RedisOperations.class, Jedis.class })
@EnableConfigurationProperties(RedisProperties.class)
@Order(1)
public class MutiRedisAutoConfiguration {
public static final String BEAN_REDIS_FACTORY0 = "redisConnectionFactory";
public static final String BEAN_REDIS_TEMPLATE0 = "redisTemplate";
public static final String BEAN_REDIS_STRING_TEMPLATE0 = "stringRedisTemplate";
public static final String BEAN_REDIS_FACTORY1 = "redis-factory-1";
public static final String BEAN_REDIS_TEMPLATE1 = "redis-template-1";
public static final String BEAN_REDIS_STRING_TEMPLATE1 = "redis-string-template-1";
public static final String BEAN_REDIS_FACTORY2 = "redis-factory-2";
public static final String BEAN_REDIS_TEMPLATE2 = "redis-template-2";
public static final String BEAN_REDIS_STRING_TEMPLATE2 = "redis-string-template-2";
public static final String BEAN_REDIS_FACTORY3 = "redis-factory-3";
public static final String BEAN_REDIS_TEMPLATE3 = "redis-template-3";
public static final String BEAN_REDIS_STRING_TEMPLATE3 = "redis-string-template-3";
public static final String BEAN_REDIS_FACTORY4 = "redis-factory-4";
public static final String BEAN_REDIS_TEMPLATE4 = "redis-template-4";
public static final String BEAN_REDIS_STRING_TEMPLATE4 = "redis-string-template-4";
public static final String BEAN_REDIS_FACTORY5 = "redis-factory-5";
public static final String BEAN_REDIS_TEMPLATE5 = "redis-template-5";
public static final String BEAN_REDIS_STRING_TEMPLATE5 = "redis-string-template-5";
public static final String BEAN_REDIS_FACTORY6 = "redis-factory-6";
public static final String BEAN_REDIS_TEMPLATE6 = "redis-template-6";
public static final String BEAN_REDIS_STRING_TEMPLATE6 = "redis-string-template-6";
public static final String BEAN_REDIS_FACTORY7 = "redis-factory-7";
public static final String BEAN_REDIS_TEMPLATE7 = "redis-template-7";
public static final String BEAN_REDIS_STRING_TEMPLATE7 = "redis-string-template-7";
public static final String BEAN_REDIS_FACTORY8 = "redis-factory-8";
public static final String BEAN_REDIS_TEMPLATE8 = "redis-template-8";
public static final String BEAN_REDIS_STRING_TEMPLATE8 = "redis-string-template-8";
public static final String BEAN_REDIS_FACTORY9 = "redis-factory-9";
public static final String BEAN_REDIS_TEMPLATE9 = "redis-template-9";
public static final String BEAN_REDIS_STRING_TEMPLATE9 = "redis-string-template-9";
/**
* Redis connection configuration.
*/
@Configuration
@ConditionalOnClass(GenericObjectPool.class)
protected static class RedisConnectionConfiguration {
private final RedisProperties properties;
private final RedisSentinelConfiguration sentinelConfiguration;
private final RedisClusterConfiguration clusterConfiguration;
public RedisConnectionConfiguration(RedisProperties properties,
ObjectProvider<RedisSentinelConfiguration> sentinelConfiguration,
ObjectProvider<RedisClusterConfiguration> clusterConfiguration) {
this.properties = properties;
this.sentinelConfiguration = sentinelConfiguration.getIfAvailable();
this.clusterConfiguration = clusterConfiguration.getIfAvailable();
}
@Primary
@Bean(BEAN_REDIS_FACTORY0)
@ConditionalOnProperty(name = "afound.redis.db0", matchIfMissing = true)
public JedisConnectionFactory redisConnectionFactory0() throws UnknownHostException {
return applyProperties(createJedisConnectionFactory(), 0);
}
@Bean(BEAN_REDIS_FACTORY1)
@ConditionalOnProperty(name = "afound.redis.db1")
public JedisConnectionFactory redisConnectionFactory1() throws UnknownHostException {
return applyProperties(createJedisConnectionFactory(), 1);
}
@Bean(BEAN_REDIS_FACTORY2)
@ConditionalOnProperty(name = "afound.redis.db2")
public JedisConnectionFactory redisConnectionFactory2() throws UnknownHostException {
return applyProperties(createJedisConnectionFactory(), 2);
}
@Bean(BEAN_REDIS_FACTORY3)
@ConditionalOnProperty(name = "afound.redis.db3")
public JedisConnectionFactory redisConnectionFactory3() throws UnknownHostException {
return applyProperties(createJedisConnectionFactory(), 3);
}
@Bean(BEAN_REDIS_FACTORY4)
@ConditionalOnProperty(name = "afound.redis.db4")
public JedisConnectionFactory redisConnectionFactory4() throws UnknownHostException {
return applyProperties(createJedisConnectionFactory(), 4);
}
@Bean(BEAN_REDIS_FACTORY5)
@ConditionalOnProperty(name = "afound.redis.db5")
public JedisConnectionFactory redisConnectionFactory5() throws UnknownHostException {
return applyProperties(createJedisConnectionFactory(), 5);
}
@Bean(BEAN_REDIS_FACTORY6)
@ConditionalOnProperty(name = "afound.redis.db6")
public JedisConnectionFactory redisConnectionFactory6() throws UnknownHostException {
return applyProperties(createJedisConnectionFactory(), 6);
}
@Bean(BEAN_REDIS_FACTORY7)
@ConditionalOnProperty(name = "afound.redis.db7")
public JedisConnectionFactory redisConnectionFactory7() throws UnknownHostException {
return applyProperties(createJedisConnectionFactory(), 7);
}
@Bean(BEAN_REDIS_FACTORY8)
@ConditionalOnProperty(name = "afound.redis.db8")
public JedisConnectionFactory redisConnectionFactory8() throws UnknownHostException {
return applyProperties(createJedisConnectionFactory(), 8);
}
@Bean(BEAN_REDIS_FACTORY9)
@ConditionalOnProperty(name = "afound.redis.db9")
public JedisConnectionFactory redisConnectionFactory9() throws UnknownHostException {
return applyProperties(createJedisConnectionFactory(), 9);
}
protected final JedisConnectionFactory applyProperties(JedisConnectionFactory factory, int database) {
configureConnection(factory);
if (this.properties.isSsl()) {
factory.setUseSsl(true);
}
factory.setDatabase(database);
if (this.properties.getTimeout() > 0) {
factory.setTimeout(this.properties.getTimeout());
}
return factory;
}
private void configureConnection(JedisConnectionFactory factory) {
if (StringUtils.hasText(this.properties.getUrl())) {
configureConnectionFromUrl(factory);
} else {
factory.setHostName(this.properties.getHost());
factory.setPort(this.properties.getPort());
if (this.properties.getPassword() != null) {
factory.setPassword(this.properties.getPassword());
}
}
}
private void configureConnectionFromUrl(JedisConnectionFactory factory) {
String url = this.properties.getUrl();
if (url.startsWith("rediss://")) {
factory.setUseSsl(true);
}
try {
URI uri = new URI(url);
factory.setHostName(uri.getHost());
factory.setPort(uri.getPort());
if (uri.getUserInfo() != null) {
String password = uri.getUserInfo();
int index = password.lastIndexOf(":");
if (index >= 0) {
password = password.substring(index + 1);
}
factory.setPassword(password);
}
} catch (URISyntaxException ex) {
throw new IllegalArgumentException("Malformed 'spring.redis.url' " + url, ex);
}
}
protected final RedisSentinelConfiguration getSentinelConfig() {
if (this.sentinelConfiguration != null) {
return this.sentinelConfiguration;
}
Sentinel sentinelProperties = this.properties.getSentinel();
if (sentinelProperties != null) {
RedisSentinelConfiguration config = new RedisSentinelConfiguration();
config.master(sentinelProperties.getMaster());
config.setSentinels(createSentinels(sentinelProperties));
return config;
}
return null;
}
/**
* Create a {@link RedisClusterConfiguration} if necessary.
*
* @return {@literal null} if no cluster settings are set.
*/
protected final RedisClusterConfiguration getClusterConfiguration() {
if (this.clusterConfiguration != null) {
return this.clusterConfiguration;
}
if (this.properties.getCluster() == null) {
return null;
}
Cluster clusterProperties = this.properties.getCluster();
RedisClusterConfiguration config = new RedisClusterConfiguration(clusterProperties.getNodes());
if (clusterProperties.getMaxRedirects() != null) {
config.setMaxRedirects(clusterProperties.getMaxRedirects());
}
return config;
}
private List<RedisNode> createSentinels(Sentinel sentinel) {
List<RedisNode> nodes = new ArrayList<RedisNode>();
for (String node : StringUtils.commaDelimitedListToStringArray(sentinel.getNodes())) {
try {
String[] parts = StringUtils.split(node, ":");
Assert.state(parts.length == 2, "Must be defined as 'host:port'");
nodes.add(new RedisNode(parts[0], Integer.valueOf(parts[1])));
} catch (RuntimeException ex) {
throw new IllegalStateException("Invalid redis sentinel " + "property '" + node + "'", ex);
}
}
return nodes;
}
private JedisConnectionFactory createJedisConnectionFactory() {
JedisPoolConfig poolConfig = this.properties.getPool() != null ? jedisPoolConfig() : new JedisPoolConfig();
if (getSentinelConfig() != null) {
return new JedisConnectionFactory(getSentinelConfig(), poolConfig);
}
if (getClusterConfiguration() != null) {
return new JedisConnectionFactory(getClusterConfiguration(), poolConfig);
}
return new JedisConnectionFactory(poolConfig);
}
private JedisPoolConfig jedisPoolConfig() {
JedisPoolConfig config = new JedisPoolConfig();
RedisProperties.Pool props = this.properties.getPool();
config.setMaxTotal(props.getMaxActive());
config.setMaxIdle(props.getMaxIdle());
config.setMinIdle(props.getMinIdle());
config.setMaxWaitMillis(props.getMaxWait());
return config;
}
}
/**
* Standard Redis configuration.
*/
@Configuration
protected static class RedisConfiguration {
@Primary
@Bean(BEAN_REDIS_TEMPLATE0)
@ConditionalOnProperty(name = "afound.redis.db0", matchIfMissing = true)
public RedisTemplate<Object, Object> redisTemplate(
@Qualifier(BEAN_REDIS_FACTORY0) RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
return createRedisTemplate(redisConnectionFactory);
}
@Bean(BEAN_REDIS_STRING_TEMPLATE0)
@ConditionalOnProperty(name = "afound.redis.db0", matchIfMissing = true)
public StringRedisTemplate stringRedisTemplate(
@Qualifier(BEAN_REDIS_FACTORY0) RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
return createStringRedisTemplate(redisConnectionFactory);
}
@Bean(BEAN_REDIS_TEMPLATE1)
@ConditionalOnProperty(name = "afound.redis.db1")
public RedisTemplate<Object, Object> redisTemplate1(
@Qualifier(BEAN_REDIS_FACTORY1) RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
return createRedisTemplate(redisConnectionFactory);
}
@Bean(BEAN_REDIS_STRING_TEMPLATE1)
@ConditionalOnProperty(name = "afound.redis.db1")
public StringRedisTemplate stringRedisTemplate1(
@Qualifier(BEAN_REDIS_FACTORY1) RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
return createStringRedisTemplate(redisConnectionFactory);
}
@Bean(BEAN_REDIS_TEMPLATE2)
@ConditionalOnProperty(name = "afound.redis.db2")
public RedisTemplate<Object, Object> redisTemplate2(
@Qualifier(BEAN_REDIS_FACTORY2) RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
return createRedisTemplate(redisConnectionFactory);
}
@Bean(BEAN_REDIS_STRING_TEMPLATE2)
@ConditionalOnProperty(name = "afound.redis.db2")
public StringRedisTemplate stringRedisTemplate2(
@Qualifier(BEAN_REDIS_FACTORY2) RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
return createStringRedisTemplate(redisConnectionFactory);
}
@Bean(BEAN_REDIS_TEMPLATE3)
@ConditionalOnProperty(name = "afound.redis.db3")
public RedisTemplate<Object, Object> redisTemplate3(
@Qualifier(BEAN_REDIS_FACTORY3) RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
return createRedisTemplate(redisConnectionFactory);
}
@Bean(BEAN_REDIS_STRING_TEMPLATE3)
@ConditionalOnProperty(name = "afound.redis.db3")
public StringRedisTemplate stringRedisTemplate3(
@Qualifier(BEAN_REDIS_FACTORY3) RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
return createStringRedisTemplate(redisConnectionFactory);
}
@Bean(BEAN_REDIS_TEMPLATE4)
@ConditionalOnProperty(name = "afound.redis.db4")
public RedisTemplate<Object, Object> redisTemplate4(
@Qualifier(BEAN_REDIS_FACTORY4) RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
return createRedisTemplate(redisConnectionFactory);
}
@Bean(BEAN_REDIS_STRING_TEMPLATE4)
@ConditionalOnProperty(name = "afound.redis.db4")
public StringRedisTemplate stringRedisTemplate4(
@Qualifier(BEAN_REDIS_FACTORY4) RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
return createStringRedisTemplate(redisConnectionFactory);
}
@Bean(BEAN_REDIS_TEMPLATE5)
@ConditionalOnProperty(name = "afound.redis.db5")
public RedisTemplate<Object, Object> redisTemplate5(
@Qualifier(BEAN_REDIS_FACTORY5) RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
return createRedisTemplate(redisConnectionFactory);
}
@Bean(BEAN_REDIS_STRING_TEMPLATE5)
@ConditionalOnProperty(name = "afound.redis.db5")
public StringRedisTemplate stringRedisTemplate5(
@Qualifier(BEAN_REDIS_FACTORY5) RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
return createStringRedisTemplate(redisConnectionFactory);
}
@Bean(BEAN_REDIS_TEMPLATE6)
@ConditionalOnProperty(name = "afound.redis.db6")
public RedisTemplate<Object, Object> redisTemplate6(
@Qualifier(BEAN_REDIS_FACTORY6) RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
return createRedisTemplate(redisConnectionFactory);
}
@Bean(BEAN_REDIS_STRING_TEMPLATE6)
@ConditionalOnProperty(name = "afound.redis.db6")
public StringRedisTemplate stringRedisTemplate6(
@Qualifier(BEAN_REDIS_FACTORY6) RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
return createStringRedisTemplate(redisConnectionFactory);
}
@Bean(BEAN_REDIS_TEMPLATE7)
@ConditionalOnProperty(name = "afound.redis.db7")
public RedisTemplate<Object, Object> redisTemplate7(
@Qualifier(BEAN_REDIS_FACTORY7) RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
return createRedisTemplate(redisConnectionFactory);
}
@Bean(BEAN_REDIS_STRING_TEMPLATE7)
@ConditionalOnProperty(name = "afound.redis.db7")
public StringRedisTemplate stringRedisTemplate7(
@Qualifier(BEAN_REDIS_FACTORY7) RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
return createStringRedisTemplate(redisConnectionFactory);
}
@Bean(BEAN_REDIS_TEMPLATE8)
@ConditionalOnProperty(name = "afound.redis.db8")
public RedisTemplate<Object, Object> redisTemplate8(
@Qualifier(BEAN_REDIS_FACTORY8) RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
return createRedisTemplate(redisConnectionFactory);
}
@Bean(BEAN_REDIS_STRING_TEMPLATE8)
@ConditionalOnProperty(name = "afound.redis.db8")
public StringRedisTemplate stringRedisTemplate8(
@Qualifier(BEAN_REDIS_FACTORY8) RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
return createStringRedisTemplate(redisConnectionFactory);
}
@Bean(BEAN_REDIS_TEMPLATE9)
@ConditionalOnProperty(name = "afound.redis.db9")
public RedisTemplate<Object, Object> redisTemplate9(
@Qualifier(BEAN_REDIS_FACTORY9) RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
return createRedisTemplate(redisConnectionFactory);
}
@Bean(BEAN_REDIS_STRING_TEMPLATE9)
@ConditionalOnProperty(name = "afound.redis.db9")
public StringRedisTemplate stringRedisTemplate9(
@Qualifier(BEAN_REDIS_FACTORY9) RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
return createStringRedisTemplate(redisConnectionFactory);
}
private RedisTemplate<Object, Object> createRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
template.setKeySerializer(new StringRedisSerializer());
template.setDefaultSerializer(new StringRedisSerializer());
template.setValueSerializer(new StringRedisSerializer());
template.setConnectionFactory(redisConnectionFactory);
return template;
}
private StringRedisTemplate createStringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
}

View File

@@ -0,0 +1,32 @@
package com.yexuejc.springboot.base.autoconfigure;
import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.OSSClient;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* OSS相关配置
*/
@Configuration
@ConditionalOnClass({ OSSClient.class })
@EnableConfigurationProperties(OssProperties.class)
public class OssAutoConfiguration {
private final OssProperties properties;
public OssAutoConfiguration(OssProperties properties) {
this.properties = properties;
}
@Bean
@ConditionalOnMissingBean
public OssFacade ossFacade() {
ClientConfiguration configuration = new ClientConfiguration();
configuration.setSupportCname(false);
return new OssFacade(properties, configuration);
}
}

View File

@@ -0,0 +1,68 @@
package com.yexuejc.springboot.base.autoconfigure;
import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.CopyObjectResult;
import com.aliyun.oss.model.PutObjectResult;
import java.io.InputStream;
/**
* 阿里云OSS服务MNS操作类
*/
public class OssFacade {
private final OssProperties properties;
private final ClientConfiguration configuration;
public OssFacade(OssProperties properties, ClientConfiguration configuration) {
this.properties = properties;
this.configuration = configuration;
}
/**
* 拷贝对象在默认Bucket中拷贝
*
* @param srcKey 元对象Key
* @param destKey 目标对象Key
* @return CopyObjectResult
*/
public CopyObjectResult copyObject(String srcKey, String destKey) {
OSSClient client = ossClient();
CopyObjectResult result = client.copyObject(properties.getBucket(), srcKey, properties.getBucket(), destKey);
client.shutdown();
return result;
}
/**
* 上传文件(简单上传,适合小文件)
*
* @param key 上传位置
* @param inputStream
* @return
*/
public PutObjectResult putObject(String key, InputStream inputStream) {
OSSClient client = ossClient();
PutObjectResult result = client.putObject(properties.getBucket(), key, inputStream);
client.shutdown();
return result;
}
/**
* 判断文件是否存在
*
* @param key 文件位置
* @return
*/
public boolean doesObjectExist(String key) {
OSSClient client = ossClient();
boolean isExist = client.doesObjectExist(properties.getBucket(), key);
client.shutdown();
return isExist;
}
private OSSClient ossClient() {
return new OSSClient(properties.getEndpoint(), properties.getAccessKeyID(), properties.getAccessKeySecret(),
configuration);
}
}

View File

@@ -0,0 +1,49 @@
package com.yexuejc.springboot.base.autoconfigure;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "yexuejc.oss")
public class OssProperties {
/** Endpoint 默认内网外网需要自行配置http://oss-cn-hangzhou.aliyuncs.com */
private String endpoint = "oss-cn-hangzhou-internal.aliyuncs.com";
/** 产品域名(固定) */
private String accessKeyID = "LTAInCYwtsprAu8g";
/** 区域ID(固定) */
private String accessKeySecret = "6aqMtyFuJPUPChYpZSLsQ11cg4qby7";
/** 默认bucket */
private String bucket = "ecentm-res";
public String getEndpoint() {
return endpoint;
}
public void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}
public String getAccessKeyID() {
return accessKeyID;
}
public void setAccessKeyID(String accessKeyID) {
this.accessKeyID = accessKeyID;
}
public String getAccessKeySecret() {
return accessKeySecret;
}
public void setAccessKeySecret(String accessKeySecret) {
this.accessKeySecret = accessKeySecret;
}
public String getBucket() {
return bucket;
}
public void setBucket(String bucket) {
this.bucket = bucket;
}
}

View File

@@ -0,0 +1,114 @@
package com.yexuejc.springboot.base.autoconfigure;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.yexuejc.base.http.Resps;
import com.yexuejc.base.util.DateUtil;
import com.yexuejc.springboot.base.filter.ValidationFilter;
import com.yexuejc.springboot.base.filter.ValidationFilterProperties;
import com.yexuejc.springboot.base.interceptor.LogInterceptor;
import com.yexuejc.springboot.base.util.LogUtil;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
* WebMvc相关配置
*
* @PackageName: com.yexuejc.util.base.http
* @Description:
* @author: maxf
* @date: 2018/1/11 19:51
*/
@Configuration
@ConditionalOnWebApplication
@EnableConfigurationProperties(ValidationFilterProperties.class)
public class WebAutoConfiguration extends WebMvcConfigurerAdapter {
public WebAutoConfiguration(ValidationFilterProperties properties) {
this.properties = properties;
}
/**
* 添加拦截器
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 日志拦截器
registry.addInterceptor(new LogInterceptor()).addPathPatterns("/**");
super.addInterceptors(registry);
}
/**
* 重写jsonConverter参数
*
* @param objectMapper
* @return
*/
@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(ObjectMapper objectMapper) {
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.setDateFormat(DateUtil.DATE_TIME_FORMAT);
return new MappingJackson2HttpMessageConverter(objectMapper);
}
private final ValidationFilterProperties properties;
/**
* 添加校验过滤器目前校验HTTP Header是否符合规范
*
* @return
*/
@Bean
@ConditionalOnProperty(name = "yexuejc.web.validation-filter.enable", matchIfMissing = true)
public FilterRegistrationBean validationFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new ValidationFilter(properties));
registration.addUrlPatterns("/*");
registration.setName("validationFilter");
registration.setOrder(Ordered.HIGHEST_PRECEDENCE + 20);
return registration;
}
/**
* 全局异常处理
*/
@ControllerAdvice
static class GlobalExceptionHandler {
private static final String ERROR_MSG = "系统错误,请联系管理员";
/**
* 出现异常时用于返回Json数据
*
* @param e
* @return
*/
@ExceptionHandler(value = Throwable.class)
@ResponseBody
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public Resps<Object> jsonErrorHandler(Throwable e) {
LogUtil.exceptionLogger.error(e.getMessage(), e);
return Resps.error(ERROR_MSG);
}
}
}

View File

@@ -0,0 +1,72 @@
package com.yexuejc.springboot.base.constant;
/**
* <pre>
* 名称:项目+业务code
* 业务code:项目编号+业务编号
* base:100
* api:101
* wap:102
* admin:103
* </pre>
*
* @author: maxf
* @date: 2018/3/13 19:43
*/
public class BizConsts {
/**
* base_code:100
*/
public static String BASE_CODE = "100";
/**
* 100001:该账户已被禁用
*/
public static String BASE_IS_LOCK_CODE = BASE_CODE + "001";
public static String BASE_IS_LOCK_MSG = "该账户已被禁用";
/**
* 100002:该帐户已过期
*/
public static String BASE_IS_EXPIRE_CODE = BASE_CODE + "002";
public static String BASE_IS_EXPIRE_MSG = "该帐户已过期";
/**
* 100003:登陆凭证已经过期,请重新登陆
*/
public static String BASE_LOGIN_IS_EXPIRE_CODE = BASE_CODE + "003";
public static String BASE_LOGIN_IS_EXPIRE_MSG = "登陆凭证已经过期,请重新登陆";
/**
* 100004:该账户被锁定
*/
public static String BASE_IS_LOCKED_CODE = BASE_CODE + "004";
public static String BASE_IS_LOCKED_MSG = "该账户被锁定";
/**
* 100005:身份验证凭证未找到
*/
public static String BASE_CREDENTIALS_NOT_FOUND_CODE = BASE_CODE + "005";
public static String BASE_CREDENTIALS_NOT_FOUND_MSG = "身份验证凭证未找到";
/**
* 100006:密码错误
*/
public static String BASE_PWD_IS_ERR_CODE = BASE_CODE + "006";
public static String BASE_PWD_IS_ERR_MSG = "密码错误";
/**
* 100007:该账户名不存在
*/
public static String BASE_ACCOUNT_NOT_FOUND_CODE = BASE_CODE + "007";
public static String BASE_ACCOUNT_NOT_FOUND_MSG = "该账户名不存在";
/**
* 100008:登录时发生错误,请联系系统管理员
*/
public static String BASE_SYS_ERR_CODE = BASE_CODE + "008";
public static String BASE_SYS_ERR_MSG = "登录时发生错误,请联系系统管理员";
/**
* 100009:权限不足
*/
public static String BASE_NOT_ROLE_CODE = BASE_CODE + "009";
public static String BASE_NOT_ROLE_MSG = "您无权访问该资源";
/**
* 100010:尚未登陆
*/
public static String BASE_NOT_LOGIN_CODE = BASE_CODE + "010";
public static String BASE_NOT_LOGIN_MSG = "您尚未登陆";
}

View File

@@ -0,0 +1,15 @@
package com.yexuejc.springboot.base.constant;
/**
* redis 业务常量
*
* @author: maxf
* @date: 2018/3/13 20:20
*/
public class RedisConsts {
/**
* 用户登录
* consumer-session-13512345678
*/
public static String CONSUMER_SESSION = "consumer-session";
}

View File

@@ -0,0 +1,71 @@
package com.yexuejc.springboot.base.filter;
import com.yexuejc.base.constant.RespsConsts;
import com.yexuejc.base.http.Resps;
import com.yexuejc.base.util.JsonUtil;
import com.yexuejc.springboot.base.util.LogUtil;
import com.yexuejc.springboot.base.util.NetUtil;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class ValidationFilter implements Filter {
ValidationFilterProperties properties;
public ValidationFilter(ValidationFilterProperties properties) {
this.properties = properties;
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
if (!(servletRequest instanceof HttpServletRequest) || !(servletResponse instanceof HttpServletResponse)) {
throw new ServletException("OncePerRequestFilter just supports HTTP requests");
}
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
String sp = request.getServletPath();
if (properties.getType() == 0) {
if (properties.getIgnored().contains(sp)) {
filterChain.doFilter(servletRequest, servletResponse);
return;
}
} else {
if (!properties.getIntercepts().contains(sp)) {
filterChain.doFilter(servletRequest, servletResponse);
return;
}
}
String xuserAgent = request.getHeader(RespsConsts.HEADER_X_USER_AGENT);
if (xuserAgent == null || xuserAgent.length() == 0) {
// 写日志
String uri = request.getRequestURI();
String userAgent = LogUtil.format(request.getHeader(HttpHeaders.USER_AGENT));
String ip = NetUtil.getIp(request);
LogUtil.accessLogger.warn("{};{};{};{};", uri, userAgent, xuserAgent, ip);
// 返回Response->400-E:请求错误
response.setContentType("application/json;charset=UTF-8");
response.setStatus(HttpStatus.BAD_REQUEST.value());
response.getWriter().write(JsonUtil.obj2Json(Resps.error(RespsConsts.CODE_ERROR, RespsConsts
.MSG_ERROT_HTTP)));
response.getWriter().close();
return;
}
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
}

View File

@@ -0,0 +1,59 @@
package com.yexuejc.springboot.base.filter;
import com.yexuejc.base.util.JsonUtil;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.ArrayList;
import java.util.List;
/**
* 过滤路径
* @PackageName: com.uselaw.base.filter
* @Description:
* @author: maxf
* @date: 2018/2/7 19:11
*/
@ConfigurationProperties(prefix = "yexuejc.http.filter")
public class ValidationFilterProperties {
/**
* 拦截类型0忽略模式默认拦截全部1拦截模式默认一个都不拦截
*/
private int type = 1;
/**
* 忽略拦截列表、路径
*/
private List<String> ignored = new ArrayList<>();
/**
* 拦截列表、路径
*/
private List<String> intercepts = new ArrayList<>();
@Override
public String toString() {
return JsonUtil.obj2Json(this);
}
public List<String> getIgnored() {
return ignored;
}
public void setIgnored(List<String> ignored) {
this.ignored = ignored;
}
public List<String> getIntercepts() {
return intercepts;
}
public void setIntercepts(List<String> intercepts) {
this.intercepts = intercepts;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
}

View File

@@ -0,0 +1,39 @@
package com.yexuejc.springboot.base.interceptor;
import com.yexuejc.base.constant.RespsConsts;
import com.yexuejc.springboot.base.util.LogUtil;
import com.yexuejc.springboot.base.util.NetUtil;
import org.springframework.http.HttpHeaders;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 访问日志拦截器,用于记录用户访问日志
*
* @author PHY
*/
public class LogInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 如登录用户访问,则记录其用户名(手机号)
String username = null;
if (SecurityContextHolder.getContext() != null && SecurityContextHolder.getContext().getAuthentication() != null
&& SecurityContextHolder.getContext().getAuthentication().getName() != null) {
username = SecurityContextHolder.getContext().getAuthentication().getName();
}
// 写日志
String uri = request.getRequestURI();
String userAgent = LogUtil.format(request.getHeader(HttpHeaders.USER_AGENT));
String xuserAgent = request.getHeader(RespsConsts.HEADER_X_USER_AGENT);
String ip = NetUtil.getIp(request);
LogUtil.accessLogger.info("{};{};{};{};{}", uri, userAgent, xuserAgent, ip, username);
return true;
}
}

View File

@@ -0,0 +1,50 @@
package com.yexuejc.springboot.base.pojo;
import com.yexuejc.base.pojo.BaseVO;
import com.yexuejc.base.util.JsonUtil;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
/**
* 分页 VO
*
* @author: maxf
* @date: 2018/3/28 14:23
*/
public class PagerVO extends BaseVO {
private static final long serialVersionUID = 3490440129554644587L;
@NotNull
@Min(1L)
private Integer page = 1;
@NotNull
@Min(1L)
private Integer size = 20;
public int getOffset() {
return (this.page - 1) * this.size;
}
@Override
public String toString() {
return JsonUtil.obj2Json(this);
}
public Integer getPage() {
return page;
}
public void setPage(Integer page) {
this.page = page;
}
public Integer getSize() {
return size;
}
public void setSize(Integer size) {
this.size = size;
}
}

View File

@@ -0,0 +1,38 @@
package com.yexuejc.springboot.base.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 日志处理类
*/
public class LogUtil {
private LogUtil() {
}
/**
* 用于记录访问日志输出到access.log
*/
public final static Logger accessLogger = LoggerFactory.getLogger("com.yexuejc.uselaw.access");
/**
* 用于记录业务日志输出到biz.log
*/
public final static Logger bizLogger = LoggerFactory.getLogger("com.yexuejc.uselaw.biz");
/**
* 用于记录程序异常日志输出到exception.log
*/
public final static Logger exceptionLogger = LoggerFactory.getLogger("com.yexuejc.uselaw.exception");
/**
* 格式化日志消息(将;替换为_)
*
* @param msg 需要被格式化的字符串
* @return 当传入参数为null时返回null
*/
public final static String format(String msg) {
if (msg == null) {
return null;
}
return msg.replaceAll(";", "_");
}
}

View File

@@ -0,0 +1,52 @@
package com.yexuejc.springboot.base.util;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* 网络工具类
*/
public class NetUtil {
private NetUtil() {
}
/**
* 获取请求主机IP地址,如果通过代理进来则透过防火墙获取真实IP地址;
*
* @param request
* @return
* @throws IOException
*/
public final static String getIp(HttpServletRequest request) throws IOException {
// 获取请求主机IP地址,如果通过代理进来则透过防火墙获取真实IP地址
String ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
} else if (ip.length() > 15) {
String[] ips = ip.split(",");
for (int index = 0; index < ips.length; index++) {
String strIp = (String) ips[index];
if (!("unknown".equalsIgnoreCase(strIp))) {
ip = strIp;
break;
}
}
}
return ip;
}
}

View File

@@ -0,0 +1,42 @@
package com.yexuejc.springboot.base.util;
import com.yexuejc.base.constant.RespsConsts;
import com.yexuejc.base.http.Resps;
import org.springframework.http.HttpStatus;
import org.springframework.validation.Errors;
import org.springframework.validation.ObjectError;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
/**
* 检查SpringMVC提交是否有数据校验错误
*
* @PackageName: com.yexuejc.util.base.util
* @Description:
* @author: maxf
* @date: 2018/1/17 14:01
*/
public class ValidUtil {
private ValidUtil() {
}
/**
* APP用 检查SpringMVC提交是否有数据校验错误如果有错则直接response错误信息
*
* @param errors
* @return
* @throws IOException
*/
public static Resps<Object> errResps(HttpServletResponse response, Errors errors) throws IOException {
List<ObjectError> objectErrorList = errors.getAllErrors();
String[] err = new String[objectErrorList.size()];
for (int i = 0; i < objectErrorList.size(); i++) {
err[i] = objectErrorList.get(i).getDefaultMessage() == null ? objectErrorList.get(i).getCode() : objectErrorList.get(i).getDefaultMessage();
}
response.setStatus(HttpStatus.BAD_REQUEST.value());
return Resps.error(RespsConsts.CODE_VALIDATION, err);
}
}

View File

@@ -0,0 +1,4 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.yexuejc.springboot.base.autoconfigure.WebAutoConfiguration,\
com.yexuejc.springboot.base.autoconfigure.OssAutoConfiguration,\
com.yexuejc.springboot.base.autoconfigure.MutiRedisAutoConfiguration

View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 固定配置 START -->
<property name="context.name" value="yexuejc-springboot-base" />
<property name="log.path" value="../logs" />
<property name="log.pattern"
value='%d{yyyy-MM-dd_HH:mm:ss.SSS};%level;%C{0};%M;%L;%msg%n' />
<property name="roll.file.suffix" value="%d{yyyy-MM-dd}.tar.gz" />
<contextName>${context.name}</contextName>
<appender name="ACCESS"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/access.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/access.${roll.file.suffix}
</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<appender name="BIZ"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/biz.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/biz.${roll.file.suffix}
</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<appender name="EXCEPTION"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/exception.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/exception.${roll.file.suffix}
</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<logger name="com.yexuejc.uselaw.access" level="INFO">
<appender-ref ref="ACCESS" />
</logger>
<logger name="com.yexuejc.uselaw.biz" level="INFO">
<appender-ref ref="BIZ" />
</logger>
<logger name="com.yexuejc.uselaw.exception" level="ERROR">
<appender-ref ref="EXCEPTION" />
</logger>
<!-- 固定配置 END -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoder 默认配置为PatternLayoutEncoder -->
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="CONSOLE" />
</root>
</configuration>

View File

@@ -0,0 +1,11 @@
package com.yexuejc.springboot.base;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ApplicationRun {
public static void main(String[] args) {
SpringApplication.run(ApplicationRun.class, args);
}
}

View File

@@ -0,0 +1,17 @@
package com.yexuejc.springboot.base;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ApplicationRun.class)
public class ApplicationTest {
@Test
public void contextLoads() {
System.out.printf("springboot test is runing");
}
}

View File

@@ -0,0 +1,2 @@
server.port=8080
logging.level.root=info