java 项目中常用的工具类总结

java 项目中常用的工具类总结,第1张

1、文件 1、根据图片的链接,下载图片
package com.lingxu.module.BigDataJoinMessage.util;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * @date 2022/4/24
 * @versions 1.0
 */
public class FileUtil {


    /**
     *  这个函数负责把获取到的InputStream流保存到本地。
     * @param imgUrl  图片http url
     * @param fileName  文件名称
     * @param filePath  文件要保存的路径
     * @return
     */
    public static boolean saveImageToDisk(String imgUrl, String fileName, String filePath) {
        InputStream inputStream = null;
        inputStream = getInputStream(imgUrl);//调用getInputStream()函数。
        byte[] data = new byte[1024];
        int len = 0;

        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(filePath + fileName);//初始化一个FileOutputStream对象。
            while ((len = inputStream.read(data))!=-1) {//循环读取inputStream流中的数据,存入文件流fileOutputStream
                fileOutputStream.write(data,0,len);
            }

        } catch (IOException e) {
            e.printStackTrace();
            return false;
        } finally{//finally函数,不管有没有异常发生,都要调用这个函数下的代码
            if(fileOutputStream!=null){
                try {
                    fileOutputStream.close();//记得及时关闭文件流
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(inputStream!=null){
                try {
                    inputStream.close();//关闭输入流
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return true;
    }

    /**
     * 将图片下载到本地
     * @param imgUrl  图片的url
     * @return 返回文件流
     */
    public static InputStream getInputStream(String imgUrl){
        InputStream inputStream = null;
        HttpURLConnection httpURLConnection = null;
        try {
            URL url = new URL(imgUrl);//创建的URL
            httpURLConnection = (HttpURLConnection) url.openConnection();//打开链接
            httpURLConnection.setConnectTimeout(3000);//设置网络链接超时时间,3秒,链接失败后重新链接
            httpURLConnection.setDoInput(true);//打开输入流
            httpURLConnection.setRequestMethod("GET");//表示本次Http请求是GET方式
            int responseCode = httpURLConnection.getResponseCode();//获取返回码
            if (responseCode == 200) {//成功为200
                //从服务器获得一个输入流
                inputStream = httpURLConnection.getInputStream();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return inputStream;

    }

}

2、从后台的resource下,下载文件
 /**
     * Title: 导出资源预编模板Excel
     *
     * @param response
     * @throws Exception
     */
    @ApiOperation(value = "导出模板")
    @GetMapping(value = "/exportPersonExcel")
    public void downloadExcel(HttpServletResponse response) throws Exception {
        try {
            InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("excelTemplates/干部信息导入模板.xls");
            //获取要下载的模板名称
            String fileName = "干部信息导入模板.xls";
            response.setHeader("content-type", "application/octet-stream");
            response.setContentType("application/octet-stream");
            // 下载文件能正常显示中文
            fileName = URLEncoder.encode(fileName, "UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.setHeader("fileName", fileName);
            response.setHeader("Access-Control-Expose-Headers", "filename");

            OutputStream out = response.getOutputStream();
            byte[] b = new byte[2048];
            int len;
            while ((len = resourceAsStream.read(b)) != -1) {
                out.write(b, 0, len);
            }
            out.close();
            resourceAsStream.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }
3、读取文件流进行全局替换,适合小文件
	public static void main(String[] args){
		String filePath = "D:\sql\UT_PERSON_INFO.sql";
		String outPath = "D:\sql\UT_PERSON_INFO.sql";
		try {
			autoReplace(filePath,outPath);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}


		public static  void autoReplace(String filePath, String outPath) throws IOException {
			File file = new File(filePath);
			Long fileLength = file.length();
			byte[] fileContext = new byte[fileLength.intValue()];
			FileInputStream in = new FileInputStream(filePath);
			in.read(fileContext);
			in.close();
			String str = new String(fileContext);
			str = str.replace("\"PUBLIC\".", " ");
			str = str.replace("\"", "'");

			PrintWriter out = new PrintWriter(outPath);
			out.write(str.toCharArray());
			out.flush();
			out.close();
		}
4、读取文件,每行读取,然后替换指定的内容 删除指定的行数
public static  void ChangeFile (String filePath, String outPath) throws IOException {
			try {
				BufferedReader bufReader = new BufferedReader(new InputStreamReader(new FileInputStream(new File(filePath))));//数据流读取文件

				StringBuffer strBuffer = new StringBuffer();
				String empty = "";
				String tihuan = "";
				List<String> arrList = new ArrayList<>();
				for (String temp = null; (temp = bufReader.readLine()) != null; temp = null) {
					if(temp.contains("\"PUBLIC\".")) {
						temp = temp.replace("\"PUBLIC\"."," ");
					}
					if(temp.contains("\"")) {
						temp = temp.replace("\"","'");
					}
					arrList.add(temp);

				}
				//删除22行之前的数据
				arrList = arrList.subList(21,arrList.size());
				for (String str : arrList){
					strBuffer.append(str);
					strBuffer.append(System.getProperty("line.separator"));//行与行之间的分割
				}
				bufReader.close();
				PrintWriter printWriter = new PrintWriter(outPath);//替换后输出的文件位置
				printWriter.write(strBuffer.toString().toCharArray());
				printWriter.flush();
				printWriter.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
5、java 字节码数组和文件的相互转换(工具类)
public class FileUtil {

    //将文件转换成Byte数组
    public static byte[] getBytesByFile(String pathStr) {
        File file = new File(pathStr);
        try {
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
            byte[] b = new byte[1000];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            fis.close();
            byte[] data = bos.toByteArray();
            bos.close();
            return data;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    //将Byte数组转换成文件
    public static void getFileByBytes(byte[] bytes, String filePath, String fileName) {
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        File file = null;
        try {
            File dir = new File(filePath);
            if (!dir.exists() && dir.isDirectory()) {// 判断文件目录是否存在
                dir.mkdirs();
            }
            file = new File(filePath + "\" + fileName);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(bytes);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
6、excel 单元格处理
package com.lingxu.base.common.util;

import com.lingxu.base.common.constant.CommonConstant;
import com.lingxu.base.common.constant.DataTypeConstant;
import com.lingxu.base.common.exception.BussException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DateUtil;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class CellValueFormatUtil {

    /**
     * 将Cell转换为对应Entity中Filed的格式
     *
     * @param value    单元格中的值
     * @param parmtype 要转成的entity类型
     * @param cellType 来源单元格类型
     * @return obj 转换后的值
     * @throws ParseException
     */
    public static Object importFormat(String value, String parmtype, CellType cellType) throws ParseException {
        Object obj = new Object();
        if (parmtype.equals(DataTypeConstant.INTEGER_TYPE_NAME)) {
            Double d = Double.parseDouble(value);
            obj = d.intValue();
        } else if (parmtype.equals(DataTypeConstant.DOUBLE_TYPE_NAME)) {
            obj = Double.parseDouble(value);
        } else if (parmtype.equals(DataTypeConstant.FLOAT_TYPE_NAME)) {
            Double d = Double.parseDouble(value);
            obj = d.floatValue();
        } else if (parmtype.equals(DataTypeConstant.LONG_TYPE_NAME)) {
            Double d = Double.parseDouble(value);
            obj = d.longValue();
        } else if (parmtype.equals(DataTypeConstant.DATE_TYPE_NAME)) {
            if (cellType == CellType.NUMERIC) {
                Double d = Double.parseDouble(value);
                Date date = DateUtil.getJavaDate(d);
                obj = date;
            } else {
                SimpleDateFormat sdf = new SimpleDateFormat(CommonConstant.TIME_FORMAT_YMDHMS);
                obj = sdf.parse(value);
            }
        } else if (parmtype.equals(DataTypeConstant.BIGDECIMAL_TYPE_NAME)) {
            BigDecimal ab = new BigDecimal(value);
            obj = ab;
        } else {
            obj = value;
        }
        return obj;

    }

    /**
     * 单元格转字符串
     *
     * @param cell
     * @return
     */
    public static String cellToString(Cell cell) {

        if (cell == null) {
            return null;
        } else {
            if (cell.getCellTypeEnum() == CellType.STRING) {
                return cell.getStringCellValue();
            } else if (cell.getCellTypeEnum() == CellType.NUMERIC) {
                return String.valueOf(cell.getNumericCellValue());
            } else if (cell.getCellTypeEnum() == CellType.BLANK) {
                return null;
            } else if (cell.getCellTypeEnum() == CellType.FORMULA) {
                cell.setCellType(CellType.STRING);
                return cell.getStringCellValue();
            } else {
                throw new BussException("Excel格式不正确");
            }
        }
    }
}
7、文件下载相关
package com.lingxu.base.common.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @author Lizm
 */
@Slf4j
@Component
public class CompressDownloadUtil {


    /**
     * 设置下载响应头
     *
     * @param response
     * @return
     * @author hongwei.lian
     * @date 2018年9月7日 下午3:01:59
     */
    public  HttpServletResponse setDownloadResponse(HttpServletResponse response, String downloadName) {
        response.reset();
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment;fileName*=UTF-8''"+ downloadName);
        return response;
    }

    /**
     * 字符串转换为整型数组
     *
     * @param param
     * @return
     * @author hongwei.lian
     * @date 2018年9月6日 下午6:38:39
     */
    public  Integer[] toIntegerArray(String param) {
        return Arrays.stream(param.split(","))
                .map(Integer::valueOf)
                .toArray(Integer[]::new);
    }

    /**
     * 将多个文件压缩到指定输出流中
     *
     * @param files 需要压缩的文件列表
     * @param outputStream  压缩到指定的输出流
     * @author hongwei.lian
     * @date 2018年9月7日 下午3:11:59
     */
    public  void compressZip(List<File> files, OutputStream outputStream) {
        ZipOutputStream zipOutStream = null;
        try {
            //-- 包装成ZIP格式输出流
            zipOutStream = new ZipOutputStream(new BufferedOutputStream(outputStream));
            // -- 设置压缩方法
            zipOutStream.setMethod(ZipOutputStream.DEFLATED);
            //-- 将多文件循环写入压缩包
            for (int i = 0; i < files.size(); i++) {
                File file = files.get(i);
                FileInputStream filenputStream = new FileInputStream(file);
                byte[] data = new byte[(int) file.length()];
                filenputStream.read(data);
                //-- 添加ZipEntry,并ZipEntry中写入文件流,这里,加上i是防止要下载的文件有重名的导致下载失败
                zipOutStream.putNextEntry(new ZipEntry(i + file.getName()));
                zipOutStream.write(data);
                filenputStream.close();
                zipOutStream.closeEntry();
            }
        } catch (IOException e) {
            log.error("输入异常"+e.getMessage());
        }  finally {
            try {
                if (Objects.nonNull(zipOutStream)) {
                    zipOutStream.flush();
                    zipOutStream.close();
                }
                if (Objects.nonNull(outputStream)) {
                    outputStream.close();
                }
            } catch (IOException e) {
                log.error("输入异常"+e.getMessage());
            }
        }
    }

    /**
     * 下载文件
     *
     * @param zipFilepath 需要下载文件的路径
     */
    public  HttpServletResponse downloadFile(String zipFilepath,HttpServletResponse response) {
        try {
            // path是指欲下载的文件的路径。
            File file = new File(zipFilepath);
            // 取得文件名。
            String filename = file.getName();
            // 取得文件的后缀名。
            String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();

            // 以流的形式下载文件。
            InputStream fis = new BufferedInputStream(new FileInputStream(zipFilepath));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();
            // 设置response的Header
            response.addHeader("Content-Disposition", "attachment;filename="  + URLEncoder.encode(filename, "UTF-8"));
            response.addHeader("Content-Length", "" + file.length());
            response.addHeader("Access-Control-Allow-Origin","*");
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            toClient.write(buffer);
            toClient.flush();
            toClient.close();
            return null;
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return response;
    }

    /**
     * 删除指定路径的文件
     *
     * @param filepath
     * @author hongwei.lian
     * @date 2018年9月7日 下午3:44:53
     */
    public  void deleteFile(String filepath) {
        File file = new File(filepath);
        deleteFile(file);
    }

    /**
     * 删除指定文件
     *
     * @param file
     * @author hongwei.lian
     * @date 2018年9月7日 下午3:45:58
     */
    public  void deleteFile(File file) {
        //-- 路径为文件且不为空则进行删除
        if (file.isFile() && file.exists()) {
            file.delete();
        }
    }


}
8、文件复制,删除等
package com.lingxu.base.common.util;


import com.baomidou.mybatisplus.core.toolkit.StringUtils;

import java.io.*;
import java.nio.channels.FileChannel;
import java.util.HashSet;
import java.util.Set;

public class FileUtils {
    //复制方法
    public static boolean copyDir(String src, String des)  {
        try {
            //初始化文件复制
            File file1=new File(src);
            if(!file1.exists()){
                return false;
            }else{
                //把文件里面内容放进数组
                File[] fs=file1.listFiles();
                //初始化文件粘贴
                File file2=new File(des);
                //判断是否有这个文件有不管没有创建
                if(!file2.exists()){
                    file2.mkdirs();
                }
                //遍历文件及文件夹
                for (File f : fs) {
                    if(f.isFile()){
                        //文件
                        fileCopy(f.getPath(),des+ File.separator+f.getName()); //调用文件拷贝的方法
                    }else if(f.isDirectory()){
                        //文件夹
                        copyDir(f.getPath(),des+File.separator+f.getName());//继续调用复制方法      递归的地方,自己调用自己的方法,就可以复制文件夹的文件夹了
                    }
                }
                return true;
            }
        }catch (Exception e){
            e.getStackTrace();
            return false;
        }
    }

    /**
     * 文件复制的具体方法
     */
    private static void fileCopy(String src, String des) throws Exception {
        //io流固定格式
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(src));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(des));
        int i = -1;//记录获取长度
        byte[] bt = new byte[2014];//缓冲区
        while ((i = bis.read(bt))!=-1) {
            bos.write(bt, 0, i);
        }
        bis.close();
        bos.close();
        //关闭流
    }

    public static String getFileName(String fName){
        String fileName = null;
        File tempFile =new File( fName.trim());
        if(tempFile.exists()){
            File[] array = tempFile.listFiles();
            for(int i = 0 ; i<array.length ; i++){
                String houzhui = array[i].toString().substring(array[i].toString().lastIndexOf(".") + 1);
                if(houzhui.equals("iw")||houzhui.equals(".zip")){
                    fileName = array[i].getName();
                }
            }
        }
        return fileName;
    }

    /**
     * 删除空目录
     * @param dir 将要删除的目录路径
     */
    private static void doDeleteEmptyDir(String dir) {
        boolean success = (new File(dir)).delete();
        if (success) {

        } else {

        }
    }

    /**
     * 递归删除目录下的所有文件及子目录下所有文件
     * @param dir 将要删除的文件目录
     * @return boolean Returns "true" if all deletions were successful.
     *                 If a deletion fails, the method stops attempting to
     *                 delete and returns "false".
     */
    public static boolean deleteDir(File dir) {
        if (dir.isDirectory()) {
            String[] children = dir.list();
            //递归删除目录中的子目录下
            for (int i=0; i<children.length; i++) {
                boolean success = deleteDir(new File(dir, children[i]));
                if (!success) {
                    return false;
                }
            }
        }
        // 目录此时为空,可以删除
        return dir.delete();
    }

    public static Set<String> getDirName(String fName){
        Set<String> set = new HashSet<>();
        String fileName = null;
        File tempFile =new File( fName.trim());
        if(tempFile.exists()){
            File[] array = tempFile.listFiles();
            for(int i = 0 ; i<array.length ; i++){
                set.add(array[i].getName().toString());
            }
        }
        System.out.println(set);
        return set;
    }

    /*判断文件是否存在*/
    public static boolean isExists(String filePath) {
        File file = new File(filePath);
        return file.exists();
    }

    /*判断是否是文件夹*/
    public static boolean isDir(String path) {
        File file = new File(path);
        if(file.exists()){
            return file.isDirectory();
        }else{
            return false;
        }
    }

    /**
     * 文件或者目录重命名
     * @param oldFilePath 旧文件路径
     * @param newName 新的文件名,可以是单个文件名和绝对路径
     * @return
     */
    public static boolean renameTo(String oldFilePath, String newName) {
        try {
            File oldFile = new File(oldFilePath);
            //若文件存在
            if(oldFile.exists()){
                //判断是全路径还是文件名
                if (newName.indexOf("/") < 0 && newName.indexOf("\") < 0){
                    //单文件名,判断是windows还是Linux系统
                    String absolutePath = oldFile.getAbsolutePath();
                    if(newName.indexOf("/") > 0){
                        //Linux系统
                        newName = absolutePath.substring(0, absolutePath.lastIndexOf("/") + 1)  + newName;
                    }else{
                        newName = absolutePath.substring(0, absolutePath.lastIndexOf("\") + 1)  + newName;
                    }
                }
                File file = new File(newName);
                //判断重命名后的文件是否存在
                if(file.exists()){
                    System.out.println("该文件已存在,不能重命名");
                }else{
                    //不存在,重命名
                    return oldFile.renameTo(file);
                }
            }else {
                System.out.println("原该文件不存在,不能重命名");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }


    /*文件拷贝 *** 作*/
    public static void copy(String sourceFile, String targetFile) {
        File source = new File(sourceFile);
        File target = new File(targetFile);
        target.getParentFile().mkdirs();
        FileInputStream fis = null;
        FileOutputStream fos = null;
        FileChannel in = null;
        FileChannel out = null;
        try {
            fis = new FileInputStream(source);
            fos = new FileOutputStream(target);
            in = fis.getChannel();//得到对应的文件通道
            out = fos.getChannel();//得到对应的文件通道
            in.transferTo(0, in.size(), out);//连接两个通道,并且从in通道读取,然后写入out通道
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null){
                    out.close();
                }
                if (in != null){
                    in.close();
                }
                if (fos != null){
                    fos.close();
                }
                if (fis != null){
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 通过上一层目录和目录名得到最后的目录层次
     * @param previousDir 上一层目录
     * @param dirName 当前目录名
     * @return
     */
    public static String getSaveDir(String previousDir, String dirName) {
        if (StringUtils.isNotBlank(previousDir)){
            dirName = previousDir + "/" + dirName + "/";
        }else {
            dirName = dirName + "/";
        }
        return dirName;
    }

    /**
     * 如果目录不存在,就创建文件
     * @param dirPath
     * @return
     */
    public static String mkdirs(String dirPath) {
        try{
            File file = new File(dirPath);
            if(!file.exists()){
                file.mkdirs();
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        return dirPath;
    }

    public static void main(String[] args) throws Exception {

        //一;创建根文件夹
        String path="E://OaTestFile/";
        String name="办公室";
        String endPath=path+name;

        if (isExists(endPath)){
            System.out.println("文件夹已存在");
        }else {
            mkdirs(endPath);
            System.out.println("ok");
        }



    }

}
9、大文件下载
package com.lingxu.base.common.util;



import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @date 2022/3/18
 * @versions 1.0
 */
public class FolderToZipUtil {

    public static void zip(String sourceFileName, HttpServletResponse response){
        ZipOutputStream out = null;
        BufferedOutputStream bos = null;
        try {
            //将zip以流的形式输出到前台
            response.setHeader("content-type", "application/octet-stream");
            response.setCharacterEncoding("utf-8");
            // 设置浏览器响应头对应的Content-disposition
            //参数中 testZip 为压缩包文件名,尾部的.zip 为文件后缀
            response.setHeader("Content-disposition",
                    "attachment;filename=" + new String("我是压缩后的文件".getBytes("gbk"), "iso8859-1")+".zip");
            //创建zip输出流
            out = new ZipOutputStream(response.getOutputStream());
            //创建缓冲输出流
            bos = new BufferedOutputStream(out);
            File sourceFile = new File(sourceFileName);
            //调用压缩函数
            compress(out, bos, sourceFile, sourceFile.getName());
            out.flush();

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            IOCloseUtil.close(bos, out);
        }
    }

    /**
     * 文件压缩
     * @param out
     * @param bos
     * @param sourceFile
     * @param base
     */
    public static void compress(ZipOutputStream out, BufferedOutputStream bos, File sourceFile, String base){
        FileInputStream fos = null;
        BufferedInputStream bis = null;
        try {
            //如果路径为目录(文件夹)
            if (sourceFile.isDirectory()) {
                //取出文件夹中的文件(或子文件夹)
                File[] flist = sourceFile.listFiles();
                if (flist.length == 0) {//如果文件夹为空,则只需在目的地zip文件中写入一个目录进入点
                    out.putNextEntry(new ZipEntry(base + "/"));
                } else {//如果文件夹不为空,则递归调用compress,文件夹中的每一个文件(或文件夹)进行压缩
                    for (int i = 0; i < flist.length; i++) {
                        compress(out, bos, flist[i], base + "/" + flist[i].getName());
                    }
                }
            } else {//如果不是目录(文件夹),即为文件,则先写入目录进入点,之后将文件写入zip文件中
                out.putNextEntry(new ZipEntry(base));
                fos = new FileInputStream(sourceFile);
                bis = new BufferedInputStream(fos);

                int tag;
                //将源文件写入到zip文件中
                while ((tag = bis.read()) != -1) {
                    out.write(tag);
                }
                bis.close();
                fos.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            IOCloseUtil.close(bis,fos);
        }
    }
}
2、http请求 1、get请求、post请求
package com.lingxu.module.BigDataJoinMessage.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.net.SocketTimeoutException;


/**
 * @version 200
 * @date 2021/9/16 17:24
 */
@Slf4j
public class HttpClientUtilPersect {

    static PoolingHttpClientConnectionManager poolingClient = null;
    public static void init() {
        poolingClient = new PoolingHttpClientConnectionManager();
        poolingClient.setDefaultMaxPerRoute(100);// 对每个指定连接的服务器(指定的ip)可以创建并发20 socket进行访问
        poolingClient.setMaxTotal(500);// 创建socket的上线是200
    }

    // 获取连接
    public static CloseableHttpClient getHttpClient(int timeout) {
        // 设置连接超时时间
        Integer CONNECTION_TIMEOUT = 2 * 1000; // 设置请求超时5秒钟 根据业务调整
        Integer SO_TIMEOUT = timeout * 1000; // 设置等待数据超时时间5秒钟 根据业务调整

        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(CONNECTION_TIMEOUT)
                .setSocketTimeout(SO_TIMEOUT).build();

        //因为服务端断开连接,但并没有通知客户端,导致下次请求该服务时httpclient继续使用该连接导致报错。
        ConnectionKeepAliveStrategy connectionKeepAliveStrategy = new ConnectionKeepAliveStrategy() {
            @Override
            public long getKeepAliveDuration(HttpResponse httpResponse,
                                             HttpContext httpContext) {
                return 10000L; // tomcat默认keepAliveTimeout为20s; 要比服务端的短
            }
        };

        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        httpClientBuilder.setConnectionManager(poolingClient);
        httpClientBuilder.setDefaultRequestConfig(requestConfig);
        httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler());
        httpClientBuilder.setKeepAliveStrategy(connectionKeepAliveStrategy);
        CloseableHttpClient httpClient = httpClientBuilder.build();

        return httpClient;
    }

    /**
     * get请求
     * 直接后面拼接参数
     * @param url
     * @return
     */
    public static String doGet(String url) {

        // 创建Httpclient对象
        CloseableHttpClient httpClient = getHttpClient(4);

        String resultString = "";
        CloseableHttpResponse response = null;
        // 创建http GET请求
        HttpGet httpGet = new HttpGet(url);
        try {
            // 执行请求
            response = httpClient.execute(httpGet);
            // 判断返回状态是否为200
            if (response.getStatusLine().getStatusCode() == 200) {
                resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
            }
        } catch (ConnectTimeoutException e) {//如果是服务超时了
            //再重试一遍
            return doReapeat(httpGet);
        } catch (SocketTimeoutException e) {//如果是服务超时了
            //再重试一遍
            return doReapeat(httpGet);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("HttpClientUtil url: "+url+"+ error:{}", e);
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
                log.error("HttpClientUtil url: "+url+"+ error:{}", e);
            }
        }
        return resultString;
    }


    /**
     * post无参请求
     * @param url
     * @param
     * @return
     */
    public static String doPost(String url) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if(response !=null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return resultString;
    }



    /**
     * post传参请求
     * @param url
     * @param json  map对象json化
     * @return
     */
    public static String doPostJson(String url, String json,String auth)
          throws Exception
    {
        // 创建Httpclient对象
        url=url+"?auth="+auth;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        log.info("doPostJson请求的url"+url);
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            // 创建请求内容
            StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
            httpPost.setHeader("Content-type","application/json");
            httpPost.setEntity(entity);
            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
            log.info("doPostJson请求返回的json-{}"+resultString);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("请求报错-{}"+e.getMessage());
           throw new Exception(e);
        } finally {
            try {
                if(response !=null){
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return resultString;
    }

    /**
     * 重发
     * @param request
     * @return
     */
    private static String doReapeat(HttpRequestBase request){
        CloseableHttpClient httpClient = getHttpClient(6);//S 超时
        HttpResponse response = null;
        try {
            response = httpClient.execute(request);
            if (response.getStatusLine().getStatusCode() != 200) {
                log.error("重发,接口请求失败,httpcode="
                        + response.getStatusLine().getStatusCode() + "; url="
                        + request.getURI());
                return null;
            }
            String result = EntityUtils.toString(response.getEntity());
            return result;
        } catch (Exception e) {
            log.error("重发,调用API错误, url:" + request.getURI(), e);
            return null;
        } finally {
            close(response, httpClient);
        }
    }

    private static void close(HttpResponse response, CloseableHttpClient httpClient){
        if (response != null) {
            try {
                EntityUtils.consume(response.getEntity());
            } catch (IOException e) {
                log.error("response close error: {}", e);
            }
        }
    }

}

2、带请求头的get,post请求
package com.lingxu.base.common.util;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;

/**
 * niwei
 * http请求工具类
 */
public class HttpClientUtil {
    public static String doGet(String httpurl, Map<String, String> headers) {
        HttpURLConnection connection = null;
        InputStream is = null;
        BufferedReader br = null;
        String result = null;// 返回结果字符串
        try {
            // 创建远程url连接对象
            URL url = new URL(httpurl);
            // 通过远程url连接对象打开一个连接,强转成httpURLConnection类
            connection = (HttpURLConnection) url.openConnection();
            // 设置连接方式:get
            connection.setRequestMethod("GET");
            if (headers != null) {
                for (String key : headers.keySet()) {
                    connection.setRequestProperty(key, headers.get(key));
                }
            }
            // 设置连接主机服务器的超时时间:15000毫秒
            connection.setConnectTimeout(15000);
            // 设置读取远程返回的数据时间:60000毫秒
            connection.setReadTimeout(60000);
            // 发送请求
            connection.connect();
            // 通过connection连接,获取输入流
            if (connection.getResponseCode() == 200) {
                is = connection.getInputStream();
                // 封装输入流is,并指定字符集
                br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                // 存放数据
                StringBuffer sbf = new StringBuffer();
                String temp = null;
                while ((temp = br.readLine()) != null) {
                    sbf.append(temp);
                    sbf.append("\r\n");
                }
                result = sbf.toString();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != br) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            connection.disconnect();// 关闭远程连接
        }

        return result;
    }

    public static String doPost(String httpUrl, String param, Map<String, String> headers) {

        HttpURLConnection connection = null;
        InputStream is = null;
        OutputStream os = null;
        BufferedReader br = null;
        String result = null;
        try {
            URL url = new URL(httpUrl);
            // 通过远程url连接对象打开连接
            connection = (HttpURLConnection) url.openConnection();
            // 设置连接请求方式
            connection.setRequestMethod("POST");
            // 设置连接主机服务器超时时间:15000毫秒
            connection.setConnectTimeout(15000);
            // 设置读取主机服务器返回数据超时时间:60000毫秒
            connection.setReadTimeout(60000);
            if (headers != null) {
                for (String key : headers.keySet()) {
                    connection.setRequestProperty(key, headers.get(key));
                }
            }
            // 默认值为:false,当向远程服务器传送数据/写数据时,需要设置为true
            connection.setDoOutput(true);
            // 默认值为:true,当前向远程服务读取数据时,设置为true,该参数可有可无
            connection.setDoInput(true);
            // 设置传入参数的格式:请求参数应该是 name1=value1&name2=value2 的形式。
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            // 设置鉴权信息:Authorization: Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0
            connection.setRequestProperty("Authorization", "Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0");
            // 通过连接对象获取一个输出流
            os = connection.getOutputStream();
            // 通过输出流对象将参数写出去/传输出去,它是通过字节数组写出的
            os.write(param.getBytes());
            // 通过连接对象获取一个输入流,向远程读取
            if (connection.getResponseCode() == 200) {

                is = connection.getInputStream();
                // 对输入流对象进行包装:charset根据工作项目组的要求来设置
                br = new BufferedReader(new InputStreamReader(is, "UTF-8"));

                StringBuffer sbf = new StringBuffer();
                String temp = null;
                // 循环遍历一行一行读取数据
                while ((temp = br.readLine()) != null) {
                    sbf.append(temp);
                    sbf.append("\r\n");
                }
                result = sbf.toString();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != br) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != os) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            // 断开与远程地址url的连接
            connection.disconnect();
        }
        return result;
    }

    //这个函数负责把获取到的InputStream流保存到本地。
    public static boolean saveImageToDisk(String imgUrl, String fileName, String filePath) {
        InputStream inputStream = null;
        inputStream = getInputStream(imgUrl);//调用getInputStream()函数。
        byte[] data = new byte[1024];
        int len = 0;

        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(filePath + fileName);//初始化一个FileOutputStream对象。
            while ((len = inputStream.read(data))!=-1) {//循环读取inputStream流中的数据,存入文件流fileOutputStream
                fileOutputStream.write(data,0,len);
            }

        } catch (IOException e) {
            e.printStackTrace();
            return false;
        } finally{//finally函数,不管有没有异常发生,都要调用这个函数下的代码
            if(fileOutputStream!=null){
                try {
                    fileOutputStream.close();//记得及时关闭文件流
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(inputStream!=null){
                try {
                    inputStream.close();//关闭输入流
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


        return true;

    }


    public static InputStream getInputStream(String imgUrl){
        InputStream inputStream = null;
        HttpURLConnection httpURLConnection = null;
        try {
            URL url = new URL(imgUrl);//创建的URL
            httpURLConnection = (HttpURLConnection) url.openConnection();//打开链接
            httpURLConnection.setConnectTimeout(3000);//设置网络链接超时时间,3秒,链接失败后重新链接
            httpURLConnection.setDoInput(true);//打开输入流
            httpURLConnection.setRequestMethod("GET");//表示本次Http请求是GET方式
            int responseCode = httpURLConnection.getResponseCode();//获取返回码
            if (responseCode == 200) {//成功为200
                //从服务器获得一个输入流
                inputStream = httpURLConnection.getInputStream();
            }


        } catch (IOException e) {
            e.printStackTrace();
        }
        return inputStream;

    }
}
3、工具类转换 1、object转成map
package com.lingxu.module.picture.util;

import lombok.extern.slf4j.Slf4j;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * @date 2022/2/25
 * @versions 1.0
 */
@Slf4j
public class util {

    /**
     * 利用Introspector和PropertyDescriptor:属性描述器  将Bean --> Map
     * @param obj  实体类
     * @return
     */
    public static Map<String, Object> transBean2Map(Object obj) {
        if (obj == null) {
            return null;
        }
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            //利用java反射转为BeanInfo
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
            // PropertyDescriptor:属性描述器
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();
                // 过滤class属性
                if (!key.equals("class")) {
                    // 得到property对应的getter方法
                    Method getter = property.getReadMethod();
                    Object value = getter.invoke(obj);

                    map.put(key, value);
                }
            }
        } catch (Exception e) {
            log.error("transBeanMap Error {}" ,e);
        }
        return map;

    }
}
4、其他工具类 1、获取当前登录人的ip

参数获取

HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
package com.lingxu.base.common.util;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;

/**
 * IP地址
 * 
 * @Date 2019年01月14日
 */
public class IPUtils {
   private static Logger logger = LoggerFactory.getLogger(IPUtils.class);

   /**
    * 获取IP地址
    * 
    * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
    * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
    */
   public static String getIpAddr(HttpServletRequest request) {
       String ip = null;
        try {
            ip = request.getHeader("x-forwarded-for");
            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
        } catch (Exception e) {
           logger.error("IPUtils ERROR ", e);
        }
        
//        //使用代理,则获取第一个IP地址
//        if(StringUtils.isEmpty(ip) && ip.length() > 15) {
//       if(ip.indexOf(",") > 0) {
//          ip = ip.substring(0, ip.indexOf(","));
//       }
//    }
        
        return ip;
    }
   
}
2、sha1加解密
package com.lingxu.base.common.util;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

import sun.misc.BASE64Decoder;

public class AESEncryptUtil {


    /**
     * 对字符串进行sha1加密处理
     *
     * @param text
     * @return 加密后的字符串
     */
    public static final String sha1(String text) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-1");
            digest.update(text.getBytes());
            byte[] messageDigest = digest.digest();
            StringBuffer stringBuffer = new StringBuffer();
            for (int i = 0; i < messageDigest.length; i++) {
                String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    stringBuffer.append(0);
                }
                stringBuffer.append(shaHex);
            }

            return stringBuffer.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        return "";
    }

    /**
     * 获取字符串的md5值
     *
     * @param text
     * @return
     */
    private static String getMd5(String text) {
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] md5bytes = md5.digest(text.getBytes());
            return bytesToHex(md5bytes);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        return "";
    }

    /**
     * 二进制转十六进制
     *
     * @param bytes
     * @return
     */
    private static String bytesToHex(byte[] bytes) {
        StringBuffer md5str = new StringBuffer();
        // 把数组每一字节换成16进制连成md5字符串
        int digital;
        for (int i = 0; i < bytes.length; i++) {
            digital = bytes[i];

            if (digital < 0) {
                digital += 256;
            }
            if (digital < 16) {
                md5str.append("0");
            }
            md5str.append(Integer.toHexString(digital));
        }
        return md5str.toString();
    }

    /**
     * AES CBC PKCS#7填充解密
     *
     * @param appKey appKey
     * @param iv     填充向量
     * @param text   加密过的字符串
     * @return 解密后的字符串
     */
    private static String aesCBCDecrypt(String appKey, String iv, String text) {
        try {
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes("UTF-8"));
            SecretKeySpec secretKeySpec = new SecretKeySpec(appKey.getBytes("UTF-8"), "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
            //byte[] original = cipher.doFinal(Base64.getDecoder().decode(text));
            byte[] original = cipher.doFinal(new BASE64Decoder().decodeBuffer(text));
            return new String(original);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取11位时间戳
     *
     * @return
     */
    private static String getCurrentTimeStamp() {
        String timeStamp = System.currentTimeMillis() + "";
        return timeStamp.substring(0, 10);
    }

    /**
     * 对数组按数据字典进行排序
     *
     * @param arr 要排序的数据
     * @return 按字典排序后的字符串
     */
    private static String sort(String[] arr) {
        Arrays.sort(arr);
        StringBuilder builder = new StringBuilder();
        for (String s : arr) {
            builder.append(s);
        }
        return builder.toString();
    }

    /**
     * 解密单点登录传过来的加密串
     *
     * @param appkey    用来解密推送的数据,获取方式见api文档
     * @param token     创建应用时任意填写的,用来生成signature
     * @param signature 签名信息
     * @param timeStamp 11位时间戳
     * @param nonce     随机字符串
     * @param text      加密字符串
     * @return 解密后的字符串,可以拿到event和ticket用于后续 *** 作
     */
    public static String decrypt(String appkey, String token, String signature, String timeStamp, String nonce, String text) {
        timeStamp = timeStamp == null ? timeStamp = getCurrentTimeStamp() : timeStamp;
        String[] arr = {token, timeStamp, nonce, text};
        String sortedString = sort(arr);
        String sha1String = sha1(sortedString);
        if (!sha1String.equals(signature)) {
            // throw new SignatureErrorException("签名校验错误");
        }

        String iv = getMd5(appkey).substring(0, 16);
        String decryptedText = aesCBCDecrypt(appkey, iv, text);

        return decryptedText;
    }

}
2、汉字获取字母
package com.lingxu.base.common.util;

import java.io.UnsupportedEncodingException;

public class ChineseUtil {

    private final static int[] areaCode = {1601, 1637, 1833, 2078, 2274,
            2302, 2433, 2594, 2787, 3106, 3212, 3472, 3635, 3722, 3730, 3858,
            4027, 4086, 4390, 4558, 4684, 4925, 5249, 5590};
    private final static String[] letters = {"a", "b", "c", "d", "e",
            "f", "g", "h", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
            "t", "w", "x", "y", "z"};

    /**
     * 取得给定汉字的首字母,即声母
     *
     * @param chinese 给定的汉字
     * @return 给定汉字的声母
     */
    public static String getFirstLetter(String chinese) {
        if (chinese == null || chinese.trim().length() == 0) {
            return "";
        }
        chinese = conversionStr(chinese, "GB2312", "ISO8859-1");

        if (chinese.length() > 1) // 判断是不是汉字
        {
            int li_SectorCode = (int) chinese.charAt(0); // 汉字区码
            int li_PositionCode = (int) chinese.charAt(1); // 汉字位码
            li_SectorCode = li_SectorCode - 160;
            li_PositionCode = li_PositionCode - 160;
            int li_SecPosCode = li_SectorCode * 100 + li_PositionCode; // 汉字区位码
            if (li_SecPosCode > 1600 && li_SecPosCode < 5590) {
                for (int i = 0; i < 23; i++) {
                    if (li_SecPosCode >= areaCode[i]
                            && li_SecPosCode < areaCode[i + 1]) {
                        chinese = letters[i];
                        break;
                    }
                }
            } else // 非汉字字符,如图形符号或ASCII码
            {
                chinese = conversionStr(chinese, "ISO8859-1", "GB2312");
                chinese = chinese.substring(0, 1);
            }
        }

        return chinese;
    }

    /**
     * 字符串编码转换
     *
     * @param str           要转换编码的字符串
     * @param charsetName   原来的编码
     * @param toCharsetName 转换后的编码
     * @return 经过编码转换后的字符串
     */
    private static String conversionStr(String str, String charsetName, String toCharsetName) {
        try {
            str = new String(str.getBytes(charsetName), toCharsetName);
        } catch (UnsupportedEncodingException ex) {
            System.out.println("字符串编码转换异常:" + ex.getMessage());
        }
        return str;
    }
}
3、密码加盐,加解密方法
package com.lingxu.base.common.util;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import java.security.Key;
import java.security.SecureRandom;

public class PasswordUtil {

   /**
    * JAVA6支持以下任意一种算法 PBEWITHMD5ANDDES PBEWITHMD5ANDTRIPLEDES
    * PBEWITHSHAANDDESEDE PBEWITHSHA1ANDRC2_40 PBKDF2WITHHMACSHA1
    * */

   /**
    * 定义使用的算法为:PBEWITHMD5andDES算法
    */
   public static final String ALGORITHM = "PBEWithMD5AndDES";//加密算法
   public static final String Salt = "63293188";//密钥

   /**
    * 定义迭代次数为1000次
    */
   private static final int ITERATIONCOUNT = 1000;

   /**
    * 获取加密算法中使用的盐值,解密中使用的盐值必须与加密中使用的相同才能完成 *** 作. 盐长度必须为8字节
    * 
    * @return byte[] 盐值
    * */
   public static byte[] getSalt() throws Exception {
      // 实例化安全随机数
      SecureRandom random = new SecureRandom();
      // 产出盐
      return random.generateSeed(8);
   }

   public static byte[] getStaticSalt() {
      // 产出盐
      return Salt.getBytes();
   }

   /**
    * 根据PBE密码生成一把密钥
    * 
    * @param password
    *            生成密钥时所使用的密码
    * @return Key PBE算法密钥
    * */
   private static Key getPBEKey(String password) {
      // 实例化使用的算法
      SecretKeyFactory keyFactory;
      SecretKey secretKey = null;
      try {
         keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
         // 设置PBE密钥参数
         PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
         // 生成密钥
         secretKey = keyFactory.generateSecret(keySpec);
      } catch (Exception e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }

      return secretKey;
   }

   /**
    * 加密明文字符串
    * 
    * @param plaintext
    *            待加密的明文字符串
    * @param password
    *            生成密钥时所使用的密码
    * @param salt
    *            盐值
    * @return 加密后的密文字符串
    * @throws Exception
    */
   public static String encrypt(String plaintext, String password, String salt) {

      Key key = getPBEKey(password);
      byte[] encipheredData = null;
      PBEParameterSpec parameterSpec = new PBEParameterSpec(salt.getBytes(), ITERATIONCOUNT);
      try {
         Cipher cipher = Cipher.getInstance(ALGORITHM);

         cipher.init(Cipher.ENCRYPT_MODE, key, parameterSpec);
         //update-begin-author:sccott date:20180815 for:中文作为用户名时,加密的密码windows和linux会得到不同的结果 gitee/issues/IZUD7
         encipheredData = cipher.doFinal(plaintext.getBytes("utf-8"));
         //update-end-author:sccott date:20180815 for:中文作为用户名时,加密的密码windows和linux会得到不同的结果 gitee/issues/IZUD7
      } catch (Exception e) {
      }
      return bytesToHexString(encipheredData);
   }

   /**
    * 解密密文字符串
    * 
    * @param ciphertext
    *            待解密的密文字符串
    * @param password
    *            生成密钥时所使用的密码(如需解密,该参数需要与加密时使用的一致)
    * @param salt
    *            盐值(如需解密,该参数需要与加密时使用的一致)
    * @return 解密后的明文字符串
    * @throws Exception
    */
   public static String decrypt(String ciphertext, String password, String salt) {

      Key key = getPBEKey(password);
      byte[] passDec = null;
      PBEParameterSpec parameterSpec = new PBEParameterSpec(salt.getBytes(), ITERATIONCOUNT);
      try {
         Cipher cipher = Cipher.getInstance(ALGORITHM);

         cipher.init(Cipher.DECRYPT_MODE, key, parameterSpec);

         passDec = cipher.doFinal(hexStringToBytes(ciphertext));
      }

      catch (Exception e) {
         // TODO: handle exception
      }
      return new String(passDec);
   }

   /**
    * 将字节数组转换为十六进制字符串
    * 
    * @param src
    *            字节数组
    * @return
    */
   public static String bytesToHexString(byte[] src) {
      StringBuilder stringBuilder = new StringBuilder("");
      if (src == null || src.length <= 0) {
         return null;
      }
      for (int i = 0; i < src.length; i++) {
         int v = src[i] & 0xFF;
         String hv = Integer.toHexString(v);
         if (hv.length() < 2) {
            stringBuilder.append(0);
         }
         stringBuilder.append(hv);
      }
      return stringBuilder.toString();
   }

   /**
    * 将十六进制字符串转换为字节数组
    * 
    * @param hexString
    *            十六进制字符串
    * @return
    */
   public static byte[] hexStringToBytes(String hexString) {
      if (hexString == null || hexString.equals("")) {
         return null;
      }
      hexString = hexString.toUpperCase();
      int length = hexString.length() / 2;
      char[] hexChars = hexString.toCharArray();
      byte[] d = new byte[length];
      for (int i = 0; i < length; i++) {
         int pos = i * 2;
         d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
      }
      return d;
   }

   private static byte charToByte(char c) {
      return (byte) "0123456789ABCDEF".indexOf(c);
   }


}
4、redis 工具类
package com.lingxu.base.common.util;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * redis 工具类
 *
 * @Author Scott
 */
@Component
public class RedisUtil {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 指定缓存失效时间
     *
     * @param key  键
     * @param time 时间(秒)
     * @return
     */
    public boolean expire(String key, long time) {
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据key 获取过期时间
     *
     * @param key 键 不能为null
     * @return 时间(秒) 返回0代表为永久有效
     */
    public long getExpire(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }

    /**
     * 判断key是否存在
     *
     * @param key 键
     * @return true 存在 false不存在
     */
    public boolean hasKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除缓存
     *
     * @param key 可以传一个值 或多个
     */
    @SuppressWarnings("unchecked")
    public void del(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
            } else {
                redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
            }
        }
    }

    // ============================String=============================

    /**
     * 普通缓存获取
     *
     * @param key 键
     * @return 值
     */
    public Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }

    /**
     * 普通缓存放入
     *
     * @param key   键
     * @param value 值
     * @return true成功 false失败
     */
    public boolean set(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

    }

    /**
     * 普通缓存放入并设置时间
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期
     * @return true成功 false 失败
     */
    public boolean set(String key, Object value, long time) {
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 普通缓存放入并设置时间 戳
     *
     * @param key   键
     * @param value 值
     * @param days  时间(天) time要大于0 如果time小于等于0 将设置无限期
     * @return true成功 false 失败
     */
    public boolean setDay(String key, Object value, int days) {
        try {
            if (days > 0) {
                redisTemplate.opsForValue().set(key, value, days, TimeUnit.DAYS);
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 递增
     *
     * @param key   键
     * @param delta 要增加几(大于0)
     * @return
     */
    public long incr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递增因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }

    /**
     * 递减
     *
     * @param key   键
     * @param delta 要减少几(小于0)
     * @return
     */
    public long decr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递减因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, -delta);
    }

    // ================================Map=================================

    /**
     * HashGet
     *
     * @param key  键 不能为null
     * @param item 项 不能为null
     * @return 值
     */
    public Object hget(String key, String item) {
        return redisTemplate.opsForHash().get(key, item);
    }

    /**
     * 获取hashKey对应的所有键值
     *
     * @param key 键
     * @return 对应的多个键值
     */
    public Map<Object, Object> hmget(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * HashSet
     *
     * @param key 键
     * @param map 对应多个键值
     * @return true 成功 false 失败
     */
    public boolean hmset(String key, Map<String, Object> map) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * HashSet 并设置时间
     *
     * @param key  键
     * @param map  对应多个键值
     * @param time 时间(秒)
     * @return true成功 false失败
     */
    public boolean hmset(String key, Map<String, Object> map, long time) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 向一张hash表中放入数据,如果不存在将创建
     *
     * @param key   键
     * @param item  项
     * @param value 值
     * @return true 成功 false失败
     */
    public boolean hset(String key, String item, Object value) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 向一张hash表中放入数据,如果不存在将创建
     *
     * @param key   键
     * @param item  项
     * @param value 值
     * @param time  时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
     * @return true 成功 false失败
     */
    public boolean hset(String key, String item, Object value, long time) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除hash表中的值
     *
     * @param key  键 不能为null
     * @param item 项 可以使多个 不能为null
     */
    public void hdel(String key, Object... item) {
        redisTemplate.opsForHash().delete(key, item);
    }

    /**
     * 判断hash表中是否有该项的值
     *
     * @param key  键 不能为null
     * @param item 项 不能为null
     * @return true 存在 false不存在
     */
    public boolean hHasKey(String key, String item) {
        return redisTemplate.opsForHash().hasKey(key, item);
    }

    /**
     * hash递增 如果不存在,就会创建一个 并把新增后的值返回
     *
     * @param key  键
     * @param item 项
     * @param by   要增加几(大于0)
     * @return
     */
    public double hincr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, by);
    }

    /**
     * hash递减
     *
     * @param key  键
     * @param item 项
     * @param by   要减少记(小于0)
     * @return
     */
    public double hdecr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, -by);
    }

    // ============================set=============================

    /**
     * 根据key获取Set中的所有值
     *
     * @param key 键
     * @return
     */
    public Set<Object> sGet(String key) {
        try {
            return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据value从一个set中查询,是否存在
     *
     * @param key   键
     * @param value 值
     * @return true 存在 false不存在
     */
    public boolean sHasKey(String key, Object value) {
        try {
            return redisTemplate.opsForSet().isMember(key, value);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将数据放入set缓存
     *
     * @param key    键
     * @param values 值 可以是多个
     * @return 成功个数
     */
    public long sSet(String key, Object... values) {
        try {
            return redisTemplate.opsForSet().add(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 将set数据放入缓存
     *
     * @param key    键
     * @param time   时间(秒)
     * @param values 值 可以是多个
     * @return 成功个数
     */
    public long sSetAndTime(String key, long time, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().add(key, values);
            if (time > 0) {
                expire(key, time);
            }
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 获取set缓存的长度
     *
     * @param key 键
     * @return
     */
    public long sGetSetSize(String key) {
        try {
            return redisTemplate.opsForSet().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 移除值为value的
     *
     * @param key    键
     * @param values 值 可以是多个
     * @return 移除的个数
     */
    public long setRemove(String key, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().remove(key, values);
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    // ===============================list=================================

    /**
     * 获取list缓存的内容
     *
     * @param key   键
     * @param start 开始
     * @param end   结束 0 到 -1代表所有值
     * @return
     */
    public List<Object> lGet(String key, long start, long end) {
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 插入list 插入到最后一个位置
     * @param key 键
     * @param value 值
     * @return 插入数量
     */
    public Long rPush(String key, Object value){
        try {
            return redisTemplate.opsForList().rightPush(key,value);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取list缓存的长度
     *
     * @param key 键
     * @return
     */
    public long lGetListSize(String key) {
        try {
            return redisTemplate.opsForList().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 通过索引 获取list中的值
     *
     * @param key   键
     * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
     * @return
     */
    public Object lGetIndex(String key, long index) {
        try {
            return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @return
     */
    public boolean lSet(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒)
     * @return
     */
    public boolean lSet(String key, Object value, long time) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @return
     */
    public boolean lSet(String key, List<Object> value) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒)
     * @return
     */
    public boolean lSet(String key, List<Object> value, long time) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据索引修改list中的某条数据
     *
     * @param key   键
     * @param index 索引
     * @param value 值
     * @return
     */
    public boolean lUpdateIndex(String key, long index, Object value) {
        try {
            redisTemplate.opsForList().set(key, index, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 移除N个值为value
     *
     * @param key   键
     * @param count 移除多少个
     * @param value 值
     * @return 移除的个数
     */
    public long lRemove(String key, long count, Object value) {
        try {
            Long remove = redisTemplate.opsForList().remove(key, count, value);
            return remove;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }


}
5、数据库连接加解密SM2
package com.lingxu.base.common.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.PropertiesUtil;
import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
import org.bouncycastle.crypto.params.*;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.encoders.Hex;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.Properties;

/**
 * @Date: 2021/1/12 15:53
 * @Describe: SM2用于数据库链接解密的工具类
 */
@Slf4j
public class SM2DbConnUtil {

    private static String dbConnPrivateKey;
    private static String dbConnPublicKey;
    private static Properties prop = new Properties();
    private static SM2Engine sm2EncryptEngine;
    private static SM2Engine sm2DecryptEngine;



    static{
        // 初始化时加载
        readProperties("key.properties");
        dbConnPrivateKey=prop.getProperty("dbConnPrivateKey");
        dbConnPublicKey=prop.getProperty("dbConnPublicKey");

        // 获取一条SM2曲线参数
        X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
        // 构造domain参数
        ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(),
                sm2ECParameters.getG(), sm2ECParameters.getN());
        //提取公钥点
        ECPoint pukPoint = sm2ECParameters.getCurve().decodePoint(hexString2byte(dbConnPublicKey));
        // 公钥前面的02或者03表示是压缩公钥,04表示未压缩公钥, 04的时候,可以去掉前面的04
        ECPublicKeyParameters publicKeyParameters = new ECPublicKeyParameters(pukPoint, domainParameters);
        sm2EncryptEngine = new SM2Engine();
        sm2EncryptEngine.init(true, new ParametersWithRandom(publicKeyParameters, new SecureRandom()));

        BigInteger privateKeyD = new BigInteger(dbConnPrivateKey, 16);
        ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(privateKeyD, domainParameters);

        sm2DecryptEngine = new SM2Engine();
        sm2DecryptEngine.init(false, privateKeyParameters);
    }

    public static void main(String args[]){
        String msg="测试加解密";
        String msg1=encrypt("测试加解密");
        System.out.println(msg1);
        String msg2=decrypt(msg1);
        System.out.println(msg2);
    }

    public static void createKeyPair() throws NoSuchAlgorithmException {
        生成密钥对
        X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
        ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());
        ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();
        keyPairGenerator.init(new ECKeyGenerationParameters(domainParameters, SecureRandom.getInstance("SHA1PRNG")));
        AsymmetricCipherKeyPair asymmetricCipherKeyPair = keyPairGenerator.generateKeyPair();

        //私钥,16进制格式,自己保存
        BigInteger privatekey = ((ECPrivateKeyParameters) asymmetricCipherKeyPair.getPrivate()).getD();
        String privateKeyHex = privatekey.toString(16);
        System.out.println("privateKeyHex: "+privateKeyHex);
        //公钥,16进制格式,发给前端
        ECPoint ecPoint = ((ECPublicKeyParameters) asymmetricCipherKeyPair.getPublic()).getQ();
        String publicKeyHex = Hex.toHexString(ecPoint.getEncoded(false));
        System.out.println("publicKeyHex: "+publicKeyHex);
    }

    /**
     * 读取配置文件
     * @param fileName
     */
    public static void readProperties(String fileName){
        try {
            InputStream in = PropertiesUtil.class.getResourceAsStream("/"+fileName);
            BufferedReader bf = new BufferedReader(new InputStreamReader(in));
            prop.load(bf);
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    /**
     * SM2加密算法
     * @param data          数据
     * @return
     */
    public static String encrypt(String data){

        byte[] arrayOfBytes = null;
        try {
            byte[] in = data.getBytes("utf-8");
            byte[] in2 = Base64.getEncoder().encode(in);
            arrayOfBytes = sm2EncryptEngine.processBlock(in2, 0, in2.length);
        } catch (Exception e) {
            log.error("SM2加密时出现异常:", e);
        }
        return Hex.toHexString(arrayOfBytes);
    }

    /**
     * SM2解密算法
     * @param cipherData    密文数据
     * @return
     */
    public static String decrypt(String cipherData) {
        byte[] cipherDataByte = Hex.decode(cipherData);
        String result = null;
        try {
            byte[] arrayOfBytes = Base64.getDecoder().decode(sm2DecryptEngine.processBlock(cipherDataByte, 0, cipherDataByte.length));
            return new String(arrayOfBytes, "utf-8");
        } catch (Exception e) {
            log.error("SM2解密时出现异常:", e);
        }
        return result;
    }

    /**
     * @param hexString 16进制字符串    如:"33d20046" 转换为 0x33 0xD2 0x00 0x46
     * @return
     * @Title: hexString2byte
     * @Description: 16进制字符串转字节数组
     * @since: 0.0.1
     */
    public static byte[] hexString2byte(String hexString) {
        if (null == hexString || hexString.length() % 2 != 0 || hexString.contains("null")) {
            return null;
        }
        byte[] bytes = new byte[hexString.length() / 2];
        for (int i = 0; i < hexString.length(); i += 2) {
            bytes[i / 2] = (byte) (Integer.parseInt(hexString.substring(i, i + 2), 16) & 0xff);
        }
        return bytes;
    }
}
6、访问参数加解密SM2
package com.lingxu.base.common.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.PropertiesUtil;
import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
import org.bouncycastle.crypto.params.*;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.encoders.Hex;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.Properties;

/**
 * @Author: BaiDH
 * @Date: 2021/1/12 15:53
 * @Describe: SM2用于请求参数加解密的工具类
 */
@Slf4j
@Component
public class SM2RequestUtil {

    // 参照 https://www.cnblogs.com/alsodzy/p/9854521.html
    private static String servicePrivateKey;
    private static String servicePublicKey;
    private static Properties prop = new Properties();
    private static SM2Engine sm2EncryptEngine;
    private static SM2Engine sm2DecryptEngine;



    static{
        // 初始化时加载
        readProperties("key.properties");
        servicePrivateKey=prop.getProperty("servicePrivateKey");
        servicePublicKey=prop.getProperty("servicePublicKey");

        // 获取一条SM2曲线参数
        X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
        // 构造domain参数
        ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(),
                sm2ECParameters.getG(), sm2ECParameters.getN());
        //提取公钥点
        ECPoint pukPoint = sm2ECParameters.getCurve().decodePoint(hexString2byte(servicePublicKey));
        // 公钥前面的02或者03表示是压缩公钥,04表示未压缩公钥, 04的时候,可以去掉前面的04
        ECPublicKeyParameters publicKeyParameters = new ECPublicKeyParameters(pukPoint, domainParameters);
        sm2EncryptEngine = new SM2Engine();
        sm2EncryptEngine.init(true, new ParametersWithRandom(publicKeyParameters, new SecureRandom()));

        BigInteger privateKeyD = new BigInteger(servicePrivateKey, 16);
        ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(privateKeyD, domainParameters);

        sm2DecryptEngine = new SM2Engine();
        sm2DecryptEngine.init(false, privateKeyParameters);
    }

    public static void main(String args[]){
        String msg="测试加解密";
        String msg1=encrypt("测试加解密");
        System.out.println(msg1);
        String msg2=decrypt(msg1);
        System.out.println(msg2);
    }

    public static void createKeyPair() throws NoSuchAlgorithmException {
        生成密钥对
        X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
        ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());
        ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();
        keyPairGenerator.init(new ECKeyGenerationParameters(domainParameters, SecureRandom.getInstance("SHA1PRNG")));
        AsymmetricCipherKeyPair asymmetricCipherKeyPair = keyPairGenerator.generateKeyPair();

        //私钥,16进制格式,自己保存
        BigInteger privatekey = ((ECPrivateKeyParameters) asymmetricCipherKeyPair.getPrivate()).getD();
        String privateKeyHex = privatekey.toString(16);
        System.out.println("privateKeyHex: "+privateKeyHex);
        //公钥,16进制格式,发给前端
        ECPoint ecPoint = ((ECPublicKeyParameters) asymmetricCipherKeyPair.getPublic()).getQ();
        String publicKeyHex = Hex.toHexString(ecPoint.getEncoded(false));
        System.out.println("publicKeyHex: "+publicKeyHex);
    }

    /**
     * 读取配置文件
     * @param fileName
     */
    public static void readProperties(String fileName){
        try {
            InputStream in = PropertiesUtil.class.getResourceAsStream("/"+fileName);
            BufferedReader bf = new BufferedReader(new InputStreamReader(in));
            prop.load(bf);
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    /**
     * SM2加密算法
     * @param data          数据
     * @return
     */
    public static String encrypt(String data){

        byte[] arrayOfBytes = null;
        try {
            byte[] in = data.getBytes("utf-8");
            byte[] in2 = Base64.getEncoder().encode(in);
            arrayOfBytes = sm2EncryptEngine.processBlock(in2, 0, in2.length);
        } catch (Exception e) {
            log.error("SM2加密时出现异常:", e);
        }
        return Hex.toHexString(arrayOfBytes);
    }

    /**
     * SM2解密算法
     * @param cipherData    密文数据
     * @return
     */
    public static String decrypt(String cipherData) {
        byte[] cipherDataByte = Hex.decode(cipherData);
        String result = null;
        try {
            byte[] arrayOfBytes = Base64.getDecoder().decode(sm2DecryptEngine.processBlock(cipherDataByte, 0, cipherDataByte.length));
            return new String(arrayOfBytes, "utf-8");
        } catch (Exception e) {
            log.error("SM2解密时出现异常:", e);
        }
        return result;
    }

    /**
     * @param hexString 16进制字符串    如:"33d20046" 转换为 0x33 0xD2 0x00 0x46
     * @return
     * @Title: hexString2byte
     * @Description: 16进制字符串转字节数组
     * @since: 0.0.1
     */
    public static byte[] hexString2byte(String hexString) {
        if (null == hexString || hexString.length() % 2 != 0 || hexString.contains("null")) {
            return null;
        }
        byte[] bytes = new byte[hexString.length() / 2];
        for (int i = 0; i < hexString.length(); i += 2) {
            bytes[i / 2] = (byte) (Integer.parseInt(hexString.substring(i, i + 2), 16) & 0xff);
        }
        return bytes;
    }
}
7、spring 上下文对象实例
package com.lingxu.base.common.util;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Component
public class SpringContextUtils implements ApplicationContextAware {

   /**
    * 上下文对象实例
    */
   private static ApplicationContext applicationContext;

   @Override
   public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
      SpringContextUtils.applicationContext = applicationContext;
   }

   /**
    * 获取applicationContext
    *
    * @return
    */
   public static ApplicationContext getApplicationContext() {
      return applicationContext;
   }

   /**
     * 获取HttpServletRequest
    */
   public static HttpServletRequest getHttpServletRequest() {
      return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
   }

   public static String getDomain(){
      HttpServletRequest request = getHttpServletRequest();
      StringBuffer url = request.getRequestURL();
      return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();
   }

   public static String getOrigin(){
      HttpServletRequest request = getHttpServletRequest();
      return request.getHeader("Origin");
   }
   
   /**
    * 通过name获取 Bean.
    *
    * @param name
    * @return
    */
   public static Object getBean(String name) {
      return getApplicationContext().getBean(name);
   }

   /**
    * 通过class获取Bean.
    *
    * @param clazz
    * @param       
    * @return
    */
   public static <T> T getBean(Class<T> clazz) {
      return getApplicationContext().getBean(clazz);
   }

   /**
    * 通过name,以及Clazz返回指定的Bean
    *
    * @param name
    * @param clazz
    * @param       
    * @return
    */
   public static <T> T getBean(String name, Class<T> clazz) {
      return getApplicationContext().getBean(name, clazz);
   }
}

陆续更新中…

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/736369.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-28
下一篇 2022-04-28

发表评论

登录后才能评论

评论列表(0条)

保存