Преглед изворни кода

添加一个 JarFileResources 用于获取 jar 包内的文件资源

reghao пре 4 месеци
родитељ
комит
9efc5be1dc

+ 11 - 27
web/src/main/java/cn/reghao/bnt/web/blog/controller/ForegroundController.java

@@ -5,6 +5,7 @@ import cn.reghao.bnt.web.admin.service.SiteOptionService;
 import cn.reghao.bnt.web.blog.hibernate.HibernateQuery;
 import cn.reghao.bnt.web.blog.model.po.AboutView;
 import cn.reghao.bnt.web.blog.model.vo.*;
+import cn.reghao.bnt.web.util.JarFileResources;
 import cn.reghao.jutil.web.ServletUtil;
 import cn.reghao.bnt.web.blog.service.ArticleQuery;
 import cn.reghao.bnt.web.blog.model.CategoryType;
@@ -17,8 +18,6 @@ import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.domain.Sort;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Controller;
@@ -30,12 +29,9 @@ import org.springframework.web.bind.annotation.ResponseBody;
 
 import jakarta.servlet.http.HttpServletRequest;
 import java.io.IOException;
-import java.io.InputStream;
 import java.net.URLDecoder;
 import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 
 /**
  * @author reghao
@@ -50,16 +46,19 @@ public class ForegroundController extends BaseController {
     private final ArticleViewService articleViewService;
     private final SiteOptionService siteOptionService;
     private final FileService fileService;
+    private final JarFileResources jarFileResources;
 
     public ForegroundController(CategoryService categoryService, ArticleQuery articleQuery,
                                 HibernateQuery hibernateQuery, ArticleViewService articleViewService,
-                                SiteOptionService siteOptionService, FileService fileService) {
+                                SiteOptionService siteOptionService, FileService fileService,
+                                JarFileResources jarFileResources) {
         this.categoryService = categoryService;
         this.articleQuery = articleQuery;
         this.hibernateQuery = hibernateQuery;
         this.articleViewService = articleViewService;
         this.siteOptionService = siteOptionService;
         this.fileService = fileService;
+        this.jarFileResources = jarFileResources;
     }
 
     @Operation(summary = "前台首页", description = "N")
@@ -208,28 +207,13 @@ public class ForegroundController extends BaseController {
 
     @Operation(summary = "默认头像", description = "N")
     @GetMapping(value = "/avatar.jpg", produces = MediaType.APPLICATION_JSON_VALUE)
-    @Deprecated
     public ResponseEntity<byte[]> getAvatar() throws IOException {
         String avatarResource = "static/dist/images/avatar.jpg";
-        byte[] imageBytes = getResourceFromJar(avatarResource);
-
-        /*URL resource = Thread.currentThread().getContextClassLoader().getResource(avatarResource);
-        String avatarPath = resource.getPath();
-        System.out.println(avatarPath);
-        File file = new File(avatarPath);
-        byte[] imageBytes = Files.readAllBytes(file.toPath());*/
-
-        // 构建 HTTP 响应头
-        HttpHeaders headers = new HttpHeaders();
-        headers.setContentType(MediaType.IMAGE_JPEG);
-        headers.setContentLength(imageBytes.length);
-
+        byte[] imageBytes = jarFileResources.getFileFromResourceAsStream(avatarResource).readAllBytes();
         // 返回包含图片字节数组的 ResponseEntity
-        return new ResponseEntity<>(imageBytes, headers, HttpStatus.OK);
-    }
-
-    private byte[] getResourceFromJar(String resourcePath) throws IOException {
-        InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(resourcePath);
-        return resourceAsStream.readAllBytes();
+        return ResponseEntity.ok()
+                .contentType(MediaType.IMAGE_JPEG)
+                .contentLength(imageBytes.length)
+                .body(imageBytes);
     }
 }

+ 6 - 0
web/src/main/java/cn/reghao/bnt/web/config/spring/BeanConfig.java

@@ -1,6 +1,7 @@
 package cn.reghao.bnt.web.config.spring;
 
 import cn.reghao.bnt.common.machine.*;
+import cn.reghao.bnt.web.util.JarFileResources;
 import cn.reghao.jutil.jdk.converter.ByteConverter;
 import cn.reghao.jutil.jdk.http.WebClient;
 import cn.reghao.jutil.jdk.http.WebRequest;
@@ -71,4 +72,9 @@ public class BeanConfig {
     public OS os() {
         return new OS(systemInfo(), byteConverter());
     }
+
+    @Bean
+    public JarFileResources jarFileResources() {
+        return new JarFileResources();
+    }
 }

+ 102 - 0
web/src/main/java/cn/reghao/bnt/web/util/JarFileResources.java

@@ -0,0 +1,102 @@
+package cn.reghao.bnt.web.util;
+
+import java.io.*;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 获取 jar 包内的文件资源
+ * 
+ * @author reghao
+ * @date 2025-11-03 16:05:43
+ */
+public class JarFileResources {
+    /**
+     * get a file from the resources folder
+     * works everywhere, IDEA, unit test and jar file.
+     * 
+     * @param
+     * @return
+     * @date 2025-11-03 16:07:27
+     */
+    public InputStream getFileFromResourceAsStream(String resourcePath) {
+        // The class loader that loaded the class
+        ClassLoader classLoader = getClass().getClassLoader();
+        InputStream inputStream = classLoader.getResourceAsStream(resourcePath);
+        // the stream holding the file content
+        if (inputStream == null) {
+            throw new IllegalArgumentException("file not found! " + resourcePath);
+        } else {
+            return inputStream;
+        }
+    }
+
+    /**
+     * The resource URL is not working in the JAR
+     * If we try to access a file that is inside a JAR,
+     * It throws NoSuchFileException (linux), InvalidPathException (Windows)
+     * Resource URL Sample: file:java-io.jar!/json/file1.json
+     *
+     * @param
+     * @return
+     * @date 2025-11-03 16:16:48
+     */
+    public File getFileFromResource(String resourcePath) throws URISyntaxException{
+        ClassLoader classLoader = getClass().getClassLoader();
+        URL resource = classLoader.getResource(resourcePath);
+        if (resource == null) {
+            throw new IllegalArgumentException("file not found! " + resourcePath);
+        } else {
+            // failed if files have whitespaces or special characters
+            //return new File(resource.getFile());
+            return new File(resource.toURI());
+        }
+    }
+
+    /**
+     * Get all paths from a folder that inside the jar file
+     * 
+     * @param
+     * @return
+     * @date 2025-11-03 16:07:52
+     */
+    public List<Path> getPathsFromResourceJar(String folder) throws URISyntaxException, IOException {
+        // get path of the current running jar
+        String jarPath = getClass().getProtectionDomain()
+                .getCodeSource()
+                .getLocation()
+                .toURI()
+                .getPath();
+        System.out.println("jar Path :" + jarPath);
+        // file walks jar
+        URI uri = URI.create("jar:file:" + jarPath);
+        List<Path> result;
+        try (FileSystem fs = FileSystems.newFileSystem(uri, Collections.emptyMap())) {
+            result = Files.walk(fs.getPath(folder))
+                    .filter(Files::isRegularFile)
+                    .collect(Collectors.toList());
+        }
+        return result;
+    }
+
+    public String getRunningJarPath() {
+        URL url = getClass().getProtectionDomain().getCodeSource().getLocation();
+        String jarFilePath = URLDecoder.decode(url.getPath(), StandardCharsets.UTF_8);
+        if (jarFilePath.endsWith(".jar")) {
+            jarFilePath = jarFilePath.substring(0, jarFilePath.lastIndexOf("/") + 1);
+        }
+
+        File file = new File(jarFilePath);
+        return file.getAbsolutePath();
+    }
+}