Feat: [后台]:优化项目结构,增加工具类

This commit is contained in:
fanxb 2019-07-05 08:46:22 +08:00
parent 65e1ae789f
commit 32652cc60b
33 changed files with 1054 additions and 79 deletions

View File

@ -1,5 +1,5 @@
HELP.md
/target/
target
!.mvn/wrapper/maven-wrapper.jar
### STS ###

View File

@ -1 +0,0 @@
**本模块用于存放所有业务逻辑,并作为springboot入口**

View File

@ -1 +0,0 @@
**本模块为书签云存储相关功能模块**

View File

@ -13,8 +13,6 @@
<packaging>pom</packaging>
<modules>
<module>user</module>
<module>bms</module>
<module>web</module>
</modules>
<dependencies>
@ -28,10 +26,7 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.6.RELEASE</version>
</dependency>
</dependencies>

View File

@ -9,7 +9,7 @@
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>business-user</artifactId>
<artifactId>user</artifactId>
</project>

View File

@ -1,4 +1,4 @@
package com.fanxb.business.user.controller;
package com.fanxb.bookmark.business.user.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@ -9,14 +9,14 @@ import org.springframework.web.bind.annotation.RestController;
* 类功能详述
*
* @author fanxb
* @date 2019/7/4 8:59
* @date 2019/7/4 19:51
*/
@RestController
@RequestMapping("/user")
public class User {
public class UserController {
@GetMapping("test")
public String getName() {
return "test";
@GetMapping("/test")
public String test() {
return "abce";
}
}

View File

@ -1,12 +0,0 @@
package com.fanxb.business.user;
/**
* 类功能简述
* 类功能详述
*
* @author fanxb
* @date 2019/7/3 20:16
*/
public class Test {
public int id;
}

View File

@ -1 +0,0 @@
**入口模块最终只有这个模块会打出jar包**

View File

@ -1,31 +0,0 @@
<?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">
<parent>
<artifactId>business</artifactId>
<groupId>com.fanxb</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>business.web</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,6 +0,0 @@
**这是公共模块,不得存放业务代码,只能存放如下:**
- 工具类
- 过滤器,拦截器等统一逻辑
- 权限认证
- 基本实体类,数据库中表对应实体,或者自定义异常,或者响应对象

View File

@ -11,22 +11,66 @@
<artifactId>common</artifactId>
<dependencies>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp -->
<!--http请求工具依赖-->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.0.0</version>
<version>3.14.0</version>
</dependency>
<!--jwt依赖-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.7.0</version>
</dependency>
<!--redis依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!--邮件依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!--减负依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--json工具依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.56</version>
</dependency>
<!--减负依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--json工具依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.56</version>
</dependency>
</dependencies>

View File

@ -0,0 +1,32 @@
package com.fanxb.bookmark.common;
import org.springframework.stereotype.Component;
/**
* 类功能简述系统及常量类
* 类功能详述
*
* @author fanxb
* @date 2019/4/4 16:10
*/
@Component
public class Constant {
/**
* jwt key
*/
public static final String JWT_KEY = "jwt-token";
/**
* jwt 过期时间ms
*/
public static int JWT_EXPIRE_TIME = 60 * 60 * 60 * 1000;
/**
* 验证码过期时间
*/
public static int VERIFY_CODE_EXPIRE = 15 * 60 * 1000;
}

View File

@ -0,0 +1,25 @@
package com.fanxb.bookmark.common.entity;
import lombok.Data;
/**
* Created with IntelliJ IDEA
* Created By Fxb
* Date: 2019/4/7
* Time: 18:41
*/
@Data
public class MailInfo {
private String receiver;
private String subject;
private String content;
public MailInfo() {
}
public MailInfo(String receiver, String subject, String content) {
this.receiver = receiver;
this.subject = subject;
this.content = content;
}
}

View File

@ -0,0 +1,63 @@
package com.fanxb.bookmark.common.entity;
/**
* 类功能简述
* 类功能详述
*
* @author fanxb
* @date 2019/3/19 18:05
*/
public class Result {
/**
* 状态1正常0异常-1未认证
*/
private int code;
private String message;
private Object data;
public Result() {
}
public Result(int code, String message, Object data) {
this.code = code;
this.message = message;
this.data = data;
}
public static Result unAuth() {
return new Result(-1, "", null);
}
public static Result success(Object data) {
return new Result(1, "", data);
}
public static Result failed(String message) {
return new Result(0, message, null);
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}

View File

@ -0,0 +1,11 @@
package com.fanxb.bookmark.common.entity;
/**
* 类功能简述
* 类功能详述
*
* @author fanxb
* @date 2019/7/4 20:14
*/
public class User {
}

View File

@ -0,0 +1,18 @@
package com.fanxb.bookmark.common.entity;
import lombok.Data;
/**
* 类功能简述
* 类功能详述
*
* @author fanxb
* @date 2019/3/1 14:26
*/
@Data
public class UserContext {
private User user;
private String jwt;
private String sessionId;
}

View File

@ -0,0 +1,40 @@
package com.fanxb.bookmark.common.exception;
/**
* 类功能简述
* 类功能详述
*
* @author fanxb
* @date 2019/3/19 18:09
*/
public class CustomException extends RuntimeException {
String message;
public CustomException() {
super();
}
public CustomException(String message) {
super(message);
this.message = message;
}
public CustomException(Exception e){
super(e);
}
public CustomException(String message, Exception e) {
super(e);
this.message = message;
}
@Override
public String getMessage() {
if (this.message == null) {
return super.getMessage();
} else {
return this.message;
}
}
}

View File

@ -0,0 +1,30 @@
package com.fanxb.bookmark.common.exception;
import com.fanxb.bookmark.common.entity.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* 类功能简述
* 类功能详述
*
* @author fanxb
* @date 2019/3/19 18:12
*/
@RestControllerAdvice
public class ExceptionHandle {
private static Logger logger = LoggerFactory.getLogger(ExceptionHandle.class);
@ExceptionHandler(Exception.class)
public Result handleException(Exception e) {
logger.error("捕获到错误:", e);
if (e instanceof CustomException) {
return Result.failed(e.getMessage());
} else {
return Result.failed("");
}
}
}

View File

@ -0,0 +1,55 @@
package com.fanxb.bookmark.common.factory;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ThreadFactory;
/**
* 类功能简述
* 类功能详述线程工厂
*
* @author: fanxb
* @date: 2018/10/12 11:29
*/
public class CustomThreadFactory implements ThreadFactory {
/**
* 记录创建线程数
*/
private int counter;
/**
* 线程工程名
*/
private String name;
/**
* 记录最近1000条创建历史
*/
private List<String> history;
private int historyLength;
public CustomThreadFactory(String name) {
this.name = name;
this.history = new LinkedList<>();
this.historyLength = 1000;
}
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, name + "-Thread-" + counter);
this.counter++;
history.add(String.format("Created thread %d with name %s on %s \n", t.getId(), t.getName(), new Date().toString()));
if (history.size() >= this.historyLength) {
history.remove(0);
}
return t;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
this.history.forEach(builder::append);
return builder.toString();
}
}

View File

@ -0,0 +1,130 @@
package com.fanxb.bookmark.common.factory;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 类功能简述 线程池工厂可使用此工厂创建线程池,等待队列使用ArrayBlockingQueue
* 类功能详述
*
* @author fanxb
* @date 2018/11/1 10:57
*/
public class ThreadPoolFactory {
/**
* 默认核心池大小
*/
public static final int DEFAULT_CORE_POOL_SIZE = 5;
/**
* 默认最大线程数
*/
public static final int DEFAULT_MAX_POOL_SIZE = 30;
/**
* 默认空闲线程回收时间毫秒
*/
public static final long DEFAULT_KEEP_ACTIVE_TIME = 1000;
/**
* 默认等待队列长度
*/
public static final int DEFAULT_QUEUE_LENGTH = 2000;
/**
* Description: 使用默认配置创建一个连接池
*
* @param factoryName 线程工厂名
* @return java.util.concurrent.ThreadPoolExecutor
* @author fanxb
* @date 2018/10/12 13:38
*/
public static ThreadPoolExecutor createPool(String factoryName) {
ThreadFactory threadFactory = new CustomThreadFactory(factoryName);
return createPool(DEFAULT_CORE_POOL_SIZE, DEFAULT_MAX_POOL_SIZE, DEFAULT_KEEP_ACTIVE_TIME, DEFAULT_QUEUE_LENGTH, threadFactory);
}
/**
* Description: 提供参数创建一个连接池
*
* @param corePoolSize 核心池大小
* @param maxPoolSize 线程池最大线程数
* @param keepActiveTime 空闲线程回收时间ms)
* @param queueLength 等待队列长度
* @return java.util.concurrent.ThreadPoolExecutor
* @author fanxb
* @date 2018/10/12 13:39
*/
public static ThreadPoolExecutor createPool(int corePoolSize, int maxPoolSize, long keepActiveTime
, int queueLength, String threadName) {
return new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepActiveTime
, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(queueLength), new CustomThreadFactory(threadName));
}
/**
* Description: 提供参数创建一个连接池,自己提供线程工厂
*
* @param corePoolSize 核心池大小
* @param maxPoolSize 线程池最大线程数
* @param keepActiveTime 空闲线程回收时间ms)
* @param queueLength 等待队列长度
* @param factory 线程工厂
* @return java.util.concurrent.ThreadPoolExecutor
* @author fanxb
* @date 2018/10/12 13:39
*/
public static ThreadPoolExecutor createPool(int corePoolSize, int maxPoolSize, long keepActiveTime
, int queueLength, ThreadFactory factory) {
return new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepActiveTime
, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(queueLength), factory);
}
/**
* Description: 强制关闭线程池不等待已有任务的完成
*
* @param executor 被关闭线程池对象
* @return List<Runnable>
* @author fanxb
* @date 2018/10/12 13:42
*/
public static List<Runnable> forceShutdown(ThreadPoolExecutor executor) {
if (executor != null) {
return executor.shutdownNow();
} else {
return null;
}
}
/**
* Description: 关闭一个连接池等待已有任务完成
*
* @param executor 被关闭线程池对象
* @return void
* @author fanxb
* @date 2018/10/12 13:45
*/
public static void shutdown(ThreadPoolExecutor executor) {
if (executor == null) {
return;
}
executor.shutdown();
try {
int count = 0;
int timeOut = 2;
while (executor.awaitTermination(timeOut, TimeUnit.SECONDS)) {
count++;
if (count == 100) {
executor.shutdownNow();
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,134 @@
package com.fanxb.bookmark.common.util;
import com.alibaba.fastjson.JSONObject;
import com.fanxb.bookmark.common.exception.CustomException;
import okhttp3.*;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* 类功能简述
* 类功能详述
*
* @author fanxb
* @date 2019/4/4 15:53
*/
public class HttpUtil {
private static final int IP_LENGTH = 15;
public static final OkHttpClient CLIENT = new OkHttpClient.Builder().connectTimeout(3, TimeUnit.SECONDS)
.readTimeout(300, TimeUnit.SECONDS).build();
public static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
public static JSONObject get(String url) {
return get(url, null);
}
public static JSONObject get(String url, Map<String, String> headers) {
Request.Builder builder = new Request.Builder().url(url);
if (headers != null && headers.size() > 0) {
Set<String> keys = headers.keySet();
for (String key : keys) {
builder = builder.addHeader(key, headers.get(key));
}
}
return request(builder.build());
}
public static JSONObject post(String url, String jsonObj) {
return post(url, jsonObj, null);
}
/**
* 发送post请求带header
*
* @param url url
* @param jsonObj 请求体
* @param headers 请求头
* @return
*/
public static JSONObject post(String url, String jsonObj, Map<String, String> headers) {
RequestBody body = RequestBody.create(JSON, jsonObj);
Request.Builder builder = new Request.Builder().url(url).post(body);
if (headers != null) {
Set<String> set = headers.keySet();
for (String key : set) {
builder = builder.addHeader(key, headers.get(key));
}
}
return request(builder.build());
}
/**
* 构造request获取响应
*
* @param request request
* @return
*/
public static JSONObject request(Request request) {
try (Response res = CLIENT.newCall(request).execute()) {
return parseResponse(res);
} catch (Exception e) {
throw new CustomException(e);
}
}
/**
* 解析响应
*
* @param res
* @return
*/
public static JSONObject parseResponse(Response res) {
try {
if (checkIsOk(res.code())) {
String str = res.body().string();
return JSONObject.parseObject(str);
} else {
throw new CustomException("http请求出错:" + res.body().string());
}
} catch (Exception e) {
throw new CustomException(e);
}
}
public static boolean checkIsOk(int code) {
return code >= 200 && code < 300;
}
/**
* Description: 从请求头中获取用户访问ip
*
* @param request 请求头
* @return java.lang.String
* @author fanxb
* @date 2019/6/12 15:36
*/
public static String getIpAddr(HttpServletRequest request) {
String ipAddress = null;
try {
ipAddress = request.getHeader("x-forwarded-for");
if (ipAddress == null || ipAddress.length() == 0) {
ipAddress = request.getHeader("Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0) {
ipAddress = request.getHeader("WL-Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0) {
ipAddress = request.getRemoteAddr();
}
// 对于通过多个代理的情况第一个IP为客户端真实IP,多个IP按照','分割
if (ipAddress != null && ipAddress.length() > IP_LENGTH) {
ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
}
} catch (Exception e) {
ipAddress = "";
}
return ipAddress;
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,41 @@
package com.fanxb.bookmark.common.util;
import com.fanxb.bookmark.common.entity.MailInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Component;
/**
* Created with IntelliJ IDEA
* Created By Fxb
* Date: 2019/4/7
* Time: 16:08
*/
@Component
public class MailUtil {
private static JavaMailSender mailSender;
private static String from;
@Autowired
public void setMailSender(JavaMailSender mailSender) {
MailUtil.mailSender = mailSender;
}
@Value("${spring.mail.username}")
public void setFrom(String from){
MailUtil.from = from;
}
public static void sendTextMail(MailInfo info){
SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
simpleMailMessage.setFrom(from);
simpleMailMessage.setTo(info.getReceiver());
simpleMailMessage.setSubject(info.getSubject());
simpleMailMessage.setText(info.getContent());
mailSender.send(simpleMailMessage);
}
}

View File

@ -0,0 +1,82 @@
package com.fanxb.bookmark.common.util;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
/**
* 类功能简述
* 类功能详述
*
* @author fanxb
* @date 2019/3/8 13:26
*/
@Component
public class RedisUtil {
private static final int DEFAULT_EXPIRE_TIME = 60 * 1000;
private static final String STRING_TYPE_NAME = "java.lang.Class";
public static StringRedisTemplate redisTemplate;
@Autowired
public void setRedisTemplate(StringRedisTemplate redisTemplate) {
RedisUtil.redisTemplate = redisTemplate;
}
/**
* 设置键值对使用默认过期时间
*
* @param key
* @param value
*/
public static void set(String key, String value) {
set(key, value, DEFAULT_EXPIRE_TIME);
}
/**
* 设置键值对指定过期时间
*
* @param key key
* @param value value
* @param expireTime 过期时间
*/
public static void set(String key, String value, long expireTime) {
redisTemplate.opsForValue().set(key, value);
redisTemplate.expire(key, expireTime, TimeUnit.MILLISECONDS);
}
/**
* 删除key
*
* @param key key
*/
public static void delete(String key) {
redisTemplate.delete(key);
}
/**
* Description: 获取对象
*
* @param key
* @param tt 对象类
* @return T
* @author fanxb
* @date 2019/4/12 10:45
*/
public static <T> T get(String key, Class<T> tt) {
String str = redisTemplate.opsForValue().get(key);
if (StringUtil.isEmpty(str)) {
return null;
} else {
if (STRING_TYPE_NAME.equals(tt.getTypeName())) {
return (T) str;
} else {
return JSON.parseObject(str, tt);
}
}
}
}

View File

@ -0,0 +1,57 @@
package com.fanxb.bookmark.common.util;
/**
* 类功能简述
* 类功能详述
*
* @author fanxb
* @date 2019/4/4 16:17
*/
public class StringUtil {
private static char[][] chars = {{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}
, {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'},
{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}};
/**
* Description: 获取随机字符串
*
* @param length 长度
* @param mode 模式0数字字母混合1字母2数字
* @return java.lang.String
* @author fanxb
* @date 2019/4/16 13:39
*/
public static String getRandomString(int length, int mode) {
StringBuilder stringBuilder = new StringBuilder();
char[] temp = chars[mode];
for (int i = 0; i < length; i++) {
stringBuilder.append(temp[getRandomNumber(0, temp.length - 1)]);
}
return stringBuilder.toString();
}
/**
* 获取指定范围的随机数
*
* @param min 最小值
* @param max 最大值
* @return
*/
public static int getRandomNumber(int min, int max) {
return (int) (min + Math.round(Math.random() * (max - min)));
}
/**
* Description:判断字符串是否为空
*
* @param str 待判断字符串
* @return boolean
* @author fanxb
* @date 2019/4/16 13:33
*/
public static boolean isEmpty(String str) {
return str == null || str.trim().length() == 0;
}
}

View File

@ -0,0 +1,60 @@
package com.fanxb.bookmark.common.util;
import com.fanxb.bookmark.common.factory.ThreadPoolFactory;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 类功能简述当短时间需要少量线程时,使用本类长时间占用或大量线程需求请用线程工厂ThreadPoolFactory创建新的线程池,
* 类功能详述
*
* @author fanxb
* @date 2018/11/1 11:04
*/
public class ThreadPoolUtil {
private static final ThreadPoolExecutor POOL_EXECUTOR = ThreadPoolFactory.createPool("临时线程");
/**
* Description: 执行线程任务
*
* @param runnable 待执行对象
* @author fanxb
* @date 2018/11/1 11:27
*/
synchronized private static void executeTask(Runnable runnable) {
POOL_EXECUTOR.execute(runnable);
}
/**
* Description: 执行一个有返回值的任务
*
* @param callable 待执行对象
* @param timeOut 获取结果操时时间 , 操时抛出错误 单位
* @return T
* @author fanxb
* @date 2018/11/1 11:10
*/
@SuppressWarnings("unchecked")
public static <T> T execute(Callable<T> callable, int timeOut) throws Exception {
FutureTask<?> futureTask = new FutureTask<>(callable);
executeTask(futureTask);
return (T) futureTask.get(timeOut, TimeUnit.SECONDS);
}
/**
* Description: 执行一个无返回值任务
*
* @param runnable 待执行对象
* @author fanxb
* @date 2018/11/1 11:11
*/
public static void execute(Runnable runnable) {
executeTask(runnable);
}
}

View File

@ -0,0 +1,101 @@
package com.fanxb.bookmark.common.util;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 类功能简述
* 类功能详述
*
* @author fanxb
* @date 2019/3/28 16:54
*/
public class TimeUtil {
/**
* 一天的毫秒数
*/
public static int DAY_MS = 24 * 60 * 60 * 1000;
private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<>();
private static void close() {
threadLocal.remove();
}
private static DateFormat getDefaultDateFormat() {
DateFormat format = threadLocal.get();
if (format == null) {
format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
threadLocal.set(format);
}
return format;
}
/**
* Description: 格式化时间
*
* @param dateLong 毫秒时间戳
* @return java.lang.String
* @author fanxb
* @date 2019/3/28 17:10
*/
public static String formatTime(Long dateLong) {
return formatTime(null, new Date(dateLong));
}
/**
* Description: 格式化时间
*
* @param pattern pattern
* @param dateLong 毫秒时间戳
* @return java.lang.String
* @author fanxb
* @date 2019/3/28 17:11
*/
public static String formatTime(String pattern, Long dateLong) {
Date date = new Date(dateLong);
if (pattern != null) {
return formatTime(pattern, date);
} else {
return formatTime(null, date);
}
}
/**
* Description: 格式化时间
*
* @param date 时间
* @return java.lang.String
* @author fanxb
* @date 2019/3/28 17:08
*/
public static String formatTime(Date date) {
return formatTime(null, date);
}
/**
* description:格式化时间日期
*
* @param pattern 格式化字符串
* @param date 时间
* @return java.lang.String
* @author fanxb
* @date 2019/3/28 16:58
*/
public static String formatTime(String pattern, Date date) {
DateFormat format;
if (pattern == null) {
format = getDefaultDateFormat();
} else {
format = new SimpleDateFormat(pattern);
}
if (date == null) {
return format.format(new Date());
} else {
return format.format(date);
}
}
}

View File

@ -0,0 +1,29 @@
package com.fanxb.bookmark.common.util;
import com.fanxb.bookmark.common.entity.UserContext;
/**
* 类功能简述
* 类功能详述
*
* @author fanxb
* @date 2019/3/1 14:26
*/
public class UserContextHolder {
private static final ThreadLocal<UserContext> USER_CONTEXT_THREAD_LOCAL = new ThreadLocal<>();
public static UserContext get() {
return USER_CONTEXT_THREAD_LOCAL.get();
}
public static void set(UserContext context) {
USER_CONTEXT_THREAD_LOCAL.set(context);
}
public static void remove() {
USER_CONTEXT_THREAD_LOCAL.remove();
}
}

View File

@ -11,6 +11,7 @@
<modules>
<module>common</module>
<module>business</module>
<module>web</module>
</modules>
<properties>
<project.build.sourceEncoding>utf-8</project.build.sourceEncoding>
@ -21,9 +22,8 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<version>2.1.6.RELEASE</version>
<relativePath/>
</parent>
</project>

View File

@ -3,18 +3,22 @@
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">
<parent>
<artifactId>business</artifactId>
<artifactId>bookMarkService</artifactId>
<groupId>com.fanxb</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>business-bms</artifactId>
<artifactId>web</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.fanxb</groupId>
<artifactId>business-bms</artifactId>
<artifactId>user</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>

View File

@ -1,4 +1,5 @@
package com.fanxb.business.web;
package com.fanxb.bookmark.web;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@ -8,9 +9,9 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
* 类功能详述
*
* @author fanxb
* @date 2019/7/3 20:20
* @date 2019/7/4 19:38
*/
@SpringBootApplication(scanBasePackages = "com.fanxb")
@SpringBootApplication(scanBasePackages = "com.fanxb.bookmark")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);

View File

@ -0,0 +1,16 @@
spring:
mail:
host:
username:
password:
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
port: 465
server:
port: 8088