import lombok.Data;
@Data
public class CommonResult<T> {
private Integer code;
private String message;
private T data;
//成功通用返回
public static CommonResult okResult(Object data){
CommonResult commonResult = new CommonResult(AppHttpCodeEnum.SUCCESS.getCode(),AppHttpCodeEnum.SUCCESS.getMsg());
if(data!=null){
commonResult.setData(data);
}return commonResult;
}
//失败通用返回 需要传失败码
public static CommonResult failed(AppHttpCodeEnum appHttpCodeEnum){
CommonResult commonResult = new CommonResult(appHttpCodeEnum.getCode(),appHttpCodeEnum.getMsg());
return commonResult;
}
public static CommonResult failed(Integer code, String message){
CommonResult commonResult = new CommonResult(code,message);
return commonResult;
}
public CommonResult(Integer code, String message, T data) {
this.code = code;
this.message = message;
this.data = data;
}
public CommonResult(Integer code, String message) {
this.code = code;
this.message = message;
}
@Override
public String toString() {
return "CommonResult{" +
"code=" + code +
", message='" + message + '\'' +
", data=" + data +
'}';
}
}
返回类常量
package com.t2t.t2t_utils.utils_path.returnClass;
public enum AppHttpCodeEnum {
ERROR(100000,"未知原因"),
SUCCESS(200,"操作成功"),
;
int code;
String msg;
public int getCode() {
return code;
}
public String getMsg() {
return msg;
}
AppHttpCodeEnum(int code, String msg) {
this.code = code;
this.msg = msg;
}
}
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
/**
* 随机生成一个 png 或者其他的文件名
*/
public class PathUtils {
public static String generateFilePath(String fileName){
//生成日期文件夹
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
String datePath = sdf.format(new Date());
//生成uuid
String uuid = UUID.randomUUID().toString().replace("-", "");
//获取文件后缀
int index = fileName.lastIndexOf(".");
String fileType = fileName.substring(index);
return new StringBuilder().append(datePath).append(uuid).append(fileType).toString();
}
}
import com.alibaba.fastjson.JSON;
import io.jsonwebtoken.*;
import org.springframework.stereotype.Component;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.Date;
import java.util.UUID;
@Component
public class JwtUtil {
// 有效期
private static final long JWT_EXPIRE = 24 * 60 * 60 * 1000L; //1天
// 令牌秘钥
private static final String JWT_KEY = "FrDjoJR+wCJPW8wsjxHJ%iYKCdy20Z8mn";
//token过期多久可以继续刷新
private static final long Refresh_Token_Time = 24 * 24 * 60 * 60; //1天 已转化
public static String createToken(Object data) {
// 当前时间
long currentTime = System.currentTimeMillis();
// 过期时间
long expTime = currentTime + JWT_EXPIRE;
// 构建jwt
JwtBuilder builder = Jwts.builder()
.setId(UUID.randomUUID() + "")
.setSubject(JSON.toJSONString(data))
.setIssuer("system")
.setIssuedAt(new Date(currentTime))
.signWith(SignatureAlgorithm.HS256, encodeSecret(JWT_KEY))
.setExpiration(new Date(expTime));
return builder.compact();
}
private static SecretKey encodeSecret(String key) {
byte[] encode = Base64.getEncoder().encode(key.getBytes());
SecretKeySpec aes = new SecretKeySpec(encode, 0, encode.length, "AES");
return aes;
}
//解析
public static Claims parseToken(String token) {
Claims body = Jwts.parser()
.setSigningKey(encodeSecret(JWT_KEY))
.parseClaimsJws(token)
.getBody();
return body;
}
//解析重载
public static <T> T parseToken(String token, Class<T> clazz) {
Claims body = Jwts.parser()
.setSigningKey(encodeSecret(JWT_KEY))
.parseClaimsJws(token)
.getBody();
return JSON.parseObject(body.getSubject(), clazz);
}
public static <T> String refreshToken(String inToken, Class<T> clazz) {
try {
JwtUtil.parseToken(inToken);
} catch (ExpiredJwtException e) {
Claims claims = e.getClaims();
T object = JSON.parseObject(claims.getSubject(), clazz);
//判断时间是否超过某个值
//过期时间
Integer createTime = (Integer) claims.get("exp");
//当前时间
long time = new Date().getTime();
Integer currentTime = (int) (time / 1000);
//判断是否过期时间小于某一个值
if (currentTime - createTime <= Refresh_Token_Time) {
//过期时间小于一天 刷新token
String token = JwtUtil.createToken(object);
return token;
}
} catch (Exception e) {
return null;
}
//token未过期 放回原来的token
return inToken;
}
}
import com.alibaba.fastjson.JSON;
import com.t2t.t2t_utils.utils_path.returnClass.AppHttpCodeEnum;
import com.t2t.t2t_utils.utils_path.returnClass.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
@Slf4j
public class JwtValidateInterceptor implements HandlerInterceptor {
@Autowired
private JwtUtil jwtUtil;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getHeader("X-Token");
System.out.println(request.getRequestURI() +" 待验证:"+token);
if(token != null){
try {
JwtUtil.parseToken(token);
log.debug(request.getRequestURI() + " 放行...");
return true;
} catch (Exception e) {
e.printStackTrace();
}
}
log.debug(request.getRequestURI() + " 禁止访问...");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(JSON.toJSONString(CommonResult.failed(AppHttpCodeEnum.JWT_ERROR)));
return false;
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyWebConfig implements WebMvcConfigurer {
@Autowired
private JwtValidateInterceptor jwtValidateInterceptor;
// 注册拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
InterceptorRegistration registration = registry.addInterceptor(jwtValidateInterceptor);
registration.addPathPatterns("/**")
.excludePathPatterns(
"/user/login",
"/user/info",
"/user/logout",
"/error",
"/swagger-ui/**",
"/swagger-resources/**",
"/v3/**");
}
}
import org.springframework.beans.BeanUtils;
import java.util.List;
import java.util.stream.Collectors;
public class BeanCopyUtils {
public BeanCopyUtils(){
}
public static <V> V copyBean(Object source,Class<V> clazz) {
//目标
V result=null;
try {
result = clazz.newInstance();
BeanUtils.copyProperties(source, result);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
return result;
}
public static <O,V> List<V> copyBeanList(List<O> list,Class<V> clazz){
return list.stream()
.map(o -> copyBean(o,clazz))
.collect(Collectors.toList());
}
}
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletRequest;
import java.net.*;
import java.util.Enumeration;
/**
*@Author: make mpy
*@Description: 获取IP的方法
*@Date: 2021/1/18 15:02
*/
@Slf4j
public class IpUtil {
private static final String LOCAL_IP = "127.0.0.1";
/**
* 获取IP地址
*
* 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
* 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
*/
public static String getIpAddr(HttpServletRequest request) {
if (request == null) {
return "unknown";
}
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Forwarded-For");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Real-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return "0:0:0:0:0:0:0:1".equals(ip) ? LOCAL_IP : ip;
}
public static boolean internalIp(String ip) {
boolean res = false;
byte[] addr = textToNumericFormatV4(ip);
if (addr != null && ip != null) {
res = internalIp(addr) || LOCAL_IP.equals(ip);
}
return res;
}
private static boolean internalIp(byte[] addr) {
final byte b0 = addr[0];
final byte b1 = addr[1];
// 10.x.x.x/8
final byte SECTION_1 = 0x0A;
// 172.16.x.x/12
final byte SECTION_2 = (byte) 0xAC;
final byte SECTION_3 = (byte) 0x10;
final byte SECTION_4 = (byte) 0x1F;
// 192.168.x.x/16
final byte SECTION_5 = (byte) 0xC0;
final byte SECTION_6 = (byte) 0xA8;
boolean flag = false;
switch (b0) {
case SECTION_1:
flag = true;
break;
case SECTION_2:
if (b1 >= SECTION_3 && b1 <= SECTION_4) {
flag = true;
}
break;
case SECTION_5:
if (b1 == SECTION_6) {
flag = true;
}
break;
default:
break;
}
return flag;
}
/**
* 将IPv4地址转换成字节
*IPv4地址
* @param text
* @return byte 字节
*/
public static byte[] textToNumericFormatV4(String text) {
if (text.length() == 0) {
return null;
}
byte[] bytes = new byte[4];
String[] elements = text.split("\\.", -1);
try {
long l;
int i;
switch (elements.length) {
case 1:
l = Long.parseLong(elements[0]);
if ((l < 0L) || (l > 4294967295L))
return null;
bytes[0] = (byte) (int) (l >> 24 & 0xFF);
bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF);
bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
bytes[3] = (byte) (int) (l & 0xFF);
break;
case 2:
l = Integer.parseInt(elements[0]);
if ((l < 0L) || (l > 255L))
return null;
bytes[0] = (byte) (int) (l & 0xFF);
l = Integer.parseInt(elements[1]);
if ((l < 0L) || (l > 16777215L))
return null;
bytes[1] = (byte) (int) (l >> 16 & 0xFF);
bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
bytes[3] = (byte) (int) (l & 0xFF);
break;
case 3:
for (i = 0; i < 2; ++i) {
l = Integer.parseInt(elements[i]);
if ((l < 0L) || (l > 255L))
return null;
bytes[i] = (byte) (int) (l & 0xFF);
}
l = Integer.parseInt(elements[2]);
if ((l < 0L) || (l > 65535L))
return null;
bytes[2] = (byte) (int) (l >> 8 & 0xFF);
bytes[3] = (byte) (int) (l & 0xFF);
break;
case 4:
for (i = 0; i < 4; ++i) {
l = Integer.parseInt(elements[i]);
if ((l < 0L) || (l > 255L))
return null;
bytes[i] = (byte) (int) (l & 0xFF);
}
break;
default:
return null;
}
} catch (NumberFormatException e) {
log.error("数字格式化异常",e);
return null;
}
return bytes;
}
public static String getLocalIP() {
String ip = "";
if (System.getProperty("os.name").toLowerCase().startsWith("windows")) {
InetAddress addr;
try {
addr = InetAddress.getLocalHost();
ip = addr.getHostAddress();
} catch (UnknownHostException e) {
log.error("获取失败",e);
}
return ip;
} else {
try {
Enumeration<?> e1 = (Enumeration<?>) NetworkInterface
.getNetworkInterfaces();
while (e1.hasMoreElements()) {
NetworkInterface ni = (NetworkInterface) e1.nextElement();
if (!ni.getName().equals("eth0")) {
continue;
} else {
Enumeration<?> e2 = ni.getInetAddresses();
while (e2.hasMoreElements()) {
InetAddress ia = (InetAddress) e2.nextElement();
if (ia instanceof Inet6Address)
continue;
ip = ia.getHostAddress();
return ip;
}
break;
}
}
} catch (SocketException e) {
log.error("获取失败",e);
}
}
return "";
}
}
import java.lang.annotation.*;
//Type 代表可以放在类上面 Methon代表可以放在方法上
@Target({ElementType.TYPE_USE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogAnnotation {
String module() default "";
String operator() default "";
}
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
@Component
@Aspect //切面 定义了通知和切点的关系
@Slf4j
public class LogAspect {
@Autowired
private RabbitTemplate rabbitTemplate;
@Pointcut("@annotation(com.chk.commom.aop.Log.LogAnnotation)")
public void pt(){
}
//环绕通知
@Around("pt()")
public Object log(ProceedingJoinPoint point) throws Throwable {
long beginTime = System.currentTimeMillis();
//执行方法
Object result = point.proceed();
//执行时长(毫秒)
long time = System.currentTimeMillis() - beginTime;
//保存日志
recordLog(point, time);
return result;
}
private void recordLog(ProceedingJoinPoint joinPoint, long time) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class);
log.info("=====================log start================================");
log.info("业务 :{}",logAnnotation.module());
//请求的方法名
String className = joinPoint.getTarget().getClass().getName();
String methodName = signature.getName();
log.info("请求的方法地址:{}",className + "." + methodName + "()");
//获取request 设置IP地址
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
// log.info("用户ip:{}", IpUtil.getIpAddr(request)); 此处ip包在上方
log.info("执行时间 : {} ms",time);
log.info("=====================log end================================");
}
}
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
/**
* @author 阿楠
* code生成工具类
*/
public class CodeUtils {
/**
* 生成验证码图片的宽度
*/
private int width = 100;
/**
* 生成验证码图片的高度
*/
private int height = 30;
/**
* 字符样式
*/
private String[] fontNames = { "宋体", "楷体", "隶书", "微软雅黑" };
/**
* 定义验证码图片的背景颜色为白色
*/
private Color bgColor = new Color(255, 255, 255);
/**
* 生成随机
*/
private Random random = new Random();
/**
* 定义code字符
*/
private String codes = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
/**
* 记录随机字符串
*/
private String text;
/**
* 获取一个随意颜色
* @return
*/
private Color randomColor() {
int red = random.nextInt(150);
int green = random.nextInt(150);
int blue = random.nextInt(150);
return new Color(red, green, blue);
}
/**
* 获取一个随机字体
*
* @return
*/
private Font randomFont() {
String name = fontNames[random.nextInt(fontNames.length)];
int style = random.nextInt(4);
int size = random.nextInt(5) + 24;
return new Font(name, style, size);
}
/**
* 获取一个随机字符
*
* @return
*/
private char randomChar() {
return codes.charAt(random.nextInt(codes.length()));
}
/**
* 创建一个空白的BufferedImage对象
*
* @return
*/
private BufferedImage createImage() {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = (Graphics2D) image.getGraphics();
//设置验证码图片的背景颜色
g2.setColor(bgColor);
g2.fillRect(0, 0, width, height);
return image;
}
public BufferedImage getImage() {
BufferedImage image = createImage();
Graphics2D g2 = (Graphics2D) image.getGraphics();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 4; i++) {
String s = randomChar() + "";
sb.append(s);
g2.setColor(randomColor());
g2.setFont(randomFont());
float x = i * width * 1.0f / 4;
g2.drawString(s, x, height - 8);
}
this.text = sb.toString();
drawLine(image);
return image;
}
/**
* 绘制干扰线
*
* @param image
*/
private void drawLine(BufferedImage image) {
Graphics2D g2 = (Graphics2D) image.getGraphics();
int num = 5;
for (int i = 0; i < num; i++) {
int x1 = random.nextInt(width);
int y1 = random.nextInt(height);
int x2 = random.nextInt(width);
int y2 = random.nextInt(height);
g2.setColor(randomColor());
g2.setStroke(new BasicStroke(1.5f));
g2.drawLine(x1, y1, x2, y2);
}
}
public String getText() {
return text;
}
public static void output(BufferedImage image, OutputStream out) throws IOException {
ImageIO.write(image, "JPEG", out);
}
}
使用方法,类似
@GetMapping("/code")
@LogAnnotation(module = "验证码")
public void code(HttpServletRequest request,
HttpServletResponse res) throws IOException {
CodeUtils code = new CodeUtils();
BufferedImage image = code.getImage();
String text = code.getText();
HttpSession session = request.getSession(true);
session.setAttribute("code", text);
System.out.println(text);
/**
* 图片传输
*/
CodeUtils.output(image,res.getOutputStream());
/**
* 变为 数据 传输
*/
//
// ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// ImageIO.write(image, "jpg", byteArrayOutputStream);
// byte[] imageBytes = byteArrayOutputStream.toByteArray();
//
// // 将字节数组转换为Base64编码的字符串
// String base64Image = Base64.getEncoder().encodeToString(imageBytes);
//
// // 拼接成data:image格式
// String dataURL = "data:image/jpeg;base64," + base64Image;
//
//
// return dataURL;
// System.out.println("data:image格式:" + dataURL);
/**
* 变为 data:image 数据 传输
*/
}
import java.util.Collection;
import java.util.Map;
public class VoidJudgeUtils {
public static boolean isBlank(Object obj) {
if (obj == null)
return true;
if (obj instanceof CharSequence)
return ((CharSequence) obj).length() == 0;
if (obj instanceof Collection)
return ((Collection) obj).isEmpty();
if (obj instanceof Map)
return ((Map) obj).isEmpty();
if (obj instanceof Object[]) {
Object[] object = (Object[]) obj;
if (object.length == 0) {
return true;
}
boolean empty = true;
for (int i = 0; i < object.length; i++) {
if (!isBlank(object[i])) {
empty = false;
break;
}
}
return empty;
}
return false;
}
public static boolean isNotBlank(Object obj) {
return !isBlank(obj);
}
}