增加示例代码
|
@ -1,8 +1,9 @@
|
|||
# yexuejc-springboot
|
||||
|
||||
### 说明
|
||||
>本分支基于 springboot 2.x 开发,版本号也将保持2.x
|
||||
>1.x分支继续基于 springboot 1.x开发
|
||||
>基于springboot版本分别维护1.x(对应springboot1.5.16.RELEASE) 2.x(对应springboot2.0.5.RELEASE) 分支 <br>
|
||||
>master将继续同步1.x分支(后期获取会同步于2.x)
|
||||
|
||||
|
||||
#### 项目介绍
|
||||
基于springboot maven 封装可继承基础工程
|
||||
|
@ -12,8 +13,8 @@ parent:版本封装<br/>
|
|||
base:功能封装
|
||||
|
||||
#### 最新版本
|
||||
>yexuejc.springboot.version=2.0.5 <br>
|
||||
>yexuejc.base.version=1.3.9
|
||||
* yexuejc.springboot.version=1.2.1 <br>
|
||||
* yexuejc.base.version=1.3.9
|
||||
|
||||
pom.xml
|
||||
```
|
||||
|
|
88
UPDATE.md
|
@ -1,70 +1,77 @@
|
|||
yexuejc-springboot 更新内容
|
||||
-------------------
|
||||
|
||||
#### version :2.1.0
|
||||
**time:2019-7-24 18:30:49** <br/>
|
||||
#### version :1.2.1
|
||||
**time:2019-7-27 09:39:24** <br/>
|
||||
**branch:** master <br/>
|
||||
**关联工程:** <br/>
|
||||
```
|
||||
springboot-base:1.3.9
|
||||
spring-boot-starter-parent:2.0.5.RELEASE
|
||||
spring-boot-starter-parent:1.5.16.RELEASE
|
||||
```
|
||||
**update:** <br/>
|
||||
1. 所有自动装配增加开关,默认不装配。装配方式请参考[本项目自动装配开关](doc/plugin/AutoConfigure.md)
|
||||
|
||||
|
||||
#
|
||||
#### version :2.0.6
|
||||
**time:2019年4月2日21:08:453** <br/>
|
||||
**branch:** master <br/>
|
||||
**关联工程:** <br/>
|
||||
```
|
||||
springboot-base:1.3.9
|
||||
spring-boot-starter-parent:2.0.5.RELEASE
|
||||
```
|
||||
**update:** <br/>
|
||||
1. 升级依赖
|
||||
2. 出入参加密 ParamsRequestBodyAdvice/ParamsResponseBodyAdvice 增加开关(默认关)
|
||||
|
||||
|
||||
#
|
||||
|
||||
#### version :2.0.5
|
||||
**time:2018-12-1 12:27:10** <br/>
|
||||
#### version :1.2.0
|
||||
**time:2018-12-1 12:19:06** <br/>
|
||||
**branch:** master <br/>
|
||||
**关联工程:** <br/>
|
||||
```
|
||||
springboot-base:1.2.4
|
||||
spring-boot-starter-parent:2.0.5.RELEASE
|
||||
spring-boot-starter-parent:1.5.16.RELEASE
|
||||
```
|
||||
**update:** <br/>
|
||||
1. security多方登录第一个稳定版<br/>
|
||||
支持账号登录、短信登录、第三方授权openid登录<br/>
|
||||
功能链接[security重构-多方登录](doc/SECURITY.md)
|
||||
|
||||
|
||||
#
|
||||
#### version :2.0.3
|
||||
**time:2018-11-9 16:58:06** <br/>
|
||||
|
||||
#### version :1.1.6-1.1.9
|
||||
**time:2018-11-21 15:03:01** <br/>
|
||||
**branch:** master <br/>
|
||||
**关联工程:** <br/>
|
||||
```
|
||||
springboot-base:1.2.1
|
||||
spring-boot-starter-parent:2.0.5.RELEASE
|
||||
spring-boot-starter-parent:1.5.16.RELEASE
|
||||
```
|
||||
**update:** <br/>
|
||||
1. security 登录开放处理
|
||||
#
|
||||
|
||||
#### version :1.1.5
|
||||
**time:2018年11月20日20:26:06** <br/>
|
||||
**branch:** master <br/>
|
||||
**关联工程:** <br/>
|
||||
```
|
||||
springboot-base:1.2.1
|
||||
spring-boot-starter-parent:1.5.16.RELEASE
|
||||
```
|
||||
**update:** <br/>
|
||||
1. 修复security登录
|
||||
#
|
||||
|
||||
#### version :1.1.4
|
||||
**time:2018-11-9 16:55:53** <br/>
|
||||
**branch:** master <br/>
|
||||
**关联工程:** <br/>
|
||||
```
|
||||
springboot-base:1.2.1
|
||||
spring-boot-starter-parent:1.5.16.RELEASE
|
||||
```
|
||||
**update:** <br/>
|
||||
1. 集成springboot security 多方登录
|
||||
2. 文档拆分
|
||||
|
||||
|
||||
#
|
||||
#### version :2.0.2
|
||||
**time:2018-10-27 16:42:08** <br/>
|
||||
|
||||
|
||||
#### version :1.1.3
|
||||
**time:2018-10-27 16:40:36** <br/>
|
||||
**branch:** master <br/>
|
||||
**关联工程:** <br/>
|
||||
```
|
||||
springboot-base:1.2.0
|
||||
spring-boot-starter-parent:2.0.5.RELEASE
|
||||
spring-boot-starter-parent:1.5.16.RELEASE
|
||||
```
|
||||
**update:** <br/>
|
||||
1. 日志优化,按天切割日志<br>
|
||||
|
@ -86,29 +93,28 @@ logging.path=/logs/yexuejc-springboot-parent
|
|||
```
|
||||
#
|
||||
|
||||
#### version :2.0.1
|
||||
**time:2018-9-28 15:25:30** <br/>
|
||||
**branch:** 2.x <br/>
|
||||
#### version :1.1.2
|
||||
**time:2018-9-28 15:23:32** <br/>
|
||||
**branch:** master <br/>
|
||||
**关联工程:** <br/>
|
||||
```
|
||||
springboot-base:1.1.9
|
||||
spring-boot-starter-parent:2.0.5.RELEASE
|
||||
spring-boot-starter-parent:1.5.16.RELEASE
|
||||
```
|
||||
**update:** <br/>
|
||||
1. 新增声明包
|
||||
#
|
||||
|
||||
#### version :2.0.0
|
||||
**time:2018-9-26 16:55:00** <br/>
|
||||
**branch:** 2.x <br/>
|
||||
#### version :1.1.1
|
||||
**time:2018-9-26 17:00:38** <br/>
|
||||
**branch:** master <br/>
|
||||
**关联工程:** <br/>
|
||||
```
|
||||
springboot-base:1.1.9
|
||||
spring-boot-starter-parent:2.0.5.RELEASE
|
||||
spring-boot-starter-parent:1.5.16.RELEASE
|
||||
```
|
||||
**update:** <br/>
|
||||
1. 升级依赖
|
||||
2. 2.x分支将基于springboot 2.x 开发
|
||||
#
|
||||
|
||||
#### version :1.1.0
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
|
||||
### 内部集成
|
||||
#
|
||||
* [(2.0.3-2.0.5)新增 集成security多方登录](SECURITY.md)
|
||||
单独使用例子工程:[https://github.com/yexuejc/springboot-security-login-simple](https://github.com/yexuejc/springboot-security-login-simple)
|
||||
* 1.2.1 项目所集成的插件都增加开关-默认关闭,升级版本请阅读[第三方集成具体使用](plugin/AutoConfigure.md)
|
||||
* [1.1.4新增 集成security登录](SECURITY.md)
|
||||
|
||||
* [1.0.6新增 针对API请求安全解决方案](PARAMS_RSA_DECRYPT_ENCRYPT.md)<br/>
|
||||
* [1.0.6新增 加密功能](PARAMS_RSA_DECRYPT_ENCRYPT.md)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#生成私钥
|
||||
keytool -genkey -alias lgfishing -keyalg RSA -keystore lgfishing2.keystore -keysize 1024 -validity 36500
|
||||
keytool -genkey -alias test -keyalg RSA -keystore test.keystore -keysize 1024 -validity 36500
|
||||
```
|
||||
输入密钥库口令:
|
||||
再次输入新口令:
|
||||
|
|
16
pom.xml
|
@ -5,7 +5,7 @@
|
|||
|
||||
<groupId>com.yexuejc.springboot</groupId>
|
||||
<artifactId>yexuejc-springboot-parent</artifactId>
|
||||
<version>2.1.0</version>
|
||||
<version>1.2.1</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
|
@ -15,16 +15,10 @@
|
|||
<!-- spring boot父级,包含了统一版本管理,统一插件管理等 -->
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.0.5.RELEASE</version>
|
||||
<!--<relativePath/>-->
|
||||
<!--lookup parent from repository-->
|
||||
<version>1.5.16.RELEASE</version>
|
||||
<!-- <relativePath/> lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
|
||||
<modules>
|
||||
<module>yexuejc-springboot-base</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<yexuejc.base.version>1.3.9</yexuejc.base.version>
|
||||
<repos.yexuejc.url>https://nexus.yexuejc.club/repository/</repos.yexuejc.url>
|
||||
|
@ -310,4 +304,8 @@
|
|||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
|
||||
<modules>
|
||||
<module>yexuejc-springboot-base</module>
|
||||
<module>yexuejc-springboot-example</module>
|
||||
</modules>
|
||||
</project>
|
||||
|
|
|
@ -9,9 +9,9 @@
|
|||
<parent>
|
||||
<groupId>com.yexuejc.springboot</groupId>
|
||||
<artifactId>yexuejc-springboot-parent</artifactId>
|
||||
<version>2.1.0</version>
|
||||
<version>1.2.1</version>
|
||||
<!-- 本地打包:使用相对关联路径 -->
|
||||
<!--<relativePath>../</relativePath>-->
|
||||
<!--<relativePath>../../yexuejc</relativePath>-->
|
||||
</parent>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
|
|
|
@ -1,19 +1,22 @@
|
|||
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.RedisPassword;
|
||||
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
|
||||
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
|
||||
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;
|
||||
|
@ -21,17 +24,25 @@ 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;
|
||||
|
||||
/**
|
||||
* 多个database配置
|
||||
* 对redis 多个databasse封装
|
||||
*
|
||||
* @author maxf
|
||||
* @PackageName com.yexuejc.springboot.base.autoconfigure
|
||||
* @version 1.0
|
||||
* @ClassName MutiRedisAutoConfiguration
|
||||
* @Description
|
||||
* @date 2018/9/26 15:27
|
||||
* @date 2018/11/1 10:31
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass({JedisConnection.class, RedisOperations.class, Jedis.class})
|
||||
|
@ -39,6 +50,7 @@ import java.net.UnknownHostException;
|
|||
@Order(1)
|
||||
@ConditionalOnProperty(name = "yexuejc.autoconfigure.redis.enable", matchIfMissing = false)
|
||||
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";
|
||||
|
@ -71,93 +83,206 @@ public class MutiRedisAutoConfiguration {
|
|||
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;
|
||||
|
||||
public RedisConnectionConfiguration(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 = "yexuejc.redis.db0", matchIfMissing = true)
|
||||
public JedisConnectionFactory redisConnectionFactory0() throws UnknownHostException {
|
||||
return createJedisConnectionFactory(0);
|
||||
return applyProperties(createJedisConnectionFactory(), 0);
|
||||
}
|
||||
|
||||
@Bean(BEAN_REDIS_FACTORY1)
|
||||
@ConditionalOnProperty(name = "yexuejc.redis.db1")
|
||||
public JedisConnectionFactory redisConnectionFactory1() throws UnknownHostException {
|
||||
return createJedisConnectionFactory(1);
|
||||
return applyProperties(createJedisConnectionFactory(), 1);
|
||||
}
|
||||
|
||||
@Bean(BEAN_REDIS_FACTORY2)
|
||||
@ConditionalOnProperty(name = "yexuejc.redis.db2")
|
||||
public JedisConnectionFactory redisConnectionFactory2() throws UnknownHostException {
|
||||
return createJedisConnectionFactory(2);
|
||||
return applyProperties(createJedisConnectionFactory(), 2);
|
||||
}
|
||||
|
||||
@Bean(BEAN_REDIS_FACTORY3)
|
||||
@ConditionalOnProperty(name = "yexuejc.redis.db3")
|
||||
public JedisConnectionFactory redisConnectionFactory3() throws UnknownHostException {
|
||||
return createJedisConnectionFactory(3);
|
||||
return applyProperties(createJedisConnectionFactory(), 3);
|
||||
}
|
||||
|
||||
@Bean(BEAN_REDIS_FACTORY4)
|
||||
@ConditionalOnProperty(name = "yexuejc.redis.db4")
|
||||
public JedisConnectionFactory redisConnectionFactory4() throws UnknownHostException {
|
||||
return createJedisConnectionFactory(4);
|
||||
return applyProperties(createJedisConnectionFactory(), 4);
|
||||
}
|
||||
|
||||
@Bean(BEAN_REDIS_FACTORY5)
|
||||
@ConditionalOnProperty(name = "yexuejc.redis.db5")
|
||||
public JedisConnectionFactory redisConnectionFactory5() throws UnknownHostException {
|
||||
return createJedisConnectionFactory(5);
|
||||
return applyProperties(createJedisConnectionFactory(), 5);
|
||||
}
|
||||
|
||||
@Bean(BEAN_REDIS_FACTORY6)
|
||||
@ConditionalOnProperty(name = "yexuejc.redis.db6")
|
||||
public JedisConnectionFactory redisConnectionFactory6() throws UnknownHostException {
|
||||
return createJedisConnectionFactory(6);
|
||||
return applyProperties(createJedisConnectionFactory(), 6);
|
||||
}
|
||||
|
||||
@Bean(BEAN_REDIS_FACTORY7)
|
||||
@ConditionalOnProperty(name = "yexuejc.redis.db7")
|
||||
public JedisConnectionFactory redisConnectionFactory7() throws UnknownHostException {
|
||||
return createJedisConnectionFactory(7);
|
||||
return applyProperties(createJedisConnectionFactory(), 7);
|
||||
}
|
||||
|
||||
@Bean(BEAN_REDIS_FACTORY8)
|
||||
@ConditionalOnProperty(name = "yexuejc.redis.db8")
|
||||
public JedisConnectionFactory redisConnectionFactory8() throws UnknownHostException {
|
||||
return createJedisConnectionFactory(8);
|
||||
return applyProperties(createJedisConnectionFactory(), 8);
|
||||
}
|
||||
|
||||
@Bean(BEAN_REDIS_FACTORY9)
|
||||
@ConditionalOnProperty(name = "yexuejc.redis.db9")
|
||||
public JedisConnectionFactory redisConnectionFactory9() throws UnknownHostException {
|
||||
return createJedisConnectionFactory(9);
|
||||
return applyProperties(createJedisConnectionFactory(), 9);
|
||||
}
|
||||
|
||||
private JedisConnectionFactory createJedisConnectionFactory(int database) {
|
||||
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
|
||||
redisStandaloneConfiguration.setHostName(properties.getHost());
|
||||
redisStandaloneConfiguration.setPort(properties.getPort());
|
||||
redisStandaloneConfiguration.setDatabase(database);
|
||||
redisStandaloneConfiguration.setPassword(RedisPassword.of(properties.getPassword()));
|
||||
|
||||
JedisClientConfiguration.JedisClientConfigurationBuilder jedisClientConfiguration = JedisClientConfiguration.builder();
|
||||
|
||||
JedisConnectionFactory factory = new JedisConnectionFactory(redisStandaloneConfiguration,
|
||||
jedisClientConfiguration.build());
|
||||
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.
|
||||
|
@ -344,4 +469,5 @@ public class MutiRedisAutoConfiguration {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import com.yexuejc.springboot.base.util.LogUtil;
|
|||
import com.yexuejc.springboot.base.util.SSLUtil;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnResource;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.yexuejc.springboot</groupId>
|
||||
<version>1.0.0</version>
|
||||
<artifactId>yexuejc-springboot-example</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<name>yexuejc-springboot-example</name>
|
||||
|
||||
<modules>
|
||||
<module>yexuejc-springboot-simple</module>
|
||||
<module>springboot-security-login-simple</module>
|
||||
</modules>
|
||||
</project>
|
|
@ -0,0 +1,27 @@
|
|||
/target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/build/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
.mvn/wrapper/maven-wrapper.properties
|
||||
.mvn/wrapper/maven-wrapper.jar
|
|
@ -0,0 +1,245 @@
|
|||
https://github.com/yexuejc/yexuejc-springboot 多方登录模块使用例子
|
||||
---------------------------------------------------------------
|
||||
|
||||
#### 先上[效果图](Securtity效果图.md)
|
||||
|
||||
> **引入依赖 pom.xml**
|
||||
|
||||
```mxml
|
||||
<dependency>
|
||||
<groupId>com.yexuejc.springboot</groupId>
|
||||
<artifactId>yexuejc-springboot-base</artifactId>
|
||||
<version>最新版</version>
|
||||
</dependency>
|
||||
```
|
||||
#### 所有核心文件都在 com.yexuejc.springboot.base.security 包下
|
||||
#### 现附上系统实现逻辑图
|
||||
![多方登录系统实现逻辑图](sl/多方登录设计.jpg)
|
||||
|
||||
|
||||
1.com.yexuejc.springboot.base.security.SecurityConfig
|
||||
<br/>
|
||||
**Security 核心,本文件并未启动Security,需继承;然后继承类上加上@EnableWebSecurity注解就启动Security了。**
|
||||
|
||||
* 实现loadUserByUsername()方法;自定义逻辑处理登录账号,返回登录账号相关信息
|
||||
* 实现loginHodler()方法;自定义处理登录成功filter.setAuthenticationSuccessHandler()和失败filter.setAuthenticationFailureHandler()的处理
|
||||
* 继承configure(HttpSecurity http) 完善更多security过滤配置
|
||||
* 例子[com.yexuejc.springboot.base.security.MySecurityConfig](../yexuejc-springboot-base/src/test/java/com/yexuejc/springboot/base/security/MySecurityConfig.java)
|
||||
|
||||
#### 注: 代码中抛出的相关异常拦截在filter.setAuthenticationFailureHandler()中处理,参考[MySecurityConfig](../yexuejc-springboot-base/src/test/java/com/yexuejc/springboot/base/security/MySecurityConfig.java)
|
||||
```
|
||||
filter.setAuthenticationFailureHandler((request, response, exception) -> {
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.setStatus(HttpStatus.UNAUTHORIZED.value());
|
||||
Resps resps = new Resps();
|
||||
if (exception instanceof DisabledException) {
|
||||
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_IS_LOCK_MSG});
|
||||
} else if (exception instanceof AccountExpiredException) {
|
||||
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_IS_EXPIRE_MSG});
|
||||
} else if (exception instanceof CredentialsExpiredException) {
|
||||
resps.setErr(BizConsts.BASE_LOGIN_IS_EXPIRE_CODE, new String[]{BizConsts.BASE_LOGIN_IS_EXPIRE_MSG});
|
||||
} else if (exception instanceof LockedException) {
|
||||
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_IS_LOCKED_MSG});
|
||||
} else if (exception instanceof AuthenticationCredentialsNotFoundException) {
|
||||
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_CREDENTIALS_NOT_FOUND_MSG});
|
||||
} else if (exception instanceof ThirdPartyAuthorizationException) {
|
||||
resps.setErr(RespsConsts.CODE_FAIL, new String[]{exception.getMessage()});
|
||||
} else if (exception instanceof BadCredentialsException) {
|
||||
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_PWD_IS_ERR_MSG});
|
||||
} else if (exception instanceof UsernameNotFoundException) {
|
||||
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_ACCOUNT_NOT_FOUND_MSG});
|
||||
} else if (exception instanceof UserNotAuthoriayException) {
|
||||
resps.setErr(RespsConsts.CODE_FAIL, new String[]{exception.getMessage()});
|
||||
} else {
|
||||
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_SYS_ERR_MSG});
|
||||
}
|
||||
response.getWriter().write(JsonUtil.obj2Json(resps));
|
||||
response.getWriter().close();
|
||||
});
|
||||
```
|
||||
|
||||
2.com.yexuejc.springboot.base.security.UserDetailsManager
|
||||
<br/>
|
||||
**获取登录用户信息**
|
||||
* 需要实现com.yexuejc.springboot.base.security.inte.UserService
|
||||
* 例子[com.yexuejc.springboot.base.security.UserServiceImpl](../yexuejc-springboot-base/src/test/java/com/yexuejc/springboot/base/security/UserServiceImpl.java)
|
||||
|
||||
3.com.yexuejc.springboot.base.security.LoginToken
|
||||
<br/>
|
||||
**登录成功封装至JWT的登录用户信息**
|
||||
|
||||
|
||||
4.com.yexuejc.springboot.base.security.ConsumerUser
|
||||
<br/>
|
||||
**登录成功封装至redis的登录用户信息**
|
||||
|
||||
5.com.yexuejc.springboot.base.security.ConsumerToken
|
||||
<br/>
|
||||
**登录请求时(/login)用户登录参数信息**
|
||||
|
||||
6.com.yexuejc.springboot.base.security.ConsumerSecurityContextRepository
|
||||
<br/>
|
||||
**登录校验token正确性,返回登录用户(从redis中获取)**
|
||||
|
||||
7.com.yexuejc.springboot.base.security.ConsumerAuthenticationProvider
|
||||
<br/>
|
||||
**登录时账号校验(原为密码校验,重写之后增加校验短信验证码,第三方openid)**
|
||||
|
||||
8.com.yexuejc.springboot.base.security.ConsumerAuthenticationProcessingFilter
|
||||
<br/>
|
||||
**重写登录拦截,集成多种登录方式到/login**
|
||||
|
||||
<h2>使用example</h2>
|
||||
|
||||
1. 下载本项目至本地,找到yexuejc/yexuejc-springboot/yexuejc-springboot-base/src/test/java/com/yexuejc/springboot/base/ApplicationRun.java
|
||||
至接run
|
||||
2. 测试环境配置如下(测试运行环境都在test下面)<br/>
|
||||
2.1 pom.xml<br/>
|
||||
* mybatis-plus数据库框架
|
||||
* HikariCP数据库连接池
|
||||
* 本地数据库H2
|
||||
* JJWT作为登录凭证token
|
||||
* redis 存储登录用户信息
|
||||
> 关于这些相关框架、工具不做详解,有兴趣可以去学习,这些都可以用你自己熟悉的替换
|
||||
|
||||
com.yexuejc.springboot版本请依赖最新版本
|
||||
```
|
||||
<parent>
|
||||
<groupId>com.yexuejc.springboot</groupId>
|
||||
<artifactId>yexuejc-springboot-parent</artifactId>
|
||||
<version>2.0.3</version>
|
||||
</parent>
|
||||
<properties>
|
||||
<yexuejc.base.version>1.2.1</yexuejc.base.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<!--base 引用-->
|
||||
<dependency>
|
||||
<groupId>com.yexuejc.springboot</groupId>
|
||||
<artifactId>yexuejc-springboot-base</artifactId>
|
||||
<version>${parent.version}</version>
|
||||
</dependency>
|
||||
<!--https://gitee.com/incloudcode/yexuejc-base.git-->
|
||||
<dependency>
|
||||
<groupId>com.yexuejc.base</groupId>
|
||||
<artifactId>yexuejc-base</artifactId>
|
||||
<version>${yexuejc.base.version}</version>
|
||||
</dependency>
|
||||
<!-- 使用springMVC -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<!-- Spring Security -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<!-- JJWT -->
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<!-- 使用Redis -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-redis</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>redis.clients</groupId>
|
||||
<artifactId>jedis</artifactId>
|
||||
</dependency>
|
||||
<!-- HikariCP数据库连接池(JDK1.8) -->
|
||||
<dependency>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
</dependency>
|
||||
<!-- springboot mybatis-plus-->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<!-- 内存数据库h2-->
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>yexuejc-nexus-public</id>
|
||||
<name>yexuejc-nexus-public</name>
|
||||
<url>https://nexus.yexuejc.club/repository/maven-public/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
```
|
||||
|
||||
2.2 对应的application.properties<br/>
|
||||
* redis 0库存储登录用户信息,1库存储短信验证码
|
||||
* H2数据库 创建数据库表 consumer(用户表) [schema.sql](../yexuejc-springboot-base/src/test/resources/db/schema.sql);
|
||||
增加一条用户数据[data.sql](../yexuejc-springboot-base/src/test/resources/db/data.sql)
|
||||
<br/>启动项目后会自动运行这两个脚本,自此H2数据库中就会有一条用户数据,测试时可以用来登录
|
||||
<br/>PS:项目运行成功后可以访问 http://localhost:8888/h2-console 登录到数据库
|
||||
|
||||
* mybatis-plus 详情[http://mp.baomidou.com/](http://mp.baomidou.com/)
|
||||
|
||||
```
|
||||
#========================================================================================================================
|
||||
# security相关
|
||||
#reids
|
||||
#开启指定redis库db0默认开启
|
||||
yexuejc.redis.db1=true
|
||||
spring.redis.jedis.pool.max-active=100
|
||||
spring.redis.jedis.pool.max-idle=10
|
||||
spring.redis.jedis.pool.min-idle=3
|
||||
spring.redis.host=121.42.165.89
|
||||
spring.redis.password=
|
||||
spring.redis.port=16379
|
||||
|
||||
|
||||
#db
|
||||
|
||||
spring.h2.console.path=/h2-console
|
||||
spring.h2.console.enabled=true
|
||||
spring.h2.console.settings.web-allow-others=true
|
||||
spring.datasource.username=sa
|
||||
spring.datasource.password=123456
|
||||
spring.datasource.url=jdbc:h2:mem:test;MODE=PostgreSQL
|
||||
spring.datasource.driver-class-name=org.h2.Driver
|
||||
spring.datasource.schema=classpath:db/schema.sql
|
||||
spring.datasource.data=classpath:db/data.sql
|
||||
|
||||
#========================================================================================================================
|
||||
#mybatis-plus
|
||||
mybatis-plus.mapper-locations=classpath*:mapper/*.xml
|
||||
#实体扫描,多个package用逗号或者分号分隔
|
||||
mybatis-plus.type-aliases-package=com.yexuejc.springboot.base.security.domain
|
||||
#主键类型0:"数据库ID自增", 1:"用户输入ID",2:"该类型为未设置主键类型", 3:"全局唯一ID UUID",4:全局唯一ID (UUID),5:字符串全局唯一ID (idWorker 的字符串表示);
|
||||
mybatis-plus.global-config.db-config.id-type=uuid
|
||||
mybatis-plus.global-config.db-config.db-type=POSTGRE_SQL
|
||||
#字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
|
||||
mybatis-plus.global-config.db-config.field-strategy=not_empty
|
||||
#驼峰下划线转换
|
||||
mybatis-plus.global-config.db-config.column-underline=true
|
||||
#逻辑删除配置(下面3个配置)
|
||||
mybatis-plus.global-config.db-config.logic-delete-value=true
|
||||
mybatis-plus.global-config.db-config.logic-not-delete-value=false
|
||||
#配置返回数据库(column下划线命名&&返回java实体是驼峰命名),自动匹配无需as(没开启这个,SQL需要写as: select user_id as userId)
|
||||
mybatis-plus.configuration.map-underscore-to-camel-case=true
|
||||
mybatis-plus.configuration.cache-enabled=false
|
||||
#========================================================================================================================
|
||||
```
|
||||
> 附图
|
||||
|
||||
![security1.png](security1.png)
|
||||
<br>
|
||||
![security2.png](security2.png)
|
||||
<br>
|
||||
![security3.png](security3.png)
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
Security 多方登录封装使用效果图
|
||||
---------------
|
||||
### 账号登录
|
||||
密码错误
|
||||
![](sl/sl_02.png)
|
||||
正确
|
||||
![](sl/sl_01.png)
|
||||
|
||||
### 短信登录
|
||||
发送短信
|
||||
![](sl/sl_ss.png)
|
||||
短信错误
|
||||
![](sl/sl_err.jpg)
|
||||
短信过期
|
||||
![](sl/sl_gq.png)
|
||||
正确
|
||||
![](sl/sl_10.png)
|
||||
|
||||
|
||||
### 第三方登录
|
||||
第一次登录,需要绑定手机号
|
||||
![](sl/sl_t3.png)
|
||||
绑定过手机号的第三方账号登录(绑定相关业务需要自己实现)
|
||||
![](sl/sl_t4.png)
|
|
@ -0,0 +1,286 @@
|
|||
#!/bin/sh
|
||||
# ----------------------------------------------------------------------------
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Maven2 Start Up Batch script
|
||||
#
|
||||
# Required ENV vars:
|
||||
# ------------------
|
||||
# JAVA_HOME - location of a JDK home dir
|
||||
#
|
||||
# Optional ENV vars
|
||||
# -----------------
|
||||
# M2_HOME - location of maven2's installed home dir
|
||||
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
# e.g. to debug Maven itself, use
|
||||
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
if [ -z "$MAVEN_SKIP_RC" ] ; then
|
||||
|
||||
if [ -f /etc/mavenrc ] ; then
|
||||
. /etc/mavenrc
|
||||
fi
|
||||
|
||||
if [ -f "$HOME/.mavenrc" ] ; then
|
||||
. "$HOME/.mavenrc"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# OS specific support. $var _must_ be set to either true or false.
|
||||
cygwin=false;
|
||||
darwin=false;
|
||||
mingw=false
|
||||
case "`uname`" in
|
||||
CYGWIN*) cygwin=true ;;
|
||||
MINGW*) mingw=true;;
|
||||
Darwin*) darwin=true
|
||||
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
|
||||
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
if [ -x "/usr/libexec/java_home" ]; then
|
||||
export JAVA_HOME="`/usr/libexec/java_home`"
|
||||
else
|
||||
export JAVA_HOME="/Library/Java/Home"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
if [ -r /etc/gentoo-release ] ; then
|
||||
JAVA_HOME=`java-config --jre-home`
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$M2_HOME" ] ; then
|
||||
## resolve links - $0 may be a link to maven's home
|
||||
PRG="$0"
|
||||
|
||||
# need this for relative symlinks
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG="`dirname "$PRG"`/$link"
|
||||
fi
|
||||
done
|
||||
|
||||
saveddir=`pwd`
|
||||
|
||||
M2_HOME=`dirname "$PRG"`/..
|
||||
|
||||
# make it fully qualified
|
||||
M2_HOME=`cd "$M2_HOME" && pwd`
|
||||
|
||||
cd "$saveddir"
|
||||
# echo Using m2 at $M2_HOME
|
||||
fi
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||
if $cygwin ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --unix "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
|
||||
fi
|
||||
|
||||
# For Mingw, ensure paths are in UNIX format before anything is touched
|
||||
if $mingw ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME="`(cd "$M2_HOME"; pwd)`"
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
|
||||
# TODO classpath?
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
javaExecutable="`which javac`"
|
||||
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
|
||||
# readlink(1) is not available as standard on Solaris 10.
|
||||
readLink=`which readlink`
|
||||
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
|
||||
if $darwin ; then
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
|
||||
else
|
||||
javaExecutable="`readlink -f \"$javaExecutable\"`"
|
||||
fi
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
|
||||
JAVA_HOME="$javaHome"
|
||||
export JAVA_HOME
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$JAVACMD" ] ; then
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
else
|
||||
JAVACMD="`which java`"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
echo "Error: JAVA_HOME is not defined correctly." >&2
|
||||
echo " We cannot execute $JAVACMD" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
echo "Warning: JAVA_HOME environment variable is not set."
|
||||
fi
|
||||
|
||||
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
|
||||
|
||||
# traverses directory structure from process work directory to filesystem root
|
||||
# first directory with .mvn subdirectory is considered project base directory
|
||||
find_maven_basedir() {
|
||||
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
echo "Path not specified to find_maven_basedir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
basedir="$1"
|
||||
wdir="$1"
|
||||
while [ "$wdir" != '/' ] ; do
|
||||
if [ -d "$wdir"/.mvn ] ; then
|
||||
basedir=$wdir
|
||||
break
|
||||
fi
|
||||
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
|
||||
if [ -d "${wdir}" ]; then
|
||||
wdir=`cd "$wdir/.."; pwd`
|
||||
fi
|
||||
# end of workaround
|
||||
done
|
||||
echo "${basedir}"
|
||||
}
|
||||
|
||||
# concatenates all lines of a file
|
||||
concat_lines() {
|
||||
if [ -f "$1" ]; then
|
||||
echo "$(tr -s '\n' ' ' < "$1")"
|
||||
fi
|
||||
}
|
||||
|
||||
BASE_DIR=`find_maven_basedir "$(pwd)"`
|
||||
if [ -z "$BASE_DIR" ]; then
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
##########################################################################################
|
||||
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
# This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
##########################################################################################
|
||||
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found .mvn/wrapper/maven-wrapper.jar"
|
||||
fi
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
|
||||
fi
|
||||
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
|
||||
while IFS="=" read key value; do
|
||||
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
|
||||
esac
|
||||
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Downloading from: $jarUrl"
|
||||
fi
|
||||
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
|
||||
|
||||
if command -v wget > /dev/null; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found wget ... using wget"
|
||||
fi
|
||||
wget "$jarUrl" -O "$wrapperJarPath"
|
||||
elif command -v curl > /dev/null; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found curl ... using curl"
|
||||
fi
|
||||
curl -o "$wrapperJarPath" "$jarUrl"
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Falling back to using Java to download"
|
||||
fi
|
||||
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
|
||||
if [ -e "$javaClass" ]; then
|
||||
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Compiling MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
# Compiling the Java class
|
||||
("$JAVA_HOME/bin/javac" "$javaClass")
|
||||
fi
|
||||
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||
# Running the downloader
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Running MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
##########################################################################################
|
||||
# End of extension
|
||||
##########################################################################################
|
||||
|
||||
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo $MAVEN_PROJECTBASEDIR
|
||||
fi
|
||||
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --path --windows "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
|
||||
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
|
||||
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
|
||||
fi
|
||||
|
||||
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
exec "$JAVACMD" \
|
||||
$MAVEN_OPTS \
|
||||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
|
|
@ -0,0 +1,161 @@
|
|||
@REM ----------------------------------------------------------------------------
|
||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||
@REM or more contributor license agreements. See the NOTICE file
|
||||
@REM distributed with this work for additional information
|
||||
@REM regarding copyright ownership. The ASF licenses this file
|
||||
@REM to you under the Apache License, Version 2.0 (the
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM http://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@REM KIND, either express or implied. See the License for the
|
||||
@REM specific language governing permissions and limitations
|
||||
@REM under the License.
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Maven2 Start Up Batch script
|
||||
@REM
|
||||
@REM Required ENV vars:
|
||||
@REM JAVA_HOME - location of a JDK home dir
|
||||
@REM
|
||||
@REM Optional ENV vars
|
||||
@REM M2_HOME - location of maven2's installed home dir
|
||||
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
|
||||
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
@REM e.g. to debug Maven itself, use
|
||||
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||
@echo off
|
||||
@REM set title of command window
|
||||
title %0
|
||||
@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
|
||||
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||
|
||||
@REM set %HOME% to equivalent of $HOME
|
||||
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||
|
||||
@REM Execute a user defined script before this one
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
|
||||
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
|
||||
:skipRcPre
|
||||
|
||||
@setlocal
|
||||
|
||||
set ERROR_CODE=0
|
||||
|
||||
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||
@setlocal
|
||||
|
||||
@REM ==== START VALIDATION ====
|
||||
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME not found in your environment. >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
:OkJHome
|
||||
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
@REM ==== END VALIDATION ====
|
||||
|
||||
:init
|
||||
|
||||
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||
@REM Fallback to current working directory if not found.
|
||||
|
||||
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||
|
||||
set EXEC_DIR=%CD%
|
||||
set WDIR=%EXEC_DIR%
|
||||
:findBaseDir
|
||||
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||
cd ..
|
||||
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||
set WDIR=%CD%
|
||||
goto findBaseDir
|
||||
|
||||
:baseDirFound
|
||||
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||
cd "%EXEC_DIR%"
|
||||
goto endDetectBaseDir
|
||||
|
||||
:baseDirNotFound
|
||||
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||
cd "%EXEC_DIR%"
|
||||
|
||||
:endDetectBaseDir
|
||||
|
||||
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||
|
||||
@setlocal EnableExtensions EnableDelayedExpansion
|
||||
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||
|
||||
:endReadAdditionalConfig
|
||||
|
||||
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
|
||||
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
|
||||
FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO (
|
||||
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
|
||||
)
|
||||
|
||||
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
if exist %WRAPPER_JAR% (
|
||||
echo Found %WRAPPER_JAR%
|
||||
) else (
|
||||
echo Couldn't find %WRAPPER_JAR%, downloading it ...
|
||||
echo Downloading from: %DOWNLOAD_URL%
|
||||
powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"
|
||||
echo Finished downloading %WRAPPER_JAR%
|
||||
)
|
||||
@REM End of extension
|
||||
|
||||
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
|
||||
if ERRORLEVEL 1 goto error
|
||||
goto end
|
||||
|
||||
:error
|
||||
set ERROR_CODE=1
|
||||
|
||||
:end
|
||||
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
|
||||
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
|
||||
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
|
||||
:skipRcPost
|
||||
|
||||
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||
if "%MAVEN_BATCH_PAUSE%" == "on" pause
|
||||
|
||||
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
|
||||
|
||||
exit /B %ERROR_CODE%
|
|
@ -0,0 +1,101 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.yexuejc.springboot</groupId>
|
||||
<artifactId>springboot-security-login-simple</artifactId>
|
||||
<version>0.0.1</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>springboot-security-login-simple</name>
|
||||
<description>
|
||||
https://gitee.com/incloudcode/yexuejc-springboot使用例子
|
||||
</description>
|
||||
|
||||
<parent>
|
||||
<groupId>com.yexuejc.springboot</groupId>
|
||||
<artifactId>yexuejc-springboot-parent</artifactId>
|
||||
<version>1.2.1</version>
|
||||
</parent>
|
||||
<properties>
|
||||
<yexuejc.base.version>1.3.9</yexuejc.base.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<!--base 引用-->
|
||||
<dependency>
|
||||
<groupId>com.yexuejc.springboot</groupId>
|
||||
<artifactId>yexuejc-springboot-base</artifactId>
|
||||
<version>${parent.version}</version>
|
||||
</dependency>
|
||||
<!--https://gitee.com/incloudcode/yexuejc-base.git-->
|
||||
<dependency>
|
||||
<groupId>top.yexuejc</groupId>
|
||||
<artifactId>yexuejc-base</artifactId>
|
||||
<version>${yexuejc.base.version}</version>
|
||||
</dependency>
|
||||
<!-- 使用springMVC -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<!-- Spring Security -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<!-- JJWT -->
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<!-- 使用Redis -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-redis</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>redis.clients</groupId>
|
||||
<artifactId>jedis</artifactId>
|
||||
</dependency>
|
||||
<!-- HikariCP数据库连接池(JDK1.8) -->
|
||||
<dependency>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
</dependency>
|
||||
<!-- springboot mybatis-plus-->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<!-- 内存数据库h2-->
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>yexuejc-nexus-public</id>
|
||||
<name>yexuejc-nexus-public</name>
|
||||
<url>https://nexus.yexuejc.club/repository/maven-public/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
</project>
|
After Width: | Height: | Size: 108 KiB |
After Width: | Height: | Size: 52 KiB |
After Width: | Height: | Size: 56 KiB |
After Width: | Height: | Size: 63 KiB |
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 41 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 70 KiB |
After Width: | Height: | Size: 69 KiB |
After Width: | Height: | Size: 240 KiB |
|
@ -0,0 +1,12 @@
|
|||
package com.example.demo;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class DemoApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(DemoApplication.class, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package com.example.demo.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||
import com.example.demo.security.domain.Consumer;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author yexuejc
|
||||
* @since 2018-05-27
|
||||
*/
|
||||
@Mapper
|
||||
public interface ConsumerMapper extends BaseMapper<Consumer> {
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 插入一条记录
|
||||
* </p>
|
||||
*
|
||||
* @param entity 实体对象
|
||||
* @return int
|
||||
*/
|
||||
@Override
|
||||
int insert(Consumer entity);
|
||||
|
||||
|
||||
/**
|
||||
* 修改权限
|
||||
*
|
||||
* @param entity
|
||||
* @return
|
||||
*/
|
||||
Integer updateRoles(@Param(Constants.ENTITY) Consumer entity);
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package com.example.demo.mapper.handler;
|
||||
|
||||
import com.yexuejc.base.util.JsonUtil;
|
||||
import org.apache.ibatis.type.BaseTypeHandler;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
import org.apache.ibatis.type.MappedTypes;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* 数据库查询转换 -> JSON
|
||||
*/
|
||||
@MappedTypes({Object.class})
|
||||
public class JsonTypeHandler extends BaseTypeHandler<Object> {
|
||||
|
||||
@Override
|
||||
public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
|
||||
throws SQLException {
|
||||
if (parameter == null) {
|
||||
ps.setString(i, null);
|
||||
} else {
|
||||
ps.setString(i, JsonUtil.obj2Json(parameter));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
|
||||
if (rs.getString(columnName) == null) {
|
||||
return null;
|
||||
}
|
||||
return JsonUtil.json2Obj(rs.getString(columnName), Object.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
|
||||
if (rs.getString(columnIndex) == null) {
|
||||
return null;
|
||||
}
|
||||
return JsonUtil.json2Obj(rs.getString(columnIndex), Object.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
|
||||
if (cs.getString(columnIndex) == null) {
|
||||
return null;
|
||||
}
|
||||
return JsonUtil.json2Obj(cs.getString(columnIndex), Object.class);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,224 @@
|
|||
package com.example.demo.security;
|
||||
|
||||
import com.yexuejc.base.constant.RespsConsts;
|
||||
import com.yexuejc.base.http.Resps;
|
||||
import com.yexuejc.base.util.JsonUtil;
|
||||
import com.yexuejc.base.util.JwtUtil;
|
||||
import com.yexuejc.base.util.RegexUtil;
|
||||
import com.yexuejc.base.util.StrUtil;
|
||||
import com.yexuejc.springboot.base.autoconfigure.MutiRedisAutoConfiguration;
|
||||
import com.yexuejc.springboot.base.constant.BizConsts;
|
||||
import com.yexuejc.springboot.base.exception.ThirdPartyAuthorizationException;
|
||||
import com.yexuejc.springboot.base.exception.UserNotAuthoriayException;
|
||||
import com.yexuejc.springboot.base.security.ConsumerAuthenticationProcessingFilter;
|
||||
import com.yexuejc.springboot.base.security.ConsumerUser;
|
||||
import com.yexuejc.springboot.base.security.LoginToken;
|
||||
import com.yexuejc.springboot.base.security.SecurityConfig;
|
||||
import com.yexuejc.springboot.base.security.inte.UserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.authentication.*;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.WebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.security.web.context.SecurityContextRepository;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author maxf
|
||||
* @version 1.0
|
||||
* @ClassName SecurityConfig
|
||||
* @Description
|
||||
* @date 2018/11/8 17:30
|
||||
*/
|
||||
@EnableWebSecurity(debug = false)
|
||||
public class MySecurityConfig extends SecurityConfig {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("userserviceimpl")
|
||||
UserService userService;
|
||||
|
||||
@Override
|
||||
protected UserService getUserService() {
|
||||
return userService;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
@Qualifier(MutiRedisAutoConfiguration.BEAN_REDIS_TEMPLATE0)
|
||||
private RedisTemplate<Object, Object> redisTemplate0;
|
||||
|
||||
@Override
|
||||
protected RedisTemplate<Object, Object> getRedisDB() {
|
||||
return redisTemplate0;
|
||||
}
|
||||
|
||||
//自定义==================================================================
|
||||
|
||||
@Override
|
||||
protected AuthenticationProvider createConsumerAuthenticationProvider(UserDetailsService userDetailsService) {
|
||||
return super.createConsumerAuthenticationProvider(userDetailsService);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConsumerAuthenticationProcessingFilter createConsumerAuthenticationProcessingFilter(AuthenticationManager authenticationManager) {
|
||||
return super.createConsumerAuthenticationProcessingFilter(authenticationManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SecurityContextRepository createConsumerSecurityContextRepository() {
|
||||
return super.createConsumerSecurityContextRepository();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UserDetailsService createUserDetailsManager() {
|
||||
return super.createUserDetailsManager();
|
||||
}
|
||||
//自定义==================================================================
|
||||
|
||||
|
||||
/**
|
||||
* 保存登录信息至redis
|
||||
*
|
||||
* @param redisTemplate0 redis 链接
|
||||
* @param user 登录用户
|
||||
* @param roles 角色信息
|
||||
* @param token 登录token
|
||||
* @param isPast 是否设置过期
|
||||
*/
|
||||
private void saveLoginUser(RedisTemplate<Object, Object> redisTemplate0, ConsumerUser user, List<String> roles, String token,
|
||||
boolean isPast) {
|
||||
Map<String, Object> m = new HashMap<>(4);
|
||||
m.put("username", user.getUsername());
|
||||
m.put("token", token);
|
||||
m.put("roles", roles);
|
||||
m.put("id", user.getId());
|
||||
m.put("logType", user.getLogType());
|
||||
m.put("logTime", user.getLogTime());
|
||||
redisTemplate0.opsForHash().putAll(BizConsts.CONSUMER_LOGIN_REDIS + "." + user.getUsername(), m);
|
||||
if (isPast) {
|
||||
//对于没有绑定手机号的token,10分钟后过期
|
||||
redisTemplate0.expire(BizConsts.CONSUMER_LOGIN_REDIS + "." + user.getUsername(), 10, TimeUnit.MINUTES);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 处理登录
|
||||
* 成功: filter.setAuthenticationSuccessHandler()
|
||||
* 失败: filter.setAuthenticationFailureHandler()
|
||||
* </pre>
|
||||
*
|
||||
* @param filter
|
||||
*/
|
||||
@Override
|
||||
protected void loginHodler(ConsumerAuthenticationProcessingFilter filter) {
|
||||
filter.setAuthenticationSuccessHandler((request, response, authentication) -> {
|
||||
String token = JwtUtil.instace().compact(new LoginToken(authentication.getName()));
|
||||
ConsumerUser user = (ConsumerUser) authentication.getPrincipal();
|
||||
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
|
||||
List<String> roles = new ArrayList<>();
|
||||
if (authorities != null && authorities.size() > 0) {
|
||||
for (GrantedAuthority g : authorities) {
|
||||
roles.add(g.getAuthority());
|
||||
}
|
||||
}
|
||||
Map<String, Object> map = new HashMap<>(2);
|
||||
map.put("token", token);
|
||||
map.put("bindMobile", false);
|
||||
if (StrUtil.isEmpty(user.getUsername()) || !RegexUtil.regex(user.getUsername(), RegexUtil.REGEX_MOBILE)) {
|
||||
map.put("bindMobile", true);
|
||||
}
|
||||
saveLoginUser(redisTemplate0, user, roles, token, (Boolean) map.get("bindMobile"));
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.getWriter().write(JsonUtil.obj2Json(Resps.success().setSucc(map)));
|
||||
response.getWriter().close();
|
||||
});
|
||||
filter.setAuthenticationFailureHandler((request, response, exception) -> {
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.setStatus(HttpStatus.UNAUTHORIZED.value());
|
||||
Resps resps = new Resps();
|
||||
if (exception instanceof DisabledException) {
|
||||
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_IS_LOCK_MSG});
|
||||
} else if (exception instanceof AccountExpiredException) {
|
||||
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_IS_EXPIRE_MSG});
|
||||
} else if (exception instanceof CredentialsExpiredException) {
|
||||
resps.setErr(BizConsts.BASE_LOGIN_IS_EXPIRE_CODE, new String[]{BizConsts.BASE_LOGIN_IS_EXPIRE_MSG});
|
||||
} else if (exception instanceof LockedException) {
|
||||
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_IS_LOCKED_MSG});
|
||||
} else if (exception instanceof AuthenticationCredentialsNotFoundException) {
|
||||
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_CREDENTIALS_NOT_FOUND_MSG});
|
||||
} else if (exception instanceof ThirdPartyAuthorizationException) {
|
||||
resps.setErr(RespsConsts.CODE_FAIL, new String[]{exception.getMessage()});
|
||||
} else if (exception instanceof BadCredentialsException) {
|
||||
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_PWD_IS_ERR_MSG});
|
||||
} else if (exception instanceof UsernameNotFoundException) {
|
||||
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_ACCOUNT_NOT_FOUND_MSG});
|
||||
} else if (exception instanceof UserNotAuthoriayException) {
|
||||
resps.setErr(RespsConsts.CODE_FAIL, new String[]{exception.getMessage()});
|
||||
} else {
|
||||
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_SYS_ERR_MSG});
|
||||
}
|
||||
response.getWriter().write(JsonUtil.obj2Json(resps));
|
||||
response.getWriter().close();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
super.configure(http);
|
||||
http.headers().frameOptions().disable();
|
||||
/**
|
||||
* 权限控制
|
||||
* ->无权限
|
||||
*/
|
||||
http.authorizeRequests().antMatchers(
|
||||
"/", "/index"
|
||||
).permitAll();
|
||||
|
||||
/**
|
||||
* 权限控制
|
||||
* ->登录可访问
|
||||
*/
|
||||
http.authorizeRequests().antMatchers(
|
||||
"/consumer/**", "/sms/bind/**").authenticated();
|
||||
|
||||
// 登出处理。
|
||||
http.logout().logoutSuccessHandler((request, response, authentication) -> {
|
||||
redisTemplate0.delete(BizConsts.CONSUMER_LOGIN_REDIS + "." + authentication.getName());
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.getWriter().write(JsonUtil.obj2Json(Resps.success()));
|
||||
response.getWriter().close();
|
||||
});
|
||||
|
||||
// 未登录,却访问需要登录的接口时的处理
|
||||
http.exceptionHandling().authenticationEntryPoint((request, response, authException) -> {
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.setStatus(401);
|
||||
response.getWriter().write(
|
||||
JsonUtil.obj2Json(
|
||||
Resps.error(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_NOT_LOGIN_MSG})
|
||||
)
|
||||
);
|
||||
response.getWriter().close();
|
||||
});
|
||||
// 已登录,但当前用户没有访问的某个接口的权限时的处理
|
||||
http.exceptionHandling().accessDeniedHandler((request, response, accessDeniedException) -> {
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.setStatus(401);
|
||||
response.getWriter().write(
|
||||
JsonUtil.obj2Json(
|
||||
Resps.error(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_NOT_ROLE_MSG})
|
||||
)
|
||||
);
|
||||
response.getWriter().close();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,281 @@
|
|||
package com.example.demo.security.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||
import com.yexuejc.base.util.JsonUtil;
|
||||
import com.yexuejc.springboot.base.security.inte.User;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* <p>
|
||||
* </p>
|
||||
*
|
||||
* @author yexuejc
|
||||
* @since 2018-05-27
|
||||
*/
|
||||
@TableName(resultMap = "BaseResultMap")
|
||||
public class Consumer extends Model<Consumer> implements User {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
@TableId(value = "consumer_id", type = IdType.UUID)
|
||||
private String consumerId;
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
@TableField("mobile")
|
||||
private String mobile;
|
||||
/**
|
||||
* 密码:md5
|
||||
*/
|
||||
@TableField("pwd")
|
||||
private String pwd;
|
||||
/**
|
||||
* 账号是否启用
|
||||
*/
|
||||
@TableField("is_enable")
|
||||
private boolean enable;
|
||||
/**
|
||||
* 账号是否没有过期
|
||||
*/
|
||||
@TableField("is_non_expire")
|
||||
private boolean nonExpire;
|
||||
/**
|
||||
* 账号是否没有被锁定
|
||||
*/
|
||||
@TableField("is_non_lock")
|
||||
private boolean nonLock;
|
||||
/**
|
||||
* 微信id
|
||||
*/
|
||||
@TableField("wechat_id")
|
||||
private String wechatId;
|
||||
/**
|
||||
* qq id
|
||||
*/
|
||||
@TableField("qq_id")
|
||||
private String qqId;
|
||||
/**
|
||||
* 微博id
|
||||
*/
|
||||
@TableField("weibo_id")
|
||||
private String weiboId;
|
||||
/**
|
||||
* 昵称
|
||||
*/
|
||||
@TableField("nickname")
|
||||
private String nickname;
|
||||
/**
|
||||
* 用户头像
|
||||
*/
|
||||
@TableField("head")
|
||||
private String head;
|
||||
/**
|
||||
* 用户邮箱
|
||||
*/
|
||||
@TableField("email")
|
||||
private String email;
|
||||
/**
|
||||
* 用户姓别 '男',‘女’
|
||||
*/
|
||||
@TableField("sex")
|
||||
private String sex;
|
||||
/**
|
||||
* 角色、权限
|
||||
*/
|
||||
@TableField(value = "roles", el = "roles,typeHandler=com.yexuejc.guansc.core.mybatis.handler.JsonTypeHandler")
|
||||
private List<String> roles;
|
||||
/**
|
||||
* 支付密码
|
||||
*/
|
||||
@TableField("pay_pwd")
|
||||
private String payPwd;
|
||||
/**
|
||||
* 注册方式
|
||||
*/
|
||||
@TableField("reg_type")
|
||||
private String regType;
|
||||
/**
|
||||
* 第三方源头像路径
|
||||
*/
|
||||
@TableField("source_head")
|
||||
private String sourceHead;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return JsonUtil.obj2Json(this);
|
||||
}
|
||||
|
||||
public String getConsumerId() {
|
||||
return consumerId;
|
||||
}
|
||||
|
||||
public Consumer setConsumerId(String consumerId) {
|
||||
this.consumerId = consumerId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getMobile() {
|
||||
return mobile;
|
||||
}
|
||||
|
||||
public Consumer setMobile(String mobile) {
|
||||
this.mobile = mobile;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getPwd() {
|
||||
return pwd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getEnable() {
|
||||
return this.enable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getNonExpire() {
|
||||
return this.nonExpire;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getNonLock() {
|
||||
return this.nonLock;
|
||||
}
|
||||
|
||||
public Consumer setPwd(String pwd) {
|
||||
this.pwd = pwd;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Consumer setEnable(boolean enable) {
|
||||
this.enable = enable;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Consumer setNonExpire(boolean nonExpire) {
|
||||
this.nonExpire = nonExpire;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Consumer setNonLock(boolean nonLock) {
|
||||
this.nonLock = nonLock;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getWechatId() {
|
||||
return wechatId;
|
||||
}
|
||||
|
||||
public Consumer setWechatId(String wechatId) {
|
||||
this.wechatId = wechatId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getQqId() {
|
||||
return qqId;
|
||||
}
|
||||
|
||||
public Consumer setQqId(String qqId) {
|
||||
this.qqId = qqId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getWeiboId() {
|
||||
return weiboId;
|
||||
}
|
||||
|
||||
public Consumer setWeiboId(String weiboId) {
|
||||
this.weiboId = weiboId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getNickname() {
|
||||
return nickname;
|
||||
}
|
||||
|
||||
public Consumer setNickname(String nickname) {
|
||||
this.nickname = nickname;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getHead() {
|
||||
return head;
|
||||
}
|
||||
|
||||
public Consumer setHead(String head) {
|
||||
this.head = head;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public Consumer setEmail(String email) {
|
||||
this.email = email;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getSex() {
|
||||
return sex;
|
||||
}
|
||||
|
||||
public Consumer setSex(String sex) {
|
||||
this.sex = sex;
|
||||
return this;
|
||||
}
|
||||
|
||||
public List<String> getRoles() {
|
||||
return roles;
|
||||
}
|
||||
|
||||
public Consumer setRoles(List<String> roles) {
|
||||
this.roles = roles;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getPayPwd() {
|
||||
return payPwd;
|
||||
}
|
||||
|
||||
public Consumer setPayPwd(String payPwd) {
|
||||
this.payPwd = payPwd;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getRegType() {
|
||||
return regType;
|
||||
}
|
||||
|
||||
public Consumer setRegType(String regType) {
|
||||
this.regType = regType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getSourceHead() {
|
||||
return sourceHead;
|
||||
}
|
||||
|
||||
public Consumer setSourceHead(String sourceHead) {
|
||||
this.sourceHead = sourceHead;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Serializable pkVal() {
|
||||
return this.consumerId;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,383 @@
|
|||
package com.example.demo.security.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.example.demo.mapper.ConsumerMapper;
|
||||
import com.example.demo.security.domain.Consumer;
|
||||
import com.yexuejc.base.constant.RespsConsts;
|
||||
import com.yexuejc.base.pojo.ApiVO;
|
||||
import com.yexuejc.base.util.StrUtil;
|
||||
import com.yexuejc.springboot.base.autoconfigure.MutiRedisAutoConfiguration;
|
||||
import com.yexuejc.springboot.base.constant.BizConsts;
|
||||
import com.yexuejc.springboot.base.constant.DictRegTypeConsts;
|
||||
import com.yexuejc.springboot.base.constant.LogTypeConsts;
|
||||
import com.yexuejc.springboot.base.exception.ThirdPartyAuthorizationException;
|
||||
import com.yexuejc.springboot.base.security.ConsumerToken;
|
||||
import com.yexuejc.springboot.base.security.ConsumerUser;
|
||||
import com.yexuejc.springboot.base.security.inte.UserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 数据库操作DB
|
||||
*
|
||||
* @author maxf
|
||||
* @version 1.0
|
||||
* @ClassName UserServiceImpl
|
||||
* @Description
|
||||
* @date 2018/11/8 17:31
|
||||
*/
|
||||
@Service("userserviceimpl")
|
||||
public class UserServiceImpl implements UserService {
|
||||
@Autowired
|
||||
ConsumerMapper consumerMapper;
|
||||
|
||||
@Autowired
|
||||
@Qualifier(MutiRedisAutoConfiguration.BEAN_REDIS_TEMPLATE1)
|
||||
private RedisTemplate<Object, Object> redisTemplate;
|
||||
|
||||
/**
|
||||
* 根据用户名到数据库查询用户
|
||||
*
|
||||
* @param username 登录账号
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Object getConsumerByUserName(String username) {
|
||||
if (StrUtil.isEmpty(username)) {
|
||||
throw new UsernameNotFoundException("username为空,一般是第三方登录来的,直接抛出UsernameNotFoundException就是");
|
||||
}
|
||||
QueryWrapper queryWrapper = new QueryWrapper();
|
||||
queryWrapper.eq("mobile", username);
|
||||
Consumer consumer = consumerMapper.selectOne(queryWrapper);
|
||||
if (null == consumer) {
|
||||
/**
|
||||
* 1.抛出UsernameNotFoundException这个异常如果是第三方登录会走 {@link #checkOpenId(ConsumerToken)}
|
||||
* 2.抛出其他Exception可以自己到{@link MySecurityConfig#loginHodler(ConsumerAuthenticationProcessingFilter)}
|
||||
* 里面的filter.setAuthenticationFailureHandler()中做特殊处理
|
||||
*/
|
||||
throw new UsernameNotFoundException("没有该账号相关信息");
|
||||
}
|
||||
//h2不支持json,人为处理角色
|
||||
ArrayList roles = new ArrayList<>();
|
||||
roles.add("ROLE_CONSUMER");
|
||||
consumer.setRoles(roles);
|
||||
//1.consumer为User的实现类
|
||||
// return consumer;
|
||||
|
||||
//2. 自己创建ConsumerUser,直接返回
|
||||
List<GrantedAuthority> authorities = new ArrayList<>();
|
||||
for (String role : consumer.getRoles()) {
|
||||
authorities.add(new SimpleGrantedAuthority(role));
|
||||
}
|
||||
ConsumerUser consumerUser = new ConsumerUser(consumer.getMobile(), consumer.getPwd(),
|
||||
consumer.getEnable(), consumer.getNonExpire(), true, consumer.getNonLock(),
|
||||
authorities, consumer.getConsumerId(), null, System.currentTimeMillis());
|
||||
return consumerUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* 到自己的reids里面校验短信验证码
|
||||
*
|
||||
* @param smsType {@linkplain BizConsts.CONSUMER_LOGIN_SMS} 业务id reids使用
|
||||
* @param mobile 登录账号
|
||||
* @param code 短信验证码
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ApiVO checkSmsCode2Redis(String smsType, String mobile, String code) {
|
||||
redisTemplate.afterPropertiesSet();
|
||||
String rCode = (String) redisTemplate.opsForHash().get(smsType + "." + mobile, "code");
|
||||
Integer validatedNums = (Integer) redisTemplate.opsForHash().get(smsType + "." + mobile, "validatedNums");
|
||||
if (validatedNums == null) {
|
||||
return new ApiVO(ApiVO.STATUS.F, RespsConsts.CODE_FAIL, "验证码过期,请重新获取");
|
||||
} else if (validatedNums > 5) {
|
||||
redisTemplate.delete(smsType + "." + mobile);
|
||||
return new ApiVO(ApiVO.STATUS.F, RespsConsts.CODE_FAIL, "验证码过期,请重新获取");
|
||||
}
|
||||
if (code.equals(rCode)) {
|
||||
redisTemplate.delete(smsType + "." + mobile);
|
||||
return new ApiVO(ApiVO.STATUS.S);
|
||||
} else {
|
||||
validatedNums++;
|
||||
redisTemplate.opsForHash().put(smsType + "." + mobile, "validatedNums", validatedNums);
|
||||
return new ApiVO(ApiVO.STATUS.F, RespsConsts.CODE_FAIL, "验证码不正确");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 第三方登录
|
||||
* 校验openid 根据自己业务做判断
|
||||
*
|
||||
* @param consumerToken 登录信息
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Object checkOpenId(ConsumerToken consumerToken) {
|
||||
ApiVO apiVO = new ApiVO(ApiVO.STATUS.F, "没有找到用户信息");
|
||||
switch (consumerToken.getLogtype()) {
|
||||
case LogTypeConsts.QQ:
|
||||
apiVO = checkOpenid4QQ(consumerToken, true);
|
||||
break;
|
||||
case LogTypeConsts.WECHAT:
|
||||
apiVO = checkOpenid4Wechat(consumerToken, true);
|
||||
break;
|
||||
case LogTypeConsts.WEIBO:
|
||||
apiVO = checkOpenid4Weibo(consumerToken, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (apiVO.isFail()) {
|
||||
/**
|
||||
* 未查到:
|
||||
* 1.返回null会走(数据库没有这个openid[第三方账号]信息)新增流程 {@link #addConsumer(ConsumerToken)}
|
||||
* 2.也可以自己创建一个带有特殊标识的ConsumerUser,然后在 {@link MySecurityConfig#loginHodler(ConsumerAuthenticationProcessingFilter)}
|
||||
* 里面的filter.setAuthenticationSuccessHandler()中做特殊处理 ps:假装登录成功 :)
|
||||
*/
|
||||
return null;
|
||||
}
|
||||
//h2不支持json,人为处理角色
|
||||
ArrayList roles = new ArrayList<>();
|
||||
roles.add("ROLE_CONSUMER");
|
||||
apiVO.getObject1(Consumer.class).setRoles(roles);
|
||||
//根据openid到数据库查到consumer返回
|
||||
return apiVO.getObject1(Consumer.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link #checkOpenId(ConsumerToken)} 返回null会走该方法
|
||||
* 没有账号时处理自己的业务,此处必须返回 构造出的登录用户,否则会抛出{@link ThirdPartyAuthorizationException 第三方授权异常}
|
||||
* <br/>
|
||||
*
|
||||
* @param consumerToken 登录信息
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Object addConsumer(ConsumerToken consumerToken) {
|
||||
Consumer consumer = new Consumer();
|
||||
consumer.setConsumerId(StrUtil.genUUID());
|
||||
consumer.setMobile(StrUtil.isNotEmpty(consumerToken.getUsername()) ? consumerToken.getUsername() : consumerToken.getOpenid());
|
||||
consumer.setPwd(StrUtil.toMD5("123456"));
|
||||
consumer.setEnable(true);
|
||||
consumer.setNonExpire(true);
|
||||
consumer.setNonLock(true);
|
||||
List<String> roles = new ArrayList<>();
|
||||
roles.add("ROLE_CONSUMER");
|
||||
consumer.setRoles(roles);
|
||||
switch (consumerToken.getLogtype()) {
|
||||
case LogTypeConsts.SMS:
|
||||
ApiVO apiVO = checkSmsCode2Redis(BizConsts.CONSUMER_LOGIN_SMS, consumerToken.getUsername(),
|
||||
consumerToken.getSmscode());
|
||||
if (apiVO.isFail()) {
|
||||
throw new ThirdPartyAuthorizationException("短信验证码错误");
|
||||
}
|
||||
consumer.setNickname(consumerToken.getUsername());
|
||||
consumer.setHead("/head/def.png");
|
||||
consumer.setRegType(DictRegTypeConsts.DICT_MOBILE);
|
||||
break;
|
||||
case LogTypeConsts.QQ:
|
||||
consumer.setQqId(consumerToken.getOpenid());
|
||||
consumer.setNickname(consumerToken.getNickname());
|
||||
setHeader(consumerToken, consumer, false);
|
||||
setSex(consumerToken, consumer);
|
||||
consumer.setRegType(DictRegTypeConsts.DICT_QQ);
|
||||
break;
|
||||
case LogTypeConsts.WECHAT:
|
||||
consumer.setWechatId(consumerToken.getOpenid());
|
||||
consumer.setNickname(consumerToken.getNickname());
|
||||
setHeader(consumerToken, consumer, false);
|
||||
setSex(consumerToken, consumer);
|
||||
consumer.setRegType(DictRegTypeConsts.DICT_WECHAT);
|
||||
break;
|
||||
case LogTypeConsts.WEIBO:
|
||||
consumer.setWeiboId(consumerToken.getOpenid());
|
||||
consumer.setNickname(consumerToken.getNickname());
|
||||
setHeader(consumerToken, consumer, false);
|
||||
setSex(consumerToken, consumer);
|
||||
consumer.setRegType(DictRegTypeConsts.DICT_WEIBO);
|
||||
break;
|
||||
default:
|
||||
throw new ThirdPartyAuthorizationException("暂不支持该第三方授权");
|
||||
}
|
||||
Integer result = consumerMapper.insert(consumer);
|
||||
if (result < 1) {
|
||||
/**
|
||||
* 会抛出{@link ThirdPartyAuthorizationException 第三方授权异常}
|
||||
*/
|
||||
return null;
|
||||
}
|
||||
return consumer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 第三方登录 QQ登录
|
||||
*
|
||||
* @param consumerToken 登录信息
|
||||
* @param b
|
||||
* @return
|
||||
*/
|
||||
public ApiVO checkOpenid4QQ(ConsumerToken consumerToken, boolean b) {
|
||||
Consumer consumer = getConsumerByQQOpenid(consumerToken.getOpenid());
|
||||
if (consumer == null) {
|
||||
return new ApiVO(ApiVO.STATUS.F, "获取用户信息失败");
|
||||
}
|
||||
if (b && DictRegTypeConsts.DICT_QQ.equals(consumer.getRegType())) {
|
||||
//如果是qq注册的,登录的同时更新用户信息
|
||||
updateConsumer(consumer, consumerToken);
|
||||
}
|
||||
return new ApiVO(ApiVO.STATUS.S).setObject1(consumer);
|
||||
}
|
||||
|
||||
/**
|
||||
* 第三方登录 微信登录
|
||||
*
|
||||
* @param consumerToken 登录信息
|
||||
* @param b
|
||||
* @return
|
||||
*/
|
||||
public ApiVO checkOpenid4Wechat(ConsumerToken consumerToken, boolean b) {
|
||||
Consumer consumer = getConsumerByWechatOpenid(consumerToken.getOpenid());
|
||||
if (consumer == null) {
|
||||
return new ApiVO(ApiVO.STATUS.F, "获取用户信息失败");
|
||||
}
|
||||
if (b && DictRegTypeConsts.DICT_WECHAT.equals(consumer.getRegType())) {
|
||||
//如果是微信注册的,登录的同时更新用户信息
|
||||
updateConsumer(consumer, consumerToken);
|
||||
}
|
||||
return new ApiVO(ApiVO.STATUS.S).setObject1(consumer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 第三方登录 微博登录
|
||||
*
|
||||
* @param consumerToken 登录信息
|
||||
* @param b
|
||||
* @return
|
||||
*/
|
||||
public ApiVO checkOpenid4Weibo(ConsumerToken consumerToken, boolean b) {
|
||||
Consumer consumer = getConsumerByWeiboOpenid(consumerToken.getOpenid());
|
||||
if (consumer == null) {
|
||||
return new ApiVO(ApiVO.STATUS.F, "获取用户信息失败");
|
||||
}
|
||||
if (b && DictRegTypeConsts.DICT_WEIBO.equals(consumer.getRegType())) {
|
||||
//如果是微博注册的,登录的同时更新用户信息
|
||||
updateConsumer(consumer, consumerToken);
|
||||
}
|
||||
return new ApiVO(ApiVO.STATUS.S).setObject1(consumer);
|
||||
}
|
||||
|
||||
|
||||
public Consumer getConsumerByQQOpenid(String openid) {
|
||||
QueryWrapper queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("qq_id", openid);
|
||||
Consumer consumer = consumerMapper.selectOne(queryWrapper);
|
||||
return consumer;
|
||||
}
|
||||
|
||||
public Consumer getConsumerByWechatOpenid(String openid) {
|
||||
QueryWrapper queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("wechat_id", openid);
|
||||
Consumer consumer = consumerMapper.selectOne(queryWrapper);
|
||||
return consumer;
|
||||
}
|
||||
|
||||
public Consumer getConsumerByWeiboOpenid(String openid) {
|
||||
QueryWrapper queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("weibo_id", openid);
|
||||
Consumer consumer = consumerMapper.selectOne(queryWrapper);
|
||||
return consumer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 更新基本信息
|
||||
*
|
||||
* @param consumer
|
||||
* @param consumerToken
|
||||
*/
|
||||
private void updateConsumer(Consumer consumer, ConsumerToken consumerToken) {
|
||||
boolean b1, b2, b3;
|
||||
b1 = b2 = b3 = true;
|
||||
if (StrUtil.isNotEmpty(consumerToken.getNickname())) {
|
||||
if (consumerToken.getNickname().equals(consumer.getNickname())) {
|
||||
b1 = false;
|
||||
}
|
||||
consumer.setNickname(consumerToken.getNickname());
|
||||
}
|
||||
b2 = setHeader(consumerToken, consumer, true);
|
||||
b3 = setSex(consumerToken, consumer);
|
||||
if (!b1 && !b2 && !b3) {
|
||||
return;
|
||||
}
|
||||
LambdaUpdateWrapper<Consumer> queryWrapper = new UpdateWrapper<>(new Consumer()).lambda();
|
||||
try {
|
||||
queryWrapper.set(Consumer::getNickname, consumer.getNickname())
|
||||
.set(Consumer::getHead, consumer.getHead())
|
||||
.set(Consumer::getSex, consumer.getSex())
|
||||
.eq(Consumer::getConsumerId, consumer.getConsumerId());
|
||||
consumerMapper.update(new Consumer(), queryWrapper);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置头像->上传网络图片到OSS
|
||||
*
|
||||
* @param consumerToken
|
||||
* @param consumer
|
||||
* @param isUpdate
|
||||
*/
|
||||
private boolean setHeader(ConsumerToken consumerToken, Consumer consumer, boolean isUpdate) {
|
||||
if (StrUtil.isNotEmpty(consumerToken.getHead())) {
|
||||
if (isUpdate) {
|
||||
if (consumerToken.getHead().equals(consumer.getSourceHead())) {
|
||||
//未改变头像
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
consumer.setSourceHead(consumerToken.getHead());
|
||||
}
|
||||
//应该上传至OSS后返回OSS地址
|
||||
consumer.setHead(consumerToken.getHead());
|
||||
// try {
|
||||
// consumer.setHead(putOss4Head(null, consumerToken.getHead()));
|
||||
// } catch (ImageException e) {
|
||||
// return false;
|
||||
// }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置性别
|
||||
*
|
||||
* @param consumerToken
|
||||
* @param consumer
|
||||
*/
|
||||
private boolean setSex(ConsumerToken consumerToken, Consumer consumer) {
|
||||
if (StrUtil.isNotEmpty(consumerToken.getSex())) {
|
||||
if ("1".equals(consumerToken.getSex()) && !"男".equals(consumer.getSex())) {
|
||||
consumer.setSex("男");
|
||||
return true;
|
||||
} else if ("2".equals(consumerToken.getSex()) && !"女".equals(consumer.getSex())) {
|
||||
consumer.setSex("女");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
package com.example.demo.web;
|
||||
|
||||
import com.yexuejc.base.http.Resps;
|
||||
import com.yexuejc.base.pojo.ApiVO;
|
||||
import com.yexuejc.base.util.RegexUtil;
|
||||
import com.yexuejc.base.util.StrUtil;
|
||||
import com.yexuejc.springboot.base.autoconfigure.MutiRedisAutoConfiguration;
|
||||
import com.yexuejc.springboot.base.constant.BizConsts;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Security 登录注册相关controller
|
||||
* 主要实现
|
||||
* 1.短信登录发送验证码
|
||||
* 2.第三方登录绑定手机号(以及绑定手机号发送验证码)
|
||||
* </pre>
|
||||
*
|
||||
* @author maxf
|
||||
* @version 1.0
|
||||
* @ClassName SecurityCtrl
|
||||
* @Description
|
||||
* @date 2018/11/9 10:52
|
||||
*/
|
||||
@RestController
|
||||
public class SecurityCtrl {
|
||||
|
||||
@Autowired
|
||||
@Qualifier(MutiRedisAutoConfiguration.BEAN_REDIS_TEMPLATE1)
|
||||
RedisTemplate<Object, Object> redisTemplate;
|
||||
|
||||
/**
|
||||
* 登录发送短信
|
||||
*
|
||||
* @param mobile
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/login/{mobile}", method = RequestMethod.POST)
|
||||
public Resps login(@PathVariable String mobile) {
|
||||
if (!RegexUtil.regex(mobile, RegexUtil.REGEX_MOBILE)) {
|
||||
return Resps.fail("手机号不正确");
|
||||
}
|
||||
ApiVO apiVO = sendSmsCode(BizConsts.CONSUMER_LOGIN_SMS, mobile);
|
||||
if (apiVO.isFail()) {
|
||||
return Resps.fail(apiVO.getMsg());
|
||||
}
|
||||
return Resps.success(apiVO.getMsg());
|
||||
}
|
||||
|
||||
private ApiVO sendSmsCode(String smsType, String mobile) {
|
||||
String smsId = StrUtil.genUUID(30);
|
||||
String code = StrUtil.genNum().substring(2, 8);
|
||||
//自己接入短信发送
|
||||
boolean result = true;
|
||||
if (result) {
|
||||
//成功
|
||||
//存reids
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("smsId", smsId);
|
||||
map.put("code", code);
|
||||
map.put("trade_id", "短信返回id");
|
||||
map.put("validatedNums", 0);
|
||||
redisTemplate.afterPropertiesSet();
|
||||
redisTemplate.opsForHash().putAll(smsType + "." + mobile, map);
|
||||
// 过期时间:5分钟
|
||||
redisTemplate.expire(smsType + "." + mobile, 5 * 60, TimeUnit.SECONDS);
|
||||
return new ApiVO(ApiVO.STATUS.S, "短信发送成功");
|
||||
} else {
|
||||
return new ApiVO(ApiVO.STATUS.F, "短信发送失败");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
logging.level.root=info
|
||||
|
||||
#========================================================================================================================
|
||||
#========================================================================================================================
|
||||
#核心
|
||||
#开启功能 redis webmvc
|
||||
yexuejc.autoconfigure.redis.enable=true
|
||||
#webmvc 包含以下功能
|
||||
yexuejc.autoconfigure.webmvc.enable=true
|
||||
#全局异常处理
|
||||
yexuejc.ssl-ignore.enable=true
|
||||
#开启HTTPS(SSL)请求证书验证忽略
|
||||
yexuejc.global.exception.enable=true
|
||||
#开启校验过滤器,目前校验HTTP Header是否符合规范
|
||||
yexuejc.web.validation-filter.enable=true
|
||||
# 拦截类型(请求路径):0忽略模式,默认拦截全部;1拦截模式,默认一个都不拦截
|
||||
yexuejc.http.filter=0
|
||||
#忽略路径:示例放开swagger
|
||||
yexuejc.http.filter.ignored=/,/swagger/**,/error,/v2/api-docs,/webjars/**
|
||||
#========================================================================================================================
|
||||
#========================================================================================================================
|
||||
#========================================================================================================================
|
||||
# security相关
|
||||
#reids
|
||||
#开启指定redis库db0默认开启
|
||||
yexuejc.redis.db1=true
|
||||
spring.redis.jedis.pool.max-active=100
|
||||
spring.redis.jedis.pool.max-idle=10
|
||||
spring.redis.jedis.pool.min-idle=3
|
||||
spring.redis.host=121.42.165.89
|
||||
spring.redis.password=
|
||||
spring.redis.port=16379
|
||||
|
||||
|
||||
#db
|
||||
|
||||
spring.h2.console.path=/h2-console
|
||||
spring.h2.console.enabled=true
|
||||
spring.h2.console.settings.web-allow-others=true
|
||||
spring.datasource.username=sa
|
||||
spring.datasource.password=123456
|
||||
spring.datasource.url=jdbc:h2:mem:test;MODE=PostgreSQL
|
||||
spring.datasource.driver-class-name=org.h2.Driver
|
||||
spring.datasource.schema=classpath:db/schema.sql
|
||||
spring.datasource.data=classpath:db/data.sql
|
||||
|
||||
#========================================================================================================================
|
||||
#mybatis-plus
|
||||
mybatis-plus.mapper-locations=classpath*:mapper/*.xml
|
||||
#实体扫描,多个package用逗号或者分号分隔
|
||||
mybatis-plus.type-aliases-package=com.yexuejc.springboot.base.security.domain
|
||||
#主键类型0:"数据库ID自增", 1:"用户输入ID",2:"该类型为未设置主键类型", 3:"全局唯一ID UUID",4:全局唯一ID (UUID),5:字符串全局唯一ID (idWorker 的字符串表示);
|
||||
mybatis-plus.global-config.db-config.id-type=uuid
|
||||
mybatis-plus.global-config.db-config.db-type=POSTGRE_SQL
|
||||
#字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
|
||||
mybatis-plus.global-config.db-config.field-strategy=not_empty
|
||||
#驼峰下划线转换
|
||||
mybatis-plus.global-config.db-config.column-underline=true
|
||||
#逻辑删除配置(下面3个配置)
|
||||
mybatis-plus.global-config.db-config.logic-delete-value=true
|
||||
mybatis-plus.global-config.db-config.logic-not-delete-value=false
|
||||
#配置返回数据库(column下划线命名&&返回java实体是驼峰命名),自动匹配无需as(没开启这个,SQL需要写as: select user_id as userId)
|
||||
mybatis-plus.configuration.map-underscore-to-camel-case=true
|
||||
mybatis-plus.configuration.cache-enabled=false
|
||||
#========================================================================================================================
|
|
@ -0,0 +1,34 @@
|
|||
INSERT INTO consumer (consumer_id,
|
||||
mobile,
|
||||
pwd,
|
||||
is_enable,
|
||||
is_non_expire,
|
||||
is_non_lock,
|
||||
wechat_id,
|
||||
qq_id,
|
||||
weibo_id,
|
||||
nickname,
|
||||
head,
|
||||
email,
|
||||
sex,
|
||||
roles,
|
||||
pay_pwd,
|
||||
reg_type,
|
||||
source_head)
|
||||
VALUES ('119d8c62b8b04154a073b3f6c3d9e14f',
|
||||
'18202837563',
|
||||
'e10adc3949ba59abbe56e057f20f883e',
|
||||
't',
|
||||
't',
|
||||
't',
|
||||
'ogIXq0HrDq3kS6MAHqMI1RUqBrGw',
|
||||
NULL,
|
||||
NULL,
|
||||
'18202837563',
|
||||
'head/6dc93e2e0809426ca8a9e6ede30b0b50.JPEG',
|
||||
NULL,
|
||||
'男',
|
||||
'[ROLE_CONSUMER, ROLE_LAYER]',
|
||||
NULL,
|
||||
'S',
|
||||
'https://wx.qlogo.cn/mmopen/vi_32/MftzC3yHluDbjZ9c3sYEibUuXNkC3pha8E6pibZO3Wh0Zop0bqHLcltjmrENc4R8Xm6oJECQGibAxZot1v9PR1hsw/132');
|
|
@ -0,0 +1,42 @@
|
|||
CREATE TABLE consumer (
|
||||
consumer_id varchar(32) NOT NULL DEFAULT NULL::character varying,
|
||||
mobile varchar(50) NOT NULL DEFAULT NULL::character varying,
|
||||
pwd varchar(32) DEFAULT NULL::character varying,
|
||||
is_enable bool DEFAULT true,
|
||||
is_non_expire bool DEFAULT true,
|
||||
is_non_lock bool DEFAULT true,
|
||||
wechat_id varchar(50) DEFAULT NULL::character varying,
|
||||
qq_id varchar(50) DEFAULT NULL::character varying,
|
||||
weibo_id varchar(50) DEFAULT NULL::character varying,
|
||||
nickname varchar(50) DEFAULT NULL::character varying,
|
||||
head varchar(255) DEFAULT NULL::character varying,
|
||||
email varchar(32) DEFAULT NULL::character varying,
|
||||
sex varchar(1) DEFAULT NULL::character varying,
|
||||
roles varchar(255),
|
||||
pay_pwd varchar(32) DEFAULT NULL::character varying,
|
||||
reg_type varchar(10) ,
|
||||
source_head varchar(255)
|
||||
)
|
||||
;
|
||||
COMMENT ON COLUMN consumer.consumer_id IS '用户id';
|
||||
COMMENT ON COLUMN consumer.mobile IS '手机号';
|
||||
COMMENT ON COLUMN consumer.pwd IS '密码:md5';
|
||||
COMMENT ON COLUMN consumer.is_enable IS '账号是否启用';
|
||||
COMMENT ON COLUMN consumer.is_non_expire IS '账号是否没有过期';
|
||||
COMMENT ON COLUMN consumer.is_non_lock IS '账号是否没有被锁定';
|
||||
COMMENT ON COLUMN consumer.wechat_id IS '微信id';
|
||||
COMMENT ON COLUMN consumer.qq_id IS 'qq id';
|
||||
COMMENT ON COLUMN consumer.weibo_id IS '微博id';
|
||||
COMMENT ON COLUMN consumer.nickname IS '昵称';
|
||||
COMMENT ON COLUMN consumer.head IS '用户头像';
|
||||
COMMENT ON COLUMN consumer.email IS '用户邮箱';
|
||||
COMMENT ON COLUMN consumer.sex IS '用户姓别 ''男'',‘女’';
|
||||
COMMENT ON COLUMN consumer.roles IS '角色、权限';
|
||||
COMMENT ON COLUMN consumer.pay_pwd IS '支付密码';
|
||||
COMMENT ON COLUMN consumer.reg_type IS '注册方式';
|
||||
COMMENT ON COLUMN consumer.source_head IS '第三方源头像路径';
|
||||
|
||||
-- ----------------------------
|
||||
-- Primary Key structure for table consumer
|
||||
-- ----------------------------
|
||||
ALTER TABLE consumer ADD CONSTRAINT consumer_pkey PRIMARY KEY (consumer_id);
|
|
@ -0,0 +1,82 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.example.demo.mapper.ConsumerMapper">
|
||||
|
||||
<!-- 通用查询映射结果 -->
|
||||
<resultMap id="BaseResultMap" type="com.example.demo.security.domain.Consumer">
|
||||
<id column="consumer_id" property="consumerId"/>
|
||||
<result column="mobile" property="mobile"/>
|
||||
<result column="pwd" property="pwd"/>
|
||||
<result column="is_enable" property="enable"/>
|
||||
<result column="is_non_expire" property="nonExpire"/>
|
||||
<result column="is_non_lock" property="nonLock"/>
|
||||
<result column="wechat_id" property="wechatId"/>
|
||||
<result column="qq_id" property="qqId"/>
|
||||
<result column="weibo_id" property="weiboId"/>
|
||||
<result column="nickname" property="nickname"/>
|
||||
<result column="head" property="head"/>
|
||||
<result column="email" property="email"/>
|
||||
<result column="sex" property="sex"/>
|
||||
<result column="roles" property="roles"
|
||||
typeHandler="com.example.demo.mapper.handler.JsonTypeHandler"/>
|
||||
<result column="pay_pwd" property="payPwd"/>
|
||||
<result column="reg_type" property="regType"/>
|
||||
<result column="source_head" property="sourceHead"/>
|
||||
</resultMap>
|
||||
|
||||
<insert id="insert">
|
||||
INSERT INTO consumer (consumer_id,
|
||||
mobile,
|
||||
pwd,
|
||||
is_enable,
|
||||
is_non_expire,
|
||||
is_non_lock,
|
||||
wechat_id,
|
||||
qq_id,
|
||||
weibo_id,
|
||||
nickname,
|
||||
head,
|
||||
email,
|
||||
sex,
|
||||
roles,
|
||||
pay_pwd,
|
||||
reg_type,
|
||||
source_head)
|
||||
VALUES (#{consumerId},
|
||||
#{mobile},
|
||||
#{pwd},
|
||||
#{enable},
|
||||
#{nonExpire},
|
||||
#{nonLock},
|
||||
#{wechatId},
|
||||
#{qqId},
|
||||
#{weiboId},
|
||||
#{nickname},
|
||||
#{head},
|
||||
#{email},
|
||||
#{sex},
|
||||
#{roles,typeHandler=com.example.demo.mapper.handler.JsonTypeHandler},
|
||||
#{payPwd},
|
||||
#{regType},
|
||||
#{sourceHead});
|
||||
</insert>
|
||||
|
||||
<select id="selectOne" resultMap="BaseResultMap">
|
||||
select * from consumer
|
||||
<where>${ew.sqlSegment}</where>
|
||||
</select>
|
||||
|
||||
<update id="updateRoles">
|
||||
update consumer
|
||||
<set>
|
||||
<if test='et.roles!=null'>
|
||||
roles = #{et.roles,typeHandler=com.example.demo.mapper.handler.JsonTypeHandler},
|
||||
</if>
|
||||
mdfy_time=now(),
|
||||
mdfy_by=#{et.mdfyBy}
|
||||
</set>
|
||||
where
|
||||
consumer_id=#{et.consumerId}
|
||||
</update>
|
||||
|
||||
</mapper>
|
|
@ -0,0 +1,16 @@
|
|||
package com.example.demo;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
public class DemoApplicationTests {
|
||||
|
||||
@Test
|
||||
public void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
HELP.md
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**
|
||||
!**/src/test/**
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
|
@ -0,0 +1,63 @@
|
|||
# yexuejc-springboot-simple
|
||||
|
||||
### 说明
|
||||
>本工程是yexuejc-springboot的使用示例,新接入请参考本工程
|
||||
|
||||
#### 什么都不用
|
||||
<details>
|
||||
<summary>直接新建一个springboot工程 pom.xml 配置</summary>
|
||||
|
||||
```
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.yexuejc.springboot</groupId>
|
||||
<artifactId>yexuejc-springboot-parent</artifactId>
|
||||
<version>1.2.1</version>
|
||||
</parent>
|
||||
<groupId>top.yexuejc</groupId>
|
||||
<artifactId>yexuejc-springboot-simple</artifactId>
|
||||
<version>0.0.1</version>
|
||||
<name>yexuejc-springboot-simple</name>
|
||||
<description>测试工程</description>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.yexuejc.springboot</groupId>
|
||||
<artifactId>yexuejc-springboot-base</artifactId>
|
||||
<version>1.2.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
||||
```
|
||||
</details>
|
||||
|
||||
#### 使用多端登录
|
||||
参考[使用多端登录](../springboot-security-login-simple/README.md)
|
|
@ -0,0 +1,286 @@
|
|||
#!/bin/sh
|
||||
# ----------------------------------------------------------------------------
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Maven2 Start Up Batch script
|
||||
#
|
||||
# Required ENV vars:
|
||||
# ------------------
|
||||
# JAVA_HOME - location of a JDK home dir
|
||||
#
|
||||
# Optional ENV vars
|
||||
# -----------------
|
||||
# M2_HOME - location of maven2's installed home dir
|
||||
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
# e.g. to debug Maven itself, use
|
||||
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
if [ -z "$MAVEN_SKIP_RC" ] ; then
|
||||
|
||||
if [ -f /etc/mavenrc ] ; then
|
||||
. /etc/mavenrc
|
||||
fi
|
||||
|
||||
if [ -f "$HOME/.mavenrc" ] ; then
|
||||
. "$HOME/.mavenrc"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# OS specific support. $var _must_ be set to either true or false.
|
||||
cygwin=false;
|
||||
darwin=false;
|
||||
mingw=false
|
||||
case "`uname`" in
|
||||
CYGWIN*) cygwin=true ;;
|
||||
MINGW*) mingw=true;;
|
||||
Darwin*) darwin=true
|
||||
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
|
||||
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
if [ -x "/usr/libexec/java_home" ]; then
|
||||
export JAVA_HOME="`/usr/libexec/java_home`"
|
||||
else
|
||||
export JAVA_HOME="/Library/Java/Home"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
if [ -r /etc/gentoo-release ] ; then
|
||||
JAVA_HOME=`java-config --jre-home`
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$M2_HOME" ] ; then
|
||||
## resolve links - $0 may be a link to maven's home
|
||||
PRG="$0"
|
||||
|
||||
# need this for relative symlinks
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG="`dirname "$PRG"`/$link"
|
||||
fi
|
||||
done
|
||||
|
||||
saveddir=`pwd`
|
||||
|
||||
M2_HOME=`dirname "$PRG"`/..
|
||||
|
||||
# make it fully qualified
|
||||
M2_HOME=`cd "$M2_HOME" && pwd`
|
||||
|
||||
cd "$saveddir"
|
||||
# echo Using m2 at $M2_HOME
|
||||
fi
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||
if $cygwin ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --unix "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
|
||||
fi
|
||||
|
||||
# For Mingw, ensure paths are in UNIX format before anything is touched
|
||||
if $mingw ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME="`(cd "$M2_HOME"; pwd)`"
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
|
||||
# TODO classpath?
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
javaExecutable="`which javac`"
|
||||
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
|
||||
# readlink(1) is not available as standard on Solaris 10.
|
||||
readLink=`which readlink`
|
||||
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
|
||||
if $darwin ; then
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
|
||||
else
|
||||
javaExecutable="`readlink -f \"$javaExecutable\"`"
|
||||
fi
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
|
||||
JAVA_HOME="$javaHome"
|
||||
export JAVA_HOME
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$JAVACMD" ] ; then
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
else
|
||||
JAVACMD="`which java`"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
echo "Error: JAVA_HOME is not defined correctly." >&2
|
||||
echo " We cannot execute $JAVACMD" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
echo "Warning: JAVA_HOME environment variable is not set."
|
||||
fi
|
||||
|
||||
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
|
||||
|
||||
# traverses directory structure from process work directory to filesystem root
|
||||
# first directory with .mvn subdirectory is considered project base directory
|
||||
find_maven_basedir() {
|
||||
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
echo "Path not specified to find_maven_basedir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
basedir="$1"
|
||||
wdir="$1"
|
||||
while [ "$wdir" != '/' ] ; do
|
||||
if [ -d "$wdir"/.mvn ] ; then
|
||||
basedir=$wdir
|
||||
break
|
||||
fi
|
||||
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
|
||||
if [ -d "${wdir}" ]; then
|
||||
wdir=`cd "$wdir/.."; pwd`
|
||||
fi
|
||||
# end of workaround
|
||||
done
|
||||
echo "${basedir}"
|
||||
}
|
||||
|
||||
# concatenates all lines of a file
|
||||
concat_lines() {
|
||||
if [ -f "$1" ]; then
|
||||
echo "$(tr -s '\n' ' ' < "$1")"
|
||||
fi
|
||||
}
|
||||
|
||||
BASE_DIR=`find_maven_basedir "$(pwd)"`
|
||||
if [ -z "$BASE_DIR" ]; then
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
##########################################################################################
|
||||
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
# This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
##########################################################################################
|
||||
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found .mvn/wrapper/maven-wrapper.jar"
|
||||
fi
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
|
||||
fi
|
||||
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
|
||||
while IFS="=" read key value; do
|
||||
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
|
||||
esac
|
||||
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Downloading from: $jarUrl"
|
||||
fi
|
||||
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
|
||||
|
||||
if command -v wget > /dev/null; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found wget ... using wget"
|
||||
fi
|
||||
wget "$jarUrl" -O "$wrapperJarPath"
|
||||
elif command -v curl > /dev/null; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found curl ... using curl"
|
||||
fi
|
||||
curl -o "$wrapperJarPath" "$jarUrl"
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Falling back to using Java to download"
|
||||
fi
|
||||
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
|
||||
if [ -e "$javaClass" ]; then
|
||||
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Compiling MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
# Compiling the Java class
|
||||
("$JAVA_HOME/bin/javac" "$javaClass")
|
||||
fi
|
||||
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||
# Running the downloader
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Running MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
##########################################################################################
|
||||
# End of extension
|
||||
##########################################################################################
|
||||
|
||||
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo $MAVEN_PROJECTBASEDIR
|
||||
fi
|
||||
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --path --windows "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
|
||||
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
|
||||
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
|
||||
fi
|
||||
|
||||
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
exec "$JAVACMD" \
|
||||
$MAVEN_OPTS \
|
||||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
|
|
@ -0,0 +1,161 @@
|
|||
@REM ----------------------------------------------------------------------------
|
||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||
@REM or more contributor license agreements. See the NOTICE file
|
||||
@REM distributed with this work for additional information
|
||||
@REM regarding copyright ownership. The ASF licenses this file
|
||||
@REM to you under the Apache License, Version 2.0 (the
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM https://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@REM KIND, either express or implied. See the License for the
|
||||
@REM specific language governing permissions and limitations
|
||||
@REM under the License.
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Maven2 Start Up Batch script
|
||||
@REM
|
||||
@REM Required ENV vars:
|
||||
@REM JAVA_HOME - location of a JDK home dir
|
||||
@REM
|
||||
@REM Optional ENV vars
|
||||
@REM M2_HOME - location of maven2's installed home dir
|
||||
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
|
||||
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
@REM e.g. to debug Maven itself, use
|
||||
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||
@echo off
|
||||
@REM set title of command window
|
||||
title %0
|
||||
@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
|
||||
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||
|
||||
@REM set %HOME% to equivalent of $HOME
|
||||
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||
|
||||
@REM Execute a user defined script before this one
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
|
||||
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
|
||||
:skipRcPre
|
||||
|
||||
@setlocal
|
||||
|
||||
set ERROR_CODE=0
|
||||
|
||||
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||
@setlocal
|
||||
|
||||
@REM ==== START VALIDATION ====
|
||||
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME not found in your environment. >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
:OkJHome
|
||||
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
@REM ==== END VALIDATION ====
|
||||
|
||||
:init
|
||||
|
||||
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||
@REM Fallback to current working directory if not found.
|
||||
|
||||
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||
|
||||
set EXEC_DIR=%CD%
|
||||
set WDIR=%EXEC_DIR%
|
||||
:findBaseDir
|
||||
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||
cd ..
|
||||
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||
set WDIR=%CD%
|
||||
goto findBaseDir
|
||||
|
||||
:baseDirFound
|
||||
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||
cd "%EXEC_DIR%"
|
||||
goto endDetectBaseDir
|
||||
|
||||
:baseDirNotFound
|
||||
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||
cd "%EXEC_DIR%"
|
||||
|
||||
:endDetectBaseDir
|
||||
|
||||
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||
|
||||
@setlocal EnableExtensions EnableDelayedExpansion
|
||||
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||
|
||||
:endReadAdditionalConfig
|
||||
|
||||
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
|
||||
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
|
||||
FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO (
|
||||
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
|
||||
)
|
||||
|
||||
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
if exist %WRAPPER_JAR% (
|
||||
echo Found %WRAPPER_JAR%
|
||||
) else (
|
||||
echo Couldn't find %WRAPPER_JAR%, downloading it ...
|
||||
echo Downloading from: %DOWNLOAD_URL%
|
||||
powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"
|
||||
echo Finished downloading %WRAPPER_JAR%
|
||||
)
|
||||
@REM End of extension
|
||||
|
||||
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
|
||||
if ERRORLEVEL 1 goto error
|
||||
goto end
|
||||
|
||||
:error
|
||||
set ERROR_CODE=1
|
||||
|
||||
:end
|
||||
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
|
||||
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
|
||||
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
|
||||
:skipRcPost
|
||||
|
||||
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||
if "%MAVEN_BATCH_PAUSE%" == "on" pause
|
||||
|
||||
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
|
||||
|
||||
exit /B %ERROR_CODE%
|
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.yexuejc.springboot</groupId>
|
||||
<artifactId>yexuejc-springboot-parent</artifactId>
|
||||
<version>1.2.1</version>
|
||||
</parent>
|
||||
<groupId>top.yexuejc</groupId>
|
||||
<artifactId>yexuejc-springboot-simple</artifactId>
|
||||
<version>0.0.1</version>
|
||||
<name>yexuejc-springboot-simple</name>
|
||||
<description>测试工程</description>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.yexuejc.springboot</groupId>
|
||||
<artifactId>yexuejc-springboot-base</artifactId>
|
||||
<version>1.2.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,14 @@
|
|||
package top.yexuejc.springboot.simple;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
|
||||
@SpringBootApplication
|
||||
public class YexuejcSpringbootSimpleApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(YexuejcSpringbootSimpleApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
logging.level.root=info
|
|
@ -0,0 +1,16 @@
|
|||
package top.yexuejc.springboot.simple;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
public class YexuejcSpringbootSimpleApplicationTests {
|
||||
|
||||
@Test
|
||||
public void contextLoads() {
|
||||
}
|
||||
|
||||
}
|