# Conflicts: # user-service/src/main/java/com/hp/user/service/UserServiceApplaction.java # user-service/src/main/java/com/hp/user/service/config/SwaggerConfig1.javadev
@@ -9,5 +9,12 @@ package com.hp.user.client.service; | |||
* @since 2020-11-20 | |||
*/ | |||
public interface AccountService { | |||
/** | |||
* 登陆 | |||
* @param phone 手机号 | |||
* @param verificationCode 验证码 | |||
*/ | |||
public void login(String phone,String verificationCode); | |||
} |
@@ -0,0 +1,22 @@ | |||
package com.hp.user.client.service; | |||
/** | |||
* 信息服务 | |||
* @author yeqid | |||
* | |||
*/ | |||
public interface MessageService { | |||
/** | |||
* 发送验证码 | |||
* @param phone 手机号 | |||
*/ | |||
public void sendVerificationCode(String phone); | |||
/** | |||
* 获取验证码 | |||
* @param phone 手机号 | |||
* @return 返回验证码 | |||
*/ | |||
public String getVerificationCode(String phone); | |||
} |
@@ -157,6 +157,12 @@ | |||
<artifactId>jackson-databind</artifactId> | |||
<version>2.9.5</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>redis.clients</groupId> | |||
<artifactId>jedis</artifactId> | |||
<version>2.9.0</version> | |||
</dependency> | |||
@@ -1,12 +1,13 @@ | |||
package com.hp.user.service; | |||
import cn.nyhlw.doc2swagger.springswagger2.EnableSwagger2; | |||
import org.mybatis.spring.annotation.MapperScan; | |||
import org.springframework.boot.SpringApplication; | |||
import org.springframework.boot.autoconfigure.SpringBootApplication; | |||
import org.springframework.cache.annotation.EnableCaching; | |||
import org.springframework.context.annotation.ComponentScan; | |||
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource; | |||
import org.springframework.context.annotation.ComponentScan; | |||
import com.hp.user.service.redis.RedisOperation; | |||
/** | |||
* 用户服务启动类 | |||
@@ -17,8 +18,19 @@ import org.springframework.context.annotation.ComponentScan; | |||
@MapperScan("com.hp.user.service.dao") //扫描的mapper | |||
@SpringBootApplication | |||
@NacosPropertySource(dataId = "userdatasource", autoRefreshed = true) | |||
<<<<<<< HEAD | |||
======= | |||
//不能加compentscan,加了 | |||
//@ComponentScan("com.hp.user.service.dao")//这个地方不能写错,写错的话会出现2个问题,如果写的路径扫描不到swaggerconfig那么页面会报错 | |||
//(Unable to infer base url. This is common when using dynamic servlet registration or when the API is behind an API Gateway. | |||
//The base url is the root of where all the swagger resources are served. For e.g. if the api is available at http://example.org/api/v2/api-docs then the base url is http://example.org/api/. Please enter the location manually: ), | |||
//如果写的路径扫描不到controller那么页面不会有接口信息 | |||
//所以最好不要写 | |||
>>>>>>> 42c9261a99b7b4e4d5dc88f577e4b1385b75c668 | |||
public class UserServiceApplaction { | |||
public static void main(String[] args) { | |||
SpringApplication.run(UserServiceApplaction.class, args); | |||
System.out.println(RedisOperation.getRedis().get("tst")); | |||
RedisOperation.getRedis().close(); | |||
} | |||
} |
@@ -0,0 +1,50 @@ | |||
package com.hp.user.service.config; | |||
import org.springframework.context.annotation.Bean; | |||
import org.springframework.context.annotation.Configuration; | |||
//import cn.nyhlw.doc2swagger.springswagger2.EnableSwagger2; | |||
import springfox.documentation.builders.ApiInfoBuilder; | |||
import springfox.documentation.builders.PathSelectors; | |||
import springfox.documentation.builders.RequestHandlerSelectors; | |||
import springfox.documentation.service.ApiInfo; | |||
import springfox.documentation.spi.DocumentationType; | |||
import springfox.documentation.spring.web.plugins.Docket; | |||
import springfox.documentation.swagger2.annotations.EnableSwagger2; | |||
//这两个注释一定要有,没有以及EnableSwagger2依赖错误会报 | |||
//(Unable to infer base url. This is common when using dynamic servlet registration or when the API is behind an API Gateway. | |||
//The base url is the root of where all the swagger resources are served. For e.g. if the api is available at http://example.org/api/v2/api-docs then the base url is http://example.org/api/. Please enter the location manually: ), | |||
@Configuration | |||
@EnableSwagger2//并且这个注释要特别注意不能使用cn.nyhlw.doc2swagger.springswagger2.EnableSwagger2;一定要使用springfox.documentation.swagger2.annotations.EnableSwagger2; | |||
public class SwaggerConfig { | |||
public static final String VERSION = "1.0.0"; | |||
public static final String SWAGGER_SCAN_BASE_PACKAGE = "com.hp.user.service.controller"; | |||
@Bean | |||
public Docket createRestApi() { | |||
return new Docket(DocumentationType.SWAGGER_2) | |||
.apiInfo(apiInfo()) | |||
.select() | |||
.apis(RequestHandlerSelectors.basePackage(SWAGGER_SCAN_BASE_PACKAGE)) | |||
.paths(PathSelectors.any()) | |||
.build(); | |||
} | |||
private ApiInfo apiInfo() { | |||
return new ApiInfoBuilder() | |||
.title("rest doc user") | |||
.description("用户信息系统") | |||
// .termsOfServiceUrl("http://www.cnblogs.com/congc/") | |||
.version(VERSION) | |||
.build(); | |||
} | |||
// RestDocConfig _swaggerConfig() | |||
// { | |||
// return RestDocConfig.builder() | |||
// .apiTitle("rest doc user") | |||
// .apiDescription("用户信息系统") | |||
// .apiVersion("1.0.0") | |||
// .packages(Arrays.asList("com.hp.user.service.controller")) | |||
// .build(); | |||
// } | |||
} |
@@ -1,28 +1,39 @@ | |||
package com.hp.user.service.controller; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.web.bind.annotation.RequestMapping; | |||
import org.springframework.web.bind.annotation.RestController; | |||
import com.hp.user.client.service.AccountService; | |||
import io.swagger.annotations.Api; | |||
@RestController | |||
@RequestMapping("/authentication") | |||
@Api(value="身份认证") | |||
public class AuthenticationController { | |||
@Autowired | |||
private AccountService accountService; | |||
/** | |||
* 登录 | |||
* @param account 账号 | |||
* @param password 密码 | |||
* @param phone 账号 | |||
* @param verificationCode 验证码 | |||
*/ | |||
@RequestMapping("/login") | |||
public void login(String account,String password){ | |||
public void login(String phone,String verificationCode) { | |||
accountService.login(phone, verificationCode); | |||
} | |||
/** | |||
* 登出 | |||
*/ | |||
@RequestMapping("/loginOut") | |||
public void loginOut(){ | |||
public void loginOut() { | |||
} | |||
/** | |||
@@ -30,16 +41,10 @@ public class AuthenticationController { | |||
* 需要用户信息 | |||
*/ | |||
@RequestMapping("/register") | |||
public void register(){ | |||
public void register() { | |||
} | |||
/** | |||
* 找回密码 | |||
* @param account 账号 | |||
*/ | |||
@RequestMapping("findPassword") | |||
public void findPassword(String account){ | |||
} | |||
} |
@@ -0,0 +1,32 @@ | |||
package com.hp.user.service.controller; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.web.bind.annotation.RequestMapping; | |||
import org.springframework.web.bind.annotation.RestController; | |||
import com.hp.user.client.service.MessageService; | |||
import io.swagger.annotations.Api; | |||
/** | |||
* 短信 | |||
* @author yeqid | |||
* | |||
*/ | |||
@Api(value="短信") | |||
@RestController | |||
@RequestMapping("/area") | |||
public class MessageController { | |||
@Autowired | |||
private MessageService messageService; | |||
/** | |||
* 发送验证码 | |||
* @param phoneNumber | |||
*/ | |||
@RequestMapping("/sendVerificationCode") | |||
public void sendVerificationCode(String phoneNumber) { | |||
messageService.sendVerificationCode(phoneNumber); | |||
} | |||
} |
@@ -1,6 +1,10 @@ | |||
package com.hp.user.service.impl; | |||
import com.hp.user.client.service.AccountService; | |||
import com.hp.user.client.service.MessageService; | |||
import org.apache.commons.codec.binary.StringUtils; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.stereotype.Service; | |||
/** | |||
@@ -13,5 +17,22 @@ import org.springframework.stereotype.Service; | |||
*/ | |||
@Service | |||
public class AccountServiceImpl implements AccountService { | |||
@Autowired | |||
private MessageService messageService; | |||
@Override | |||
public void login(String phone, String verificationCode) { | |||
try { | |||
String code = messageService.getVerificationCode(phone); | |||
if(StringUtils.equals(verificationCode, code)) { | |||
//登陆成功 | |||
}else { | |||
//登陆失败,返回验证码 | |||
} | |||
}catch(Exception e) { | |||
} | |||
} | |||
} |
@@ -0,0 +1,28 @@ | |||
package com.hp.user.service.impl; | |||
import org.springframework.stereotype.Service; | |||
import com.hp.user.client.service.MessageService; | |||
/** | |||
* 信息服务实现类 | |||
* @author yeqid | |||
* @since 2020/11/26 | |||
* | |||
*/ | |||
@Service | |||
public class MessageServiceImpl implements MessageService { | |||
@Override | |||
public void sendVerificationCode(String phone) { | |||
// TODO Auto-generated method stub | |||
} | |||
@Override | |||
public String getVerificationCode(String phone) { | |||
// TODO Auto-generated method stub | |||
return null; | |||
} | |||
} |
@@ -0,0 +1,178 @@ | |||
package com.hp.user.service.redis; | |||
import java.io.IOException; | |||
import java.util.HashSet; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Set; | |||
import org.apache.commons.pool2.impl.GenericObjectPoolConfig; | |||
import org.springframework.beans.factory.annotation.Value; | |||
import org.springframework.boot.ApplicationArguments; | |||
import org.springframework.boot.ApplicationRunner; | |||
import org.springframework.stereotype.Component; | |||
import redis.clients.jedis.Jedis; | |||
import redis.clients.jedis.JedisPool; | |||
@Component | |||
public class RedisOperation implements ApplicationRunner{ | |||
@Value("${redis-cluster.redisUrlList}") | |||
private String hostAndPort; | |||
@Value("${redis-cluster.password}") | |||
private String password; | |||
//10.1.170.207:17000,10.1.170.207:17001,10.1.170.207:17002,10.1.170.207:17003,10.1.170.207:17004,10.1.170.207:17005 | |||
private static JedisPool pool = null; | |||
public static Jedis getRedis() { | |||
return pool.getResource(); | |||
} | |||
// public RedisOperation() { | |||
// jedis = pool.getResource(); | |||
// jedis.close(); | |||
// System.out.println(jedis); | |||
// } | |||
// @PostConstruct | |||
// public void init() { | |||
// | |||
// } | |||
/** | |||
* 从redis中获取数据 | |||
* @param key | |||
* @return | |||
*/ | |||
// public String get(String key) { | |||
// | |||
// return jedis.get(key); | |||
// } | |||
// | |||
// /** | |||
// * 往redis中set数据 | |||
// * @param key | |||
// * @param value | |||
// */ | |||
// public void set(String key,String value) { | |||
// jedis.set(key, value); | |||
// } | |||
// | |||
// /** | |||
// * 往redis中hset数据 | |||
// * @param key | |||
// * @param field | |||
// * @param value | |||
// */ | |||
// public void hset(String key,String field,String value) { | |||
// jedis.hset(key, field, value); | |||
// } | |||
// | |||
// /** | |||
// * 从redis中hgetAll数据 | |||
// * @param key | |||
// * @return | |||
// */ | |||
// public Map<String,String> hgetAll(String key) { | |||
// return jedis.hgetAll(key); | |||
// } | |||
// | |||
// public String hget(String key,String filed) { | |||
// return jedis.hget(key,filed); | |||
// } | |||
// | |||
// public void hmset(String key,Map<String,String> hash) { | |||
// jedis.hmset(key, hash); | |||
// } | |||
// /** | |||
// * 设置有效时间 | |||
// * @param key | |||
// * @param second | |||
// */ | |||
// public void expire(String key,int second) { | |||
// jedis.expire(key, second); | |||
// } | |||
// | |||
// /** | |||
// * 往redis中存数据并且设置失效时间 | |||
// * @param key | |||
// * @param seconds | |||
// * @param value | |||
// */ | |||
// public void setex(String key,int seconds,String value) { | |||
// jedis.setex(key, seconds, value); | |||
// } | |||
// | |||
// /** | |||
// * 批量获取指定的多个key的数据 | |||
// * @param keys | |||
// * @return | |||
// */ | |||
// public List<String> mget(String ...keys) { | |||
// return jedis.mget(keys); | |||
// } | |||
// | |||
// /** | |||
// * 删除key | |||
// * @param key | |||
// */ | |||
// public void del(String key) { | |||
// jedis.del(key); | |||
// } | |||
// /** | |||
// * 判断key | |||
// * @param key | |||
// * @return | |||
// */ | |||
// public boolean exists(String key) { | |||
// return jedis.exists(key); | |||
// } | |||
// /** | |||
// * 释放资源 | |||
// */ | |||
// public void close() { | |||
// try { | |||
// if(jedis != null) { | |||
// jedis.close(); | |||
// } | |||
// | |||
// } catch (Exception e) { | |||
//// LOGGER.error("redis close fail={}",e.getMessage()); | |||
// } | |||
// } | |||
@Override | |||
public void run(ApplicationArguments args) throws Exception { | |||
System.out.print("redis"); | |||
// JedisPool pool = null; | |||
// common-pool配置 | |||
if (pool == null) { | |||
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig(); | |||
poolConfig.setMaxTotal(GenericObjectPoolConfig.DEFAULT_MAX_TOTAL * 10); | |||
poolConfig.setMaxIdle(GenericObjectPoolConfig.DEFAULT_MAX_IDLE * 4); | |||
poolConfig.setMinIdle(GenericObjectPoolConfig.DEFAULT_MAX_IDLE * 2); | |||
// JedisPool.borrowObject最大等待时间 | |||
poolConfig.setMaxWaitMillis(1000L); | |||
try { | |||
// Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>(); | |||
// String[] singleUrl = hostAndPort.trim().split(","); | |||
String[] single = hostAndPort.split(":"); | |||
// for (int i = 0; i < singleUrl.length; i++) { | |||
// String[] single = singleUrl[i].split(":"); | |||
// jedisClusterNodes.add(new HostAndPort(single[0],Integer.parseInt(single[1]))); | |||
//// jedisClusterNodes.add(new HostAndPort(single[0], Integer.parseInt(single[1]), false)); | |||
// } | |||
// jedis = new JedisCluster(jedisClusterNodes,2000,20); | |||
// jedis = new JedisCluster(jedisClusterNodes,1000,10,4,password,poolConfig); | |||
// new JedisPool(poolConfig, singleUrl[0], singleUrl[1],1000, password); | |||
pool= new JedisPool(poolConfig, single[0], Integer.parseInt(single[1]),1000, password); | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} | |||
} | |||
} | |||
} |
@@ -0,0 +1,156 @@ | |||
package com.hp.user.util; | |||
/** | |||
* Id生成器 | |||
* @author yeqid | |||
* | |||
*/ | |||
public class IdWorker{ | |||
//下面两个每个5位,加起来就是10位的工作机器id | |||
private long workerId; //工作id | |||
private long datacenterId; //数据id | |||
//12位的序列号 | |||
private long sequence; | |||
public static IdWorker worker = null; | |||
public IdWorker(long workerId, long datacenterId, long sequence){ | |||
// sanity check for workerId | |||
if (workerId > maxWorkerId || workerId < 0) { | |||
throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0",maxWorkerId)); | |||
} | |||
if (datacenterId > maxDatacenterId || datacenterId < 0) { | |||
throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0",maxDatacenterId)); | |||
} | |||
System.out.printf("worker starting. timestamp left shift %d, datacenter id bits %d, worker id bits %d, sequence bits %d, workerid %d", | |||
timestampLeftShift, datacenterIdBits, workerIdBits, sequenceBits, workerId); | |||
this.workerId = workerId; | |||
this.datacenterId = datacenterId; | |||
this.sequence = sequence; | |||
} | |||
//初始时间戳 | |||
private long twepoch = 1525705533000l; | |||
//长度为5位 | |||
private long workerIdBits = 5L; | |||
private long datacenterIdBits = 5L; | |||
//最大值 | |||
private long maxWorkerId = -1L ^ (-1L << workerIdBits); | |||
private long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); | |||
//序列号id长度 | |||
private long sequenceBits = 12L; | |||
//序列号最大值 | |||
private long sequenceMask = -1L ^ (-1L << sequenceBits); | |||
//工作id需要左移的位数,12位 | |||
private long workerIdShift = sequenceBits; | |||
//数据id需要左移位数 12+5=17位 | |||
private long datacenterIdShift = sequenceBits + workerIdBits; | |||
//时间戳需要左移位数 12+5+5=22位 | |||
private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; | |||
//上次时间戳,初始值为负数 | |||
private long lastTimestamp = -1L; | |||
public long getWorkerId(){ | |||
return workerId; | |||
} | |||
public long getDatacenterId(){ | |||
return datacenterId; | |||
} | |||
public long getTimestamp(){ | |||
return System.currentTimeMillis(); | |||
} | |||
//下一个ID生成算法 | |||
public synchronized long nextId() { | |||
long timestamp = timeGen(); | |||
//获取当前时间戳如果小于上次时间戳,则表示时间戳获取出现异常 | |||
if (timestamp < lastTimestamp) { | |||
System.err.printf("clock is moving backwards. Rejecting requests until %d.", lastTimestamp); | |||
throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", | |||
lastTimestamp - timestamp)); | |||
} | |||
//获取当前时间戳如果等于上次时间戳(同一毫秒内),则在序列号加一;否则序列号赋值为0,从0开始。 | |||
if (lastTimestamp == timestamp) { | |||
sequence = (sequence + 1) & sequenceMask; | |||
if (sequence == 0) { | |||
timestamp = tilNextMillis(lastTimestamp); | |||
} | |||
} else { | |||
sequence = 0; | |||
} | |||
//将上次时间戳值刷新 | |||
lastTimestamp = timestamp; | |||
/** | |||
* 返回结果: | |||
* (timestamp - twepoch) << timestampLeftShift) 表示将时间戳减去初始时间戳,再左移相应位数 | |||
* (datacenterId << datacenterIdShift) 表示将数据id左移相应位数 | |||
* (workerId << workerIdShift) 表示将工作id左移相应位数 | |||
* | 是按位或运算符,例如:x | y,只有当x,y都为0的时候结果才为0,其它情况结果都为1。 | |||
* 因为个部分只有相应位上的值有意义,其它位上都是0,所以将各部分的值进行 | 运算就能得到最终拼接好的id | |||
*/ | |||
return ((timestamp - twepoch) << timestampLeftShift) | | |||
(datacenterId << datacenterIdShift) | | |||
(workerId << workerIdShift) | | |||
sequence; | |||
} | |||
//获取时间戳,并与上次时间戳比较 | |||
private long tilNextMillis(long lastTimestamp) { | |||
long timestamp = timeGen(); | |||
while (timestamp <= lastTimestamp) { | |||
timestamp = timeGen(); | |||
} | |||
return timestamp; | |||
} | |||
//获取系统时间戳 | |||
private long timeGen(){ | |||
return System.currentTimeMillis(); | |||
} | |||
public static Long generactorId() { | |||
if(worker == null) { | |||
synchronized(IdWorker.class) { | |||
if(worker == null) { | |||
worker = new IdWorker(1,1,1); | |||
} | |||
} | |||
} | |||
return worker.nextId(); | |||
} | |||
//---------------测试--------------- | |||
// public static void main(String[] args) throws InterruptedException { | |||
//// IdWorker worker = new IdWorker(1,1,1); | |||
// Thread t1 = new Thread( new Runnable() {public void run() { for (int i = 0; i < 30; i++) { | |||
// | |||
// System.out.println(IdWorker.generactorId()); | |||
// | |||
// };} }, "t1"); | |||
// Thread t2 = new Thread( new Runnable() {public void run() { for (int i = 0; i < 30; i++) { | |||
// | |||
// System.out.println(IdWorker.generactorId()); | |||
// };} }, "t2"); | |||
// Thread t3 = new Thread( new Runnable() {public void run() { for (int i = 0; i < 30; i++) { | |||
// | |||
// System.out.println(IdWorker.generactorId()); | |||
// };} }, "t3"); | |||
// t2.start(); | |||
// t1.start(); | |||
// t3.start(); | |||
// t1.join(); | |||
// t2.join(); | |||
// } | |||
} |