From 13dc7dd1dd861ee68aa2061523640ed1ad1e3dae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E7=82=AB=E5=A5=BD?= <143517814@qq.com> Date: Sun, 15 Dec 2024 20:11:59 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B3=A8=E9=87=8A=E4=BA=86=E5=90=8E=E7=AB=AF?= =?UTF-8?q?=E7=9A=84utils=E6=96=87=E4=BB=B6=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/lsgwr/exam/utils/FileTransUtil.java | 27 +++++++++++++ .../main/java/lsgwr/exam/utils/FileUtils.java | 39 +++++++++++++++++-- .../main/java/lsgwr/exam/utils/JwtUtils.java | 5 +++ .../java/lsgwr/exam/utils/ResultVOUtil.java | 4 ++ 4 files changed, 72 insertions(+), 3 deletions(-) diff --git a/backend/src/main/java/lsgwr/exam/utils/FileTransUtil.java b/backend/src/main/java/lsgwr/exam/utils/FileTransUtil.java index 54679c8..652de98 100644 --- a/backend/src/main/java/lsgwr/exam/utils/FileTransUtil.java +++ b/backend/src/main/java/lsgwr/exam/utils/FileTransUtil.java @@ -55,17 +55,24 @@ public class FileTransUtil { * @return 成功或者失败消息 */ public static String uploadFiles(MultipartFile[] uploadfiles, String dir) { + // 打印调试信息 log.debug("Multiple file upload!"); + // 将上传的文件名拼接成一个字符串 String uploadedFileName = Arrays.stream(uploadfiles).map(x -> x.getOriginalFilename()).filter(x -> !StringUtils.isEmpty(x)).collect(Collectors.joining(" , ")); + // 如果文件名为空,则返回错误信息 if (StringUtils.isEmpty(uploadedFileName)) { return "文件名不能为空"; } try { + // 调用工具类保存上传的文件 FileTransUtil.saveUploadedFiles(Arrays.asList(uploadfiles), dir); } catch (IOException e) { + // 如果保存文件时发生异常,则返回错误信息 return "后台服务异常"; } + // 打印上传成功的日志信息 log.info("file upload successfully! " + uploadedFileName); + // 返回上传成功的提示信息 return "文件上传成功"; } @@ -75,26 +82,37 @@ public class FileTransUtil { * @param files 上传的文件 * @throws IOException 文件保存异常 */ + // 保存上传的文件 public static void saveUploadedFiles(List files, String dir) throws IOException { + // 遍历文件列表 for (MultipartFile file : files) { + // 如果文件为空,则跳过 if (file.isEmpty()) { continue; } + // 如果文件夹不存在,则创建 if (!FileUtil.exist(dir)) { // 文件夹不存在就创建 FileUtil.mkdir(dir); } + // 获取文件的字节数组 byte[] bytes = file.getBytes(); + // 获取文件的原始文件名,并替换反斜杠为正斜杠 String fileName = file.getOriginalFilename().replace("\\", "/"); + // 如果文件名中包含斜杠,则说明是上传文件夹 if (fileName.lastIndexOf('/')>0){ // 上传文件夹的时候会有这种情况 + // 获取文件夹路径 String fileDir = dir + "/" + fileName.substring(0, fileName.lastIndexOf('/')); + // 如果文件夹不存在,则创建 if (!FileUtil.exist(fileDir)) { // 文件夹不存在就创建,创建文件夹的时候会用到 FileUtil.mkdir(fileDir); } } + // 获取文件的路径 Path path = Paths.get(dir + "/" + fileName); + // 将文件写入路径 Files.write(path, bytes); } } @@ -107,14 +125,23 @@ public class FileTransUtil { * @throws IOException 文件流读取异常 */ public static ResponseEntity downloadFile(String filePath) throws IOException { + // 记录下载文件的信息 log.info("downloading file : " + filePath); + // 创建文件系统资源 FileSystemResource file = new FileSystemResource(filePath); + // 创建响应头 HttpHeaders headers = new HttpHeaders(); + // 设置缓存控制 headers.add("Cache-Control", "no-cache, no-store, must-revalidate"); + // 设置文件下载时的文件名 headers.add("Content-Disposition", String.format("attachment; filename=\"%s\"", new String(file.getFilename().getBytes("gbk"), "iso-8859-1"))); + // 设置缓存控制 headers.add("Pragma", "no-cache"); + // 设置缓存控制 headers.add("Expires", "0"); + // 打印文件名 System.out.println(file.getFilename()); + // 返回响应实体 return ResponseEntity .ok() .headers(headers) diff --git a/backend/src/main/java/lsgwr/exam/utils/FileUtils.java b/backend/src/main/java/lsgwr/exam/utils/FileUtils.java index ebaf303..a0d3021 100644 --- a/backend/src/main/java/lsgwr/exam/utils/FileUtils.java +++ b/backend/src/main/java/lsgwr/exam/utils/FileUtils.java @@ -24,12 +24,18 @@ public class FileUtils { * @param url 文件读取路径 * @param suffix 文件后缀名 */ - public static File createFileByUrl(String url, String suffix) { + // 根据URL创建文件 + public static File createFileByUrl(String url, String suffix) { + // 从URL获取图片字节数组 byte[] byteFile = getImageFromNetByUrl(url); + // 如果字节数组不为空 if (byteFile != null) { + // 从字节数组获取文件 File file = getFileFromBytes(byteFile, suffix); + // 返回文件 return file; } else { + // 否则返回null return null; } } @@ -42,9 +48,13 @@ public class FileUtils { */ private static byte[] getImageFromNetByUrl(String strUrl) { try { + // 创建URL对象 URL url = new URL(strUrl); + // 打开连接 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + // 设置请求方法 conn.setRequestMethod("GET"); + // 设置连接超时时间 conn.setConnectTimeout(5 * 1000); // 通过输入流获取图片数据 InputStream inStream = conn.getInputStream(); @@ -65,41 +75,61 @@ public class FileUtils { * @throws Exception */ private static byte[] readInputStream(InputStream inStream) throws Exception { + // 创建一个ByteArrayOutputStream对象,用于存储读取的字节数据 ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + // 创建一个字节数组,用于存储每次读取的字节数据 byte[] buffer = new byte[1024]; + // 定义一个变量,用于存储每次读取的字节数 int len = 0; + // 循环读取输入流中的数据,直到读取完毕 while ((len = inStream.read(buffer)) != -1) { + // 将读取的字节数据写入ByteArrayOutputStream对象中 outStream.write(buffer, 0, len); } + // 关闭输入流 inStream.close(); + // 将ByteArrayOutputStream对象中的字节数据转换为字节数组并返回 return outStream.toByteArray(); } // 创建临时文件 - private static File getFileFromBytes(byte[] b, String suffix) { + // 根据字节数组和后缀名创建临时文件 + private static File getFileFromBytes(byte[] b, String suffix) { + // 定义输出流 BufferedOutputStream stream = null; + // 定义文件 File file = null; try { + // 创建临时文件 file = File.createTempFile("pattern", "." + suffix); + // 输出临时文件位置 System.out.println("临时文件位置:" + file.getCanonicalPath()); + // 创建文件输出流 FileOutputStream fstream = new FileOutputStream(file); + // 创建缓冲输出流 stream = new BufferedOutputStream(fstream); + // 将字节数组写入文件 stream.write(b); } catch (Exception e) { + // 打印异常信息 e.printStackTrace(); } finally { + // 关闭输出流 if (stream != null) { try { stream.close(); } catch (IOException e) { + // 打印异常信息 e.printStackTrace(); } } } + // 返回文件 return file; } - public static MultipartFile createImg(String url) { + // 创建一个MultipartFile对象,根据给定的url +public static MultipartFile createImg(String url) { try { // File转换成MutipartFile File file = FileUtils.createFileByUrl(url, "jpg"); @@ -131,12 +161,15 @@ public class FileUtils { } public static boolean base64ToFile(String filePath, String base64Data) throws Exception { + // 定义变量dataPrix和data,用于存储base64Data中的数据 String dataPrix = ""; String data = ""; + // 判断base64Data是否为空 if (base64Data == null || "".equals(base64Data)) { return false; } else { + // 将base64Data按照"base64,"进行分割,获取dataPrix和data String[] d = base64Data.split("base64,"); if (d != null && d.length == 2) { dataPrix = d[0]; diff --git a/backend/src/main/java/lsgwr/exam/utils/JwtUtils.java b/backend/src/main/java/lsgwr/exam/utils/JwtUtils.java index 91b673a..5d5e908 100644 --- a/backend/src/main/java/lsgwr/exam/utils/JwtUtils.java +++ b/backend/src/main/java/lsgwr/exam/utils/JwtUtils.java @@ -26,17 +26,21 @@ public class JwtUtils { private static final String APP_SECRET = "liangshanguang"; public static String genJsonWebToken(User user) { + // 判断用户信息是否为空 if (user == null || user.getUserId() == null || user.getUserUsername() == null || user.getUserAvatar() == null) { return null; } + // 使用Jwts.builder()创建一个JWT对象 return Jwts.builder().setSubject(SUBJECT) // 下面3行设置token中间字段,携带用户的信息 .claim("id", user.getUserId()) .claim("username", user.getUserUsername()) .claim("avatar", user.getUserAvatar()) + // 设置签发时间 .setIssuedAt(new Date()) // 设置过期时间 .setExpiration(new Date(System.currentTimeMillis() + EXPIRE)) + // 使用HS256算法进行签名 .signWith(SignatureAlgorithm.HS256, APP_SECRET) // 生成的结果字符串太长,这里压缩下 .compact(); @@ -50,6 +54,7 @@ public class JwtUtils { */ public static Claims checkJWT(String token) { try { + // 使用Jwts解析token,并设置签名密钥为APP_SECRET return Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(token).getBody(); } catch (Exception e) { // 篡改token会导致校验失败,走到异常分支,这里返回null diff --git a/backend/src/main/java/lsgwr/exam/utils/ResultVOUtil.java b/backend/src/main/java/lsgwr/exam/utils/ResultVOUtil.java index fbd6df1..9fadd60 100644 --- a/backend/src/main/java/lsgwr/exam/utils/ResultVOUtil.java +++ b/backend/src/main/java/lsgwr/exam/utils/ResultVOUtil.java @@ -10,19 +10,23 @@ import lsgwr.exam.vo.ResultVO; public class ResultVOUtil { + // 返回一个包含code、msg和object的ResultVO对象 public static ResultVO success(Integer code, String msg, Object object) { return new ResultVO(code, msg, object); } + // 返回一个包含object的ResultVO对象,默认code为0,msg为"成功" public static ResultVO success(Object object) { return new ResultVO(0, "成功", object); } + // 返回一个默认的ResultVO对象,默认code为0,msg为"成功",object为null public static ResultVO success() { return new ResultVO(0, "成功", null); } + // 返回一个包含code和msg的ResultVO对象,默认object为null public static ResultVO error(Integer code, String msg) { return new ResultVO(code, msg, null); }