Tools
程序员文章站
2022-06-24 17:06:13
...
Base64转MultipartFile
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;
import java.io.*;
/**
* Create on 2021/9/16.
*
* @author Jaime
* @Description:
*/
public class BASE64DecodedMultipartFile implements MultipartFile {
private final byte[] imgContent;
private final String header;
public BASE64DecodedMultipartFile(byte[] imgContent, String header) {
this.imgContent = imgContent;
this.header = header.split(";")[0];
}
@Override
public String getName() {
return System.currentTimeMillis() + Math.random() + "." + header.split("/")[1];
}
@Override
public String getOriginalFilename() {
return System.currentTimeMillis() + (int) Math.random() * 10000 + "." + header.split("/")[1];
}
@Override
public String getContentType() {
return header.split(":")[1];
}
@Override
public boolean isEmpty() {
return imgContent == null || imgContent.length == 0;
}
@Override
public long getSize() {
return imgContent.length;
}
@Override
public byte[] getBytes() throws IOException {
return imgContent;
}
@Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(imgContent);
}
@Override
public void transferTo(File dest) throws IOException, IllegalStateException {
new FileOutputStream(dest).write(imgContent);
}
public static MultipartFile base64ToMultipart(String base64) {
try {
String[] baseStrs = base64.split(",");
BASE64Decoder decoder = new BASE64Decoder();
byte[] b = new byte[0];
b = decoder.decodeBuffer(baseStrs[1]);
for (int i = 0; i < b.length; ++i) {
if (b[i] < 0) {
b[i] += 256;
}
}
return new BASE64DecodedMultipartFile(b, baseStrs[0]);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
MultipartFile文件上传
public static final String[] DEFAULT_ALLOWED_EXTENSION = {
// 图片
"bmp", "gif", "jpg", "jpeg", "png",
// word excel powerpoint
"doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt",
// 压缩文件
"rar", "zip", "gz", "bz2",
// pdf
"pdf" };
/**
* 文件上传
*
* @param baseDir 相对应用的基目录
* @param file 上传的文件
* @param extension 上传文件类型
* @return 返回上传成功的文件名
* @throws FileSizeLimitExceededException 如果超出最大大小
* @throws FileNameLengthLimitExceededException 文件名太长
* @throws IOException 比如读写文件出错时
* @throws InvalidExtensionException 文件校验异常
*/
public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension)
throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
InvalidExtensionException
{
int fileNamelength = file.getOriginalFilename().length();
if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH)
{
throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
}
String fileName = file.getOriginalFilename();
File desc = getAbsoluteFile(baseDir, fileName);
file.transferTo(desc);
String pathFileName = getPathFileName(baseDir, fileName);
return pathFileName;
}
private static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException
{
File desc = new File(uploadDir + File.separator + fileName);
if (!desc.getParentFile().exists())
{
desc.getParentFile().mkdirs();
}
if (!desc.exists())
{
desc.createNewFile();
}
return desc;
}
private static final String getPathFileName(String uploadDir, String fileName) throws IOException
{
int dirLastIndex = RuoYiConfig.getProfile().length() + 1;
String currentDir = StringUtils.substring(uploadDir, dirLastIndex);
String pathFileName = Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + fileName;
return pathFileName;
}
微信扫码登录
//微信获取用户信息
@CrossOrigin
@RequestMapping(value = "WeiXinCode")
public AjaxResult WeiXinCode() {
PageData pd;
try {
pd = this.getPageData();
JSONObject json=GetReqUtil.getWxOpenId(pd.getString("code"));
if(json.get("errcode")!=null) return AjaxResult.error(405,"调取微信登录失败");
String avatar = GetReqUtil.getHeadUrl(json.getString("access_token"), json.getString("openid"));
String openId = json.getString("openid");
openId = AESUtils.parseStr2Hex(openId, Common.MYSQL_ENCRYPT_KEY);
pd= loginService.loginByWeixing(openId);
AjaxResult ajax = AjaxResult.success();
if(StringUtils.isEmpty(pd)||StringUtils.isEmpty(pd.get("token"))){
ajax.put(Constants.JWT_AVATAR, avatar);
ajax.put(Constants.OPENID, openId);
}else{
ajax.putAll(pd);
}
//获取到用户的基本信息
return ajax;
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error(405,"调取微信登录失败");
}
}
public static JSONObject getWxOpenId(String code) {
String url = "https://sz.api.weixin.qq.com/sns/oauth2/access_token";
Map<String,Object> paramMap = new HashMap<>();
paramMap.put("appid", WeiXinUtil.appid);
paramMap.put("secret", AESUtils.parseHex2Str(WeiXinUtil.appSecret, Common.MYSQL_ENCRYPT_KEY));
paramMap.put("code", code);
paramMap.put("grant_type", "authorization_code");
String result2 = HttpRequest.get(url).charset(CharsetUtil.CHARSET_GBK)
.header(Header.USER_AGENT, "Hutool http")//头信息,多个头信息多次调用此方法即可
.form(paramMap)//表单内容
.timeout(20000)//超时,毫秒
.execute().body();
JSONObject jsonObject = JSONObject.parseObject(result2); //字符串转Map
return jsonObject;
}
public static String getHeadUrl(String access_token,String openid) {
String url = "https://sz.api.weixin.qq.com/sns/userinfo";
Map<String,Object> paramMap = new HashMap<>();
paramMap.put("access_token", access_token);
paramMap.put("openid", openid);
String result2 = HttpRequest.get(url).charset(CharsetUtil.CHARSET_GBK)
.header(Header.USER_AGENT, "Hutool http")//头信息,多个头信息多次调用此方法即可
.form(paramMap)//表单内容
.timeout(20000)//超时,毫秒
.execute().body();
JSONObject jsonObject = JSONObject.parseObject(result2); //字符串转Map
if(jsonObject.get("errcode")!=null){
return "errcode";
}else {
return jsonObject.get("headimgurl").toString();
}
}
public PageData loginByWeixing(String openID) {
PageData pd =new PageData();
SysUser user = userMapper.findUserByopenId(openID);
if(user == null) return null;
//部分老用户没有默认头像, 添加默认头像
if (StringUtils.isEmpty(user.getAvatar())) {
user.setAvatar("/profile/avatar/20210925141027_44.jpg");
userMapper.updateUser(user);
}
if (user.getAvatar().startsWith("/profile")) {
user.setAvatar(uploadpath + user.getAvatar());
}
if (StringUtils.isEmpty(user.getDept())) {
user.setDept(new SysDept());
}
LoginUser loginUser = new LoginUser(user, permissionService.getMenuPermission(user));
AsyncManager.me().execute(AsyncFactory.recordLogininfor(user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
pd.put("token",tokenService.createToken(loginUser));
pd.put("user",changeUserTopd(user));
return pd;
}
//微信扫码后, 使用手机号进行绑定
SysUser user = userMapper.selectUserByPhonenumber(phone);
if(user == null) return null;
if (StringUtils.isEmpty(user.getAvatar())) {
user.setAvatar("/profile/avatar/20210925141027_44.jpg");
}
if(StringUtils.isNotEmpty(openID)) {
user.setOpenID(openID);
user.setPassword(SecurityUtils.encryptPassword(password));
userMapper.updateUser(user);
}
if (user.getAvatar().startsWith("/profile")) {
user.setAvatar(uploadpath + user.getAvatar());
}
LoginUser loginUser = new LoginUser(user, permissionService.getMenuPermission(user));
AsyncManager.me().execute(AsyncFactory.recordLogininfor(user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
// 生成token、
AjaxResult ajax = AjaxResult.success();
ajax.put(Constants.TOKEN,tokenService.createToken(loginUser));
ajax.put("user",changeUserTopd(user));
微信解码encryptedData
String decrypt = WeiXinUtil.decrypt(WeiXinUtil.appid2, data.getString("encryptedData"),
json.getString("session_key"), data.getString("iv"));
JSONObject jsonObject = JSONObject.parseObject(decrypt);
/**
* 解密数据
*/
package org.apache.commons.codec.binary;
public static String decrypt(String appId, String encryptedData, String sessionKey, String iv){
String result = "";
try {
AES aes = new AES();
byte[] resultByte = aes.decrypt(Base64.decodeBase64(encryptedData), Base64.decodeBase64(sessionKey), Base64.decodeBase64(iv));
if(null != resultByte && resultByte.length > 0){
result = new String(WxPKCS7Encoder.decode(resultByte));
JSONObject jsonObject = JSONObject.parseObject(result);
String decryptAppid = jsonObject.getJSONObject(WATERMARK).getString(APPID);
if(!appId.equals(decryptAppid)){
result = "";
}
}
} catch (Exception e) {
result = "";
e.printStackTrace();
}
return result;
}
package com.ruoyi.common.utils.weixin;
import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
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 org.bouncycastle.jce.provider.BouncyCastleProvider;
/**
* AES加密
* @author liuyazhuang
*
*/
public class AES {
public static boolean initialized = false;
/**
* AES解密
*
* @param content
* 密文
* @return
* @throws InvalidAlgorithmParameterException
* @throws NoSuchProviderException
*/
public byte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte) throws InvalidAlgorithmParameterException {
initialize();
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
Key sKeySpec = new SecretKeySpec(keyByte, "AES");
cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivByte));// 初始化
byte[] result = cipher.doFinal(content);
return result;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public static void initialize() {
if (initialized)
return;
Security.addProvider(new BouncyCastleProvider());
initialized = true;
}
// 生成iv
public static AlgorithmParameters generateIV(byte[] iv) throws Exception {
AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
params.init(new IvParameterSpec(iv));
return params;
}
}
package com.ruoyi.common.utils.weixin;
import java.nio.charset.Charset;
import java.util.Arrays;
/**
* 微信小程序加解密
* @author liuyazhuang
*
*/
public class WxPKCS7Encoder {
private static final Charset CHARSET = Charset.forName("utf-8");
private static final int BLOCK_SIZE = 32;
/**
* 获得对明文进行补位填充的字节.
*
* @param count
* 需要进行填充补位操作的明文字节个数
* @return 补齐用的字节数组
*/
public static byte[] encode(int count) {
// 计算需要填充的位数
int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);
if (amountToPad == 0) {
amountToPad = BLOCK_SIZE;
}
// 获得补位所用的字符
char padChr = chr(amountToPad);
String tmp = new String();
for (int index = 0; index < amountToPad; index++) {
tmp += padChr;
}
return tmp.getBytes(CHARSET);
}
/**
* 删除解密后明文的补位字符
*
* @param decrypted
* 解密后的明文
* @return 删除补位字符后的明文
*/
public static byte[] decode(byte[] decrypted) {
int pad = decrypted[decrypted.length - 1];
if (pad < 1 || pad > 32) {
pad = 0;
}
return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
}
/**
* 将数字转化成ASCII码对应的字符,用于对明文进行补码
*
* @param a
* 需要转化的数字
* @return 转化得到的字符
*/
public static char chr(int a) {
byte target = (byte) (a & 0xFF);
return (char) target;
}
}
AESUtil
package com.ruoyi.common.utils;
import com.ruoyi.common.core.lang.UUID;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class AESUtils {
/**
* AES加密字符串
*
* @param content
* 需要被加密的字符串
* @param password
* 加密需要的密码
* @return 密文
*/
public static byte[] encrypt(String content, String password) {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");// 创建AES的Key生产者
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(password.getBytes());
//kgen.init(128, new SecureRandom(password.getBytes()));// 利用用户密码作为随机数初始化出
// 128位的key生产者
kgen.init(128, secureRandom);
//加密没关系,SecureRandom是生成安全随机数序列,password.getBytes()是种子,只要种子相同,序列就一样,所以解密只要有password就行
SecretKey secretKey = kgen.generateKey();// 根据用户密码,生成一个**
byte[] enCodeFormat = secretKey.getEncoded();// 返回基本编码格式的**,如果此**不支持编码,则返回
// null。
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");// 转换为AES专用**
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
byte[] byteContent = content.getBytes("utf-8");
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化为加密模式的密码器
byte[] result = cipher.doFinal(byteContent);// 加密
return result;
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return null;
}
/**
* 解密AES加密过的字符串
*
* @param content
* AES加密过过的内容
* @param password
* 加密时的密码
* @return 明文
*/
public static String decrypt(byte[] content, String password) {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");// 创建AES的Key生产者
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(password.getBytes());
//kgen.init(128, new SecureRandom(password.getBytes()));
kgen.init(128, secureRandom);
SecretKey secretKey = kgen.generateKey();// 根据用户密码,生成一个**
byte[] enCodeFormat = secretKey.getEncoded();// 返回基本编码格式的**
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");// 转换为AES专用**
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
cipher.init(Cipher.DECRYPT_MODE, key);// 初始化为解密模式的密码器
byte[] result = cipher.doFinal(content);
// return result; // 明文
return new String(result);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return null;
}
/**将二进制转换成16进制
* @param buf
* @return
*/
public static String parseByte2HexStr(byte buf[]) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < buf.length; i++) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
/**将16进制转换为二进制
* @param hexStr
* @return
*/
public static byte[] parseHexStr2Byte(String hexStr) {
if (hexStr.length() < 1)
return null;
byte[] result = new byte[hexStr.length()/2];
for (int i = 0;i< hexStr.length()/2; i++) {
int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);
int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);
result[i] = (byte) (high * 16 + low);
}
return result;
}
/**
* 数据加密
* @param args
*/
public static String parseStr2Hex(String content, String password){
try {
return parseByte2HexStr(encrypt(content,password));
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 数据解密
*/
public static String parseHex2Str(String content, String password){
try {
return decrypt(parseHexStr2Byte(content),password);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
Spring工具类
package com.ruoyi.common.utils.spring;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
/**
* spring工具类 方便在非spring管理环境中获取bean
*
* @author ruoyi
*/
@Component
public final class SpringUtils implements BeanFactoryPostProcessor
{
/** Spring应用上下文环境 */
private static ConfigurableListableBeanFactory beanFactory;
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException
{
SpringUtils.beanFactory = beanFactory;
}
/**
* 获取对象
*
* @param name
* @return Object 一个以所给名字注册的bean的实例
* @throws org.springframework.beans.BeansException
*
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) throws BeansException
{
return (T) beanFactory.getBean(name);
}
/**
* 获取类型为requiredType的对象
*
* @param clz
* @return
* @throws org.springframework.beans.BeansException
*
*/
public static <T> T getBean(Class<T> clz) throws BeansException
{
T result = (T) beanFactory.getBean(clz);
return result;
}
/**
* 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true
*
* @param name
* @return boolean
*/
public static boolean containsBean(String name)
{
return beanFactory.containsBean(name);
}
/**
* 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)
*
* @param name
* @return boolean
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
*
*/
public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException
{
return beanFactory.isSingleton(name);
}
/**
* @param name
* @return Class 注册对象的类型
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
*
*/
public static Class<?> getType(String name) throws NoSuchBeanDefinitionException
{
return beanFactory.getType(name);
}
/**
* 如果给定的bean名字在bean定义中有别名,则返回这些别名
*
* @param name
* @return
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
*
*/
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException
{
return beanFactory.getAliases(name);
}
/**
* 获取aop代理对象
*
* @param invoker
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T getAopProxy(T invoker)
{
return (T) AopContext.currentProxy();
}
}
异步任务管理器
package com.ruoyi.framework.manager;
import java.util.TimerTask;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import com.ruoyi.common.utils.Threads;
import com.ruoyi.common.utils.spring.SpringUtils;
/**
* 异步任务管理器
*
* @author ruoyi
*/
public class AsyncManager
{
/**
* 操作延迟10毫秒
*/
private final int OPERATE_DELAY_TIME = 10;
/**
* 异步操作任务调度线程池
*/
private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService");
/**
* 单例模式
*/
private AsyncManager(){}
private static AsyncManager me = new AsyncManager();
public static AsyncManager me()
{
return me;
}
/**
* 执行任务
*
* @param task 任务
*/
public void execute(TimerTask task)
{
executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
}
/**
* 停止任务线程池
*/
public void shutdown()
{
Threads.shutdownAndAwaitTermination(executor);
}
}
推荐阅读
-
彻底删除Daemon tools虚拟光驱不想让其留在电脑上
-
如何使用Kbuilder Tools制作《爸爸去哪儿》主题曲卡拉oK歌曲脚本图文教程
-
php tools for visual studio 完整可用破解详细教程
-
虚拟机中的Linux安装VMware Tools的方法
-
虚拟机VMware中安装VMware Tools for Linux的方法(Fedora16)
-
如何创建一个自己的.NET Core Global Tools
-
解决无法定位软件包 或 install net-tools
-
ubuntu 安装linux 下vmVMware tools 步骤及问题解决
-
Error:The SDK Build Tools revision (23.0.3) is too low for project ':app'. Minimum required is 25.0.
-
EF Core 迁移过程遇到EF Core tools version版本不相符的解决方案