java常用工具类

目录

AuthContextHolder.java

CreateVerifiCodeImage.java    绘制验证码图片

JwtHelper.java

MD5.java  

Result.java 全局统一返回结果类

ResultCodeEnum.java  统一返回结果状态信息类

UploadFile.java  上传文件的工具类

AuthContextHolder.java

import javax.servlet.http.HttpServletRequest;

public class AuthContextHolder {

    //从请求头token获取userid
    public static Long getUserIdToken(HttpServletRequest request) {
        //从请求头token
        String token = request.getHeader("token");
        //调用工具类
        Long userId = JwtHelper.getUserId(token);
        return userId;
    }

    //从请求头token获取name
    public static String getUserName(HttpServletRequest request) {
        //从header获取token
        String token = request.getHeader("token");
        //jwt从token获取username
        String userName = JwtHelper.getUserName(token);
        return userName;
    }
}

CreateVerifiCodeImage.java    绘制验证码图片

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;

/**
 * @project: ssm_sms
 * @description: 绘制验证码图片
 */
public class CreateVerifiCodeImage {

    private static int WIDTH = 90;
    private static int HEIGHT = 35;
    private static int FONT_SIZE = 20; //字符大小
    private static char[] verifiCode; //验证码
    private static BufferedImage verifiCodeImage; //验证码图片

    /**
     * @description: 获取验证码图片
     * @param: no
     * @return: java.awt.image.BufferedImage
     */
    public static BufferedImage getVerifiCodeImage() {
        // 创建一个指定宽度、高度和颜色深度的BufferedImage对象
        verifiCodeImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_BGR);

        // 获取BufferedImage的对象Graphics,用于绘制图像
        Graphics graphics = verifiCodeImage.getGraphics();

        // 生成验证码字符串
        verifiCode = generateCheckCode();

        // 绘制验证码背景
        drawBackground(graphics);
        // 在背景上绘制验证码数字或字符
        drawRands(graphics, verifiCode);

        // 释放Graphics对象的资源
        graphics.dispose();

        // 返回生成的验证码图像
        return verifiCodeImage;
    }

    /**
     * @description: 获取验证码
     * @param: no
     * @return: char[]
     */
    public static char[] getVerifiCode() {
        return verifiCode;
    }

    /**
     * 随机生成一个包含4个字符的验证码。
     * 验证码的字符集包括0-9、小写a-z、大写A-Z。
     *
     * @return char[] 返回一个长度为4的字符数组,每个字符都是验证码的一部分。
     */
    private static char[] generateCheckCode() {
        // 定义可用字符集合
        String chars = "0123456789abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        char[] rands = new char[4]; // 初始化一个长度为4的字符数组用于存放随机字符

        // 生成4个随机字符
        for (int i = 0; i < 4; i++) {
            // 生成随机索引,用于从chars中选取一个字符
            int rand = (int) (Math.random() * (10 + 26 * 2));
            rands[i] = chars.charAt(rand); // 将选取的字符存入数组
        }

        return rands;
    }


    /**
     * 绘制验证码的函数。
     * @param g Graphics对象,用于绘制验证码。
     * @param rands 包含随机字符的数组,用于生成验证码。
     * 该函数没有返回值。
     */
    private static void drawRands(Graphics g, char[] rands) {
        // 设置字体为粗体的"Console",大小为预定义的FONT_SIZE
        g.setFont(new Font("Console", Font.BOLD, FONT_SIZE));

        // 遍历字符数组,逐个绘制字符
        for (int i = 0; i < rands.length; i++) {
            // 为每个字符随机设置颜色
            g.setColor(getRandomColor());
            // 在画布上绘制字符,位置为(i * FONT_SIZE + 10, 25)
            g.drawString("" + rands[i], i * FONT_SIZE + 10, 25);
        }
    }


    /**
     * 绘制验证码图片的背景。
     * 这个方法通过绘制随机的色块和干扰点来创建一个具有噪声的背景,以增加验证码的抗自动识别能力。
     *
     * @param g Graphics对象,用于绘制图形。
     * @return void 方法没有返回值。
     */
    private static void drawBackground(Graphics g) {

        // 设置背景颜色并填充整个验证码图片区域
        g.setColor(Color.white);
        g.fillRect(0, 0, WIDTH, HEIGHT);

        // 绘制验证码干扰点
        // 这一环节是为了增加验证码的复杂度,使得计算机更难识别。
        for (int i = 0; i < 200; i++) {
            int x = (int) (Math.random() * WIDTH); // 随机生成点的x坐标
            int y = (int) (Math.random() * HEIGHT); // 随机生成点的y坐标
            g.setColor(getRandomColor()); // 随机设置颜色
            g.drawOval(x, y, 1, 1); // 绘制单个像素的圆点

        }
    }



    /**
     * @description: 获取随机颜色
     * @param: no
     * @return: java.awt.Color
     */
    private static Color getRandomColor() {
        Random ran = new Random();
        return new Color(ran.nextInt(220), ran.nextInt(220), ran.nextInt(220));
    }
}

JwtHelper.java

import io.jsonwebtoken.*;
import org.springframework.util.StringUtils;

import java.util.Date;

public class JwtHelper {
    private static long tokenExpiration = 24*60*60*1000;
    private static String tokenSignKey = "123456";

/**
 * 生成token字符串。
 * 该token包含用户ID和用户类型信息,用于用户身份验证。
 *
 * @param userId 用户的ID,唯一标识一个用户。
 * @param userType 用户的类型,用于区分不同类型的用户(如普通用户、管理员等)。
 * @return 返回生成的token字符串。
 */
public static String createToken(Long userId, Integer userType) {
    // 使用JWT构建器开始构建token
    String token = Jwts.builder()
            .setSubject("YYGH-USER") // 设置token的主题
            .setExpiration(new Date(System.currentTimeMillis() + tokenExpiration)) // 设置token的过期时间

            // 添加自定义的声明,这里包含用户ID和用户类型
            .claim("userId", userId)
            .claim("userType", userType)
            // 使用HS512算法和预定义的tokenSignKey对token进行签名
            .signWith(SignatureAlgorithm.HS512, tokenSignKey)

            // 对token进行GZIP压缩
            .compressWith(CompressionCodecs.GZIP)

            // 将构建好的token对象转换成紧凑的字符串形式
            .compact();
    return token;
}

    /**
     * 从token字符串中解析并获取用户ID。
     *
     * @param token 用户身份验证的token字符串。
     * @return 如果token有效并包含userId,则返回对应的用户ID(Long类型);如果token无效或缺失userId,则返回null。
     */
    public static Long getUserId(String token) {
        // 检查token是否为空
        if(StringUtils.isEmpty(token)) return null;

        // 使用JJWT解析token并获取其中的声明
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);
        Claims claims = claimsJws.getBody();

        // 从声明中获取用户ID
        Integer userId = (Integer)claims.get("userId");

        // 将用户ID转换为Long类型并返回
        return userId.longValue();
    }

    /**
     * 从token字符串中获取用户类型。
     *
     * @param token 用户的token字符串,用于身份验证和授权。
     * @return 返回从token中解析出的用户类型,如果token为空或解析失败则返回null。
     */
    public static Integer getUserType(String token) {
        // 检查token是否为空
        if(StringUtils.isEmpty(token)) return null;

        // 使用JJWT库解析token并获取其中的声明
        Jws<Claims> claimsJws
                = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);
        Claims claims = claimsJws.getBody();

        // 从声明中获取并返回用户类型
        return (Integer)(claims.get("userType"));
    }

    /**
     * 从token字符串中获取用户名。
     *
     * @param token 用户身份验证的令牌。
     * @return 返回从token中解析出的用户名,如果token为空或解析失败则返回空字符串。
     */
    public static String getUserName(String token) {
        // 检查token是否为空
        if(StringUtils.isEmpty(token)) return "";

        // 解析token为Claims对象
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);
        Claims claims = claimsJws.getBody();

        // 从Claims中获取用户名并返回
        return (String)claims.get("userName");
    }

    /**
     * 判断token是否有效。
     * 这个方法通过解析token并检查其是否过期来判断token的有效性。
     *
     * @param token 需要验证的token字符串。
     * @return boolean 如果token未过期,则返回false,表示有效;如果token已过期或解析失败,则返回true。
     */
    public static boolean isExpiration(String token){
        try {
            // 解析token,获取其过期时间,并判断是否当前时间之前
            boolean isExpire = Jwts.parser()
                    .setSigningKey(tokenSignKey) // 设置用于签名的密钥
                    .parseClaimsJws(token) // 解析token为Claims
                    .getBody() // 获取token的主体(包含claims)
                    .getExpiration().before(new Date()); // 判断token是否已过期
            // 如果token未过期,则返回false,表示有效
            return isExpire;
        }catch(Exception e) {
            // 如果解析过程中发生异常,认为token无效或已过期,返回true
            return true;
        }
    }


    /**
     * 刷新Token
     * @param token
     * @return
     */
    public String refreshToken(String token) {
        String refreshedToken;
        try {
            final Claims claims = Jwts.parser()
                    .setSigningKey(tokenSignKey)
                    .parseClaimsJws(token)
                    .getBody();
            refreshedToken = JwtHelper.createToken(getUserId(token), getUserType(token));
        } catch (Exception e) {
            refreshedToken = null;
        }
        return refreshedToken;
    }

        public static void main(String[] args) {
//        String token = JwtHelper.createToken(1L, "lucy");
//        System.out.println(token);
//        System.out.println(JwtHelper.getUserId(token));
//        System.out.println(JwtHelper.getUserName(token));
    }
}

MD5.java  

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;


public final class MD5 {

    /**
     * 使用MD5算法对输入字符串进行加密
     *
     * @param strSrc 需要加密的源字符串
     * @return 经过MD5加密后,转换为16进制字符串的结果
     */
    public static String encrypt(String strSrc) {
        try {
            // 定义16进制字符数组,用于转换加密后的字节数据
            char hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
                    '9', 'a', 'b', 'c', 'd', 'e', 'f' };

            // 将源字符串转换为字节数组
            byte[] bytes = strSrc.getBytes();

            // 获取MD5消息摘要算法的实例
            MessageDigest md = MessageDigest.getInstance("MD5");

            // 更新消息摘要
            md.update(bytes);

            // 计算消息摘要
            bytes = md.digest();

            // 拼接摘要为16进制字符串
            int j = bytes.length;
            char[] chars = new char[j * 2];
            int k = 0;
            for (int i = 0; i < bytes.length; i++) {
                byte b = bytes[i];
                // 将每个字节转换为两位16进制数
                chars[k++] = hexChars[b >>> 4 & 0xf];
                chars[k++] = hexChars[b & 0xf];
            }

            // 返回转换后的字符串
            return new String(chars);
        } catch (NoSuchAlgorithmException e) {
            // 处理算法不可用的异常
            e.printStackTrace();
            throw new RuntimeException("MD5加密出错!!+" + e);
        }
    }


}

Result.java 全局统一返回结果类

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
 * 全局统一返回结果类
 *
 */
@Data
@ApiModel(value = "全局统一返回结果")
public class Result<T> {

    @ApiModelProperty(value = "返回码")
    private Integer code;

    @ApiModelProperty(value = "返回消息")
    private String message;

    @ApiModelProperty(value = "返回数据")
    private T data;

    public Result(){}

    // 返回数据
    protected static <T> Result<T> build(T data) {
        Result<T> result = new Result<T>();
        if (data != null)
            result.setData(data);
        return result;
    }

    public static <T> Result<T> build(T body, ResultCodeEnum resultCodeEnum) {
        Result<T> result = build(body);
        result.setCode(resultCodeEnum.getCode());
        result.setMessage(resultCodeEnum.getMessage());
        return result;
    }

    public static<T> Result<T> ok(){
        return Result.ok(null);
    }

    /**
     * 操作成功
     * @param data
     * @param <T>
     * @return
     */
    public static<T> Result<T> ok(T data){
        Result<T> result = build(data);
        return build(data, ResultCodeEnum.SUCCESS);
    }

    public static<T> Result<T> fail(){
        return Result.fail(null);
    }

    /**
     * 操作失败
     * @param data
     * @param <T>
     * @return
     */
    public static<T> Result<T> fail(T data){
        Result<T> result = build(data);
        return build(data, ResultCodeEnum.FAIL);
    }

    public Result<T> message(String msg){
        this.setMessage(msg);
        return this;
    }

    public Result<T> code(Integer code){
        this.setCode(code);
        return this;
    }


    public boolean isOk() {
        if(this.getCode().intValue() == ResultCodeEnum.SUCCESS.getCode().intValue()) {
            return true;
        }
        return false;
    }
}

ResultCodeEnum.java  统一返回结果状态信息类

import lombok.Getter;

/**
 * 统一返回结果状态信息类
 *
 */
@Getter
public enum ResultCodeEnum {

    SUCCESS(200,"成功"),
    FAIL(201, "失败"),
    SERVICE_ERROR(2012, "服务异常"),
    ILLEGAL_REQUEST( 204, "非法请求"),
    PAY_RUN(205, "支付中"),
    ARGUMENT_VALID_ERROR(206, "参数校验错误"),

    LOGIN_ERROR(207, "用户名或密码错误"),
    LOGIN_AUTH(208, "未登陆"),
    PERMISSION(209, "没有权限"),
    SECKILL_NO_START(210, "秒杀还没开始"),
    SECKILL_RUN(211, "正在排队中"),
    SECKILL_NO_PAY_ORDER(212, "您有未支付的订单"),
    SECKILL_FINISH(213, "已售罄"),
    SECKILL_END(214, "秒杀已结束"),
    SECKILL_SUCCESS(215, "抢单成功"),
    SECKILL_FAIL(216, "抢单失败"),
    SECKILL_ILLEGAL(217, "请求不合法"),
    SECKILL_ORDER_SUCCESS(218, "下单成功"),
    COUPON_GET(220, "优惠券已经领取"),
    COUPON_LIMIT_GET(221, "优惠券已发放完毕"),
    //2022-02-22
    LOGIN_CODE(222,"长时间未操作,会话已失效,请刷新页面后重试!"),
    CODE_ERROR(223,"验证码错误!"),
    TOKEN_ERROR(224,"Token无效!")
    ;

    private Integer code;

    private String message;

    private ResultCodeEnum(Integer code, String message) {
        this.code = code;
        this.message = message;
    }
}

UploadFile.java  上传文件的工具类

import org.apache.commons.io.filefilter.SuffixFileFilter;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @project: sms
 * @description: 上传文件的工具类
 */
public class UploadFile {

    //存储文件上传失败的错误信息
    private static Map<String, Object> error_result = new HashMap<>();
    //存储头像的上传结果信息
    private static Map<String, Object> upload_result = new HashMap<>();

    /**
     * 验证上传图片的大小、格式等信息,并尝试保存图片。
     * 
     * @param photo 用户上传的图片文件,作为MultipartFile类型传入。
     * @param path 图片文件将要保存的服务器路径。
     * @return 返回一个Map<String, Object>,其中包含上传结果的成功与否及消息。
     */
    private static Map<String, Object> uploadPhoto(MultipartFile photo, String path) {
        // 设置最大允许上传的文件大小(20MB)
        int MAX_SIZE = 20971520;
        // 获取上传文件的原始名称
        String orginalName = photo.getOriginalFilename();
        
        // 检查保存文件的目录是否存在,不存在则创建
        File filePath = new File(path);
        if (!filePath.exists()) {
            filePath.mkdirs();
        }

        // 检查上传文件大小是否符合规定
        if (photo.getSize() > MAX_SIZE) {
            error_result.put("success", false);
            error_result.put("msg", "上传的图片大小不能超过20M哟!");
            return error_result;
        }

        // 检查上传文件的类型是否被允许
        String[] suffixs = new String[]{".png", ".PNG", ".jpg", ".JPG", ".jpeg", ".JPEG", ".gif", ".GIF", ".bmp", ".BMP"};
        SuffixFileFilter suffixFileFilter = new SuffixFileFilter(suffixs);
        if (!suffixFileFilter.accept(new File(path + orginalName))) {
            error_result.put("success", false);
            error_result.put("msg", "禁止上传此类型文件! 请上传图片哟!");
            return error_result;
        }

        // 若文件大小和类型检查都通过,则应进行文件保存逻辑(当前代码未实现)
        return null;
    }


    /**
     * 获取头像的上传结果信息
     * 该方法用于处理头像上传的过程,包括检查文件、上传文件、重命名文件,并返回上传结果。
     * @param photo 用户上传的头像文件
     * @param dirPaht 上传目录的路径
     * @param portraitPath 头像在项目中的相对路径
     * @return 返回一个Map,包含上传结果的信息,如成功与否、错误消息等
     */
    public static Map<String, Object> getUploadResult(MultipartFile photo, String dirPaht, String portraitPath) {

        // 检查照片是否为空且大小大于0
        if (!photo.isEmpty() && photo.getSize() > 0) {
            // 获取图片原始名称
            String orginalName = photo.getOriginalFilename();
            // 上传图片,处理可能的上传错误
            Map<String, Object> error_result = UploadFile.uploadPhoto(photo, dirPaht);
            if (error_result != null) {
                return error_result;
            }
            // 使用UUID重命名图片以避免重复
            String newPhotoName = UUID.randomUUID() + "__" + orginalName;
            try {
                // 将上传的图片保存到指定目录下
                photo.transferTo(new File(dirPaht + newPhotoName));
                // 设置上传成功的结果
                upload_result.put("success", true);
                upload_result.put("portrait_path", portraitPath + newPhotoName);
            } catch (IOException e) {
                // 处理保存图片时可能出现的异常
                e.printStackTrace();
                upload_result.put("success", false);
                upload_result.put("msg", "上传文件失败! 服务器端发生异常!");
            }

        } else {
            // 处理未选择图片或图片为空的情况
            upload_result.put("success", false);
            upload_result.put("msg", "头像上传失败! 未找到指定图片!");
        }
        return upload_result;
    }

}

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值