溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

SpringBoot怎么設(shè)置靜態(tài)資源訪問(wèn)控制和封裝集成

發(fā)布時(shí)間:2021-08-02 13:45:15 來(lái)源:億速云 閱讀:126 作者:chen 欄目:開(kāi)發(fā)技術(shù)

這篇文章主要講解了“SpringBoot怎么設(shè)置靜態(tài)資源訪問(wèn)控制和封裝集成”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“SpringBoot怎么設(shè)置靜態(tài)資源訪問(wèn)控制和封裝集成”吧!

背景

最近在著手公司框架優(yōu)化及項(xiàng)目實(shí)際應(yīng)用,原先方案是springboot+html前后端分離單獨(dú)部署,后端人員兼職前端開(kāi)發(fā),后續(xù)產(chǎn)品線業(yè)務(wù)進(jìn)行優(yōu)化,面向企業(yè)使用部分由移動(dòng)網(wǎng)站人員負(fù)責(zé)設(shè)計(jì)開(kāi)發(fā),內(nèi)部配置后臺(tái)管理還是由后端負(fù)責(zé),隨著框架不停迭代與使用的項(xiàng)目越來(lái)越多,項(xiàng)目升級(jí)框架變得十分麻煩,后端部分可以通過(guò)maven私服進(jìn)行版本迭代,后臺(tái)管理頁(yè)面升級(jí)則需要進(jìn)行各個(gè)項(xiàng)目拷貝,所以決定對(duì)框架進(jìn)行整合,將后臺(tái)管理頁(yè)面與框架后端代碼進(jìn)行整合發(fā)布。

結(jié)構(gòu)設(shè)計(jì)

  • 框架打包后臺(tái)管理相關(guān)標(biāo)準(zhǔn)資源及頁(yè)面(框架public文件夾)

  • 項(xiàng)目使用框架,開(kāi)發(fā)具體業(yè)務(wù)配置管理頁(yè)面(項(xiàng)目static文件夾)

  • 項(xiàng)目需要個(gè)性化框架頁(yè)面時(shí),在項(xiàng)目static文件夾建立與框架同目錄同名稱資源文件進(jìn)行覆蓋,訪問(wèn)時(shí)優(yōu)先級(jí)高于框架目錄

SpringBoot怎么設(shè)置靜態(tài)資源訪問(wèn)控制和封裝集成

SpringBoot靜態(tài)資源訪問(wèn)

自定義訪問(wèn)路徑

自定義WebConfig實(shí)現(xiàn)WebMvcConfigurer,重寫(xiě)addResourceHandlers方法

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Value("${system.projectName}")
    private String projectName;
 

    /**
     * 添加靜態(tài)資源文件,外部可以直接訪問(wèn)地址
     *
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //第一個(gè)方法設(shè)置訪問(wèn)路徑前綴,第二個(gè)方法設(shè)置資源路徑
        registry.addResourceHandler("/" + projectName + "/**").addResourceLocations("classpath:/static/","classpath:/public/","file:static/");
    }
}

圖標(biāo)與字體文件夾訪問(wèn)失敗問(wèn)題

將靜態(tài)文件拷貝到static/public/resource文件夾下訪問(wèn)時(shí),圖標(biāo)與字體文件會(huì)進(jìn)行過(guò)濾導(dǎo)致?lián)p壞,需要在pom文件中進(jìn)行設(shè)置

 <build>
        <resources>
            <resource>
                <filtering>true</filtering>
                <directory>src/main/resources</directory>
                <excludes>
                    <exclude>**/*.woff</exclude>
                    <exclude>**/*.ttf</exclude>
                    <exclude>**/*.ico</exclude>
                </excludes>
            </resource>
            <resource>
                <filtering>false</filtering>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.woff</include>
                    <include>**/*.ttf</include>
                    <include>**/*.ico</include>
                </includes>
            </resource>
        </resources>
 </build>

自定義歡迎頁(yè)面

在對(duì)靜態(tài)內(nèi)目錄設(shè)置自定義訪問(wèn)路徑替換原有的/**后,無(wú)法找到目錄下的index頁(yè)面,需要建立攔截器手動(dòng)進(jìn)行判斷,效果為訪問(wèn)http://localhost:port/projectName 會(huì)自動(dòng)跳轉(zhuǎn)到 http://localhost:port/projectName/index.html

@Component
public class PageRedirectInterceptor implements HandlerInterceptor {
    @Value("${system.projectName}")
    private String projectName;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestURL = request.getRequestURL().toString();
        String scheme = request.getScheme();
        String servaerName = request.getServerName();
        int port = request.getServerPort();
        String rootPageURL = scheme + ":" + "//" + servaerName + ":" + port + "/" + projectName;
        if (requestURL.equals(rootPageURL)) {
            response.sendRedirect(request.getContextPath() + "/"+projectName + "/index.html");
            return false;
        }
        return true;
    }
}

自定義頁(yè)面圖標(biāo)

在對(duì)靜態(tài)內(nèi)目錄設(shè)置自定義訪問(wèn)路徑替換原有的/**后,無(wú)法找到目錄下的favcion.ico圖標(biāo),需要在頁(yè)面引用統(tǒng)一js統(tǒng)一設(shè)置,同時(shí)需要在配置文件中關(guān)閉默認(rèn)圖標(biāo),替換spring的小葉子

spring:
  mvc:
    favicon:
      enabled: false
function GetRootPath() {
    var loc = window.location,
        host = loc.hostname,
        protocol = loc.protocol,
        port = loc.port ? (':' + loc.port) : '';
    var path = location.pathname;

    if (path.indexOf('/') === 0) {
        path = path.substring(1);
    }

    var mypath = '/' + path.split('/')[0];
    path = (mypath != undefined ? mypath : ('/' + loc.pathname.split('/')[1])) + '/';

    var rootPath = protocol + '//' + host + port + path;
    return rootPath;
}

var iconurl = GetRootPath()+"favicon.ico"
document.write('<link rel="shortcut icon" href= ' + iconurl + '    ></link>');

項(xiàng)目訪問(wèn)框架靜態(tài)資源

框架靜態(tài)資源文件獲取

項(xiàng)目啟動(dòng)時(shí),因?yàn)槭且每蚣艿膉ar包,我們需要先找到指定jar包,再將jar包進(jìn)行解壓,找到對(duì)應(yīng)目錄將資源拷貝到我們需要的地方便于訪問(wèn)

掃描jar包

 public static void copyFrameStaticFile() {
        String packageName = "com.haopan.frame";
        // 獲取包的名字 并進(jìn)行替換
        String packageDirName = packageName.replace('.', '/');
        // 定義一個(gè)枚舉的集合 并進(jìn)行循環(huán)來(lái)處理這個(gè)目錄下的things
        Enumeration<URL> dirs;
        try {
            dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
            // 循環(huán)迭代下去
            while (dirs.hasMoreElements()) {
                // 獲取下一個(gè)元素
                URL url = dirs.nextElement();
                // 得到協(xié)議的名稱
                String protocol = url.getProtocol();
                if ("jar".equals(protocol)) {
                    // 如果是jar包文件
                    // 定義一個(gè)JarFile
                    JarFile jar;
                    try {
                        // 獲取jar
                        jar = ((JarURLConnection) url.openConnection()).getJarFile();
                        String templateDecompressPath = "tempfiles/decompress/" + CommonUtil.getNewGuid() + "/";
                        File targetFile = new File(templateDecompressPath);
                        if (!targetFile.exists()) {
                            targetFile.mkdirs();
                        }
                        decompressJarFile(jar, templateDecompressPath);
                        String frameStaticPath = templateDecompressPath + "public/";
                        File frameStaticFile = new File(frameStaticPath);
                        if (frameStaticFile.exists()) {
                            String copyTargetPath = "static/";
                            File copyTargetFolder = new File(copyTargetPath);
                            if (copyTargetFolder.exists()) {
                                FileUtil.deleteDirectory(copyTargetPath);
                            }
                            copyTargetFolder.mkdirs();
                            FileUtil.copyFileFolder(frameStaticPath, copyTargetPath);
                        }
                        FileUtil.deleteDirectory(templateDecompressPath);
                        System.out.println("框架靜態(tài)文件復(fù)制完畢!");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

解壓jar包

對(duì)JarFile中的JarEntry對(duì)象進(jìn)行遍歷,判斷是文件還是目錄分類處理

public static synchronized void decompressJarFile(JarFile jf,String outputPath){
        if (!outputPath.endsWith(File.separator)) {
            outputPath += File.separator;
        }
        File dir = new File(outputPath);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        try{
            for (Enumeration<JarEntry> e = jf.entries(); e.hasMoreElements();) {
                JarEntry je = (JarEntry) e.nextElement();
                String outFileName = outputPath + je.getName();
                File f = new File(outFileName);
                if(je.isDirectory()){
                    if(!f.exists()){
                        f.mkdirs();
                    }
                }else{
                    File pf = f.getParentFile();
                    if(!pf.exists()){
                        pf.mkdirs();
                    }
                    InputStream in = jf.getInputStream(je);
                    OutputStream out = new BufferedOutputStream(
                            new FileOutputStream(f));
                    byte[] buffer = new byte[2048];
                    int nBytes = 0;
                    while ((nBytes = in.read(buffer)) > 0) {
                        out.write(buffer, 0, nBytes);
                    }
                    out.flush();
                    out.close();
                    in.close();
                }
            }
        }catch(Exception e){
            System.out.println("解壓"+jf.getName()+"出錯(cuò)---"+e.getMessage());
        }finally{
            if(jf!=null){
                try {
                    jf.close();
                    File jar = new File(jf.getName());
                    if(jar.exists()){
                        jar.delete();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

拷貝目錄到指定位置

public class FileUtil {
    private static void copy(String f1, String f2) throws IOException {
        File file1=new File(f1);
        /*     File file2=new File(f2);*/

        File[] flist=file1.listFiles();
        for (File f : flist) {
            if(f.isFile()){
                copyFile(f.getPath(),f2+"/"+f.getName()); //調(diào)用復(fù)制文件的方法
                //System.out.println("原路徑["+f.getPath()+"] 被復(fù)制路徑["+f2+"/"+f.getName()+"]");
            }else if(f.isDirectory()){
                copyFileFolder(f.getPath(),f2+"/"+f.getName()); //調(diào)用復(fù)制文件夾的方法
                //System.out.println("原路徑["+f.getPath()+"] 被復(fù)制路徑["+f2+"/"+f.getName()+"]");
            }
        }
    }

    /**
     * 復(fù)制文件夾
     * @throws IOException
     */
    public static void copyFileFolder(String sourceFolderPath,String targetFolderPath) throws IOException {
        //創(chuàng)建文件夾
        File file=new File(targetFolderPath);
        if(!file.exists()){
            file.mkdirs();
        }
        copy(sourceFolderPath,targetFolderPath);
    }

    /**
     * 復(fù)制文件
     * @throws IOException
     */
    public static void copyFile(String sourceFilePath, String tagretFilePath) throws IOException {
        try {
            InputStream in = new FileInputStream(sourceFilePath);
            OutputStream out = new FileOutputStream(tagretFilePath);
            byte[] buffer = new byte[2048];
            int nBytes = 0;
            while ((nBytes = in.read(buffer)) > 0) {
                out.write(buffer, 0, nBytes);
            }
            out.flush();
            out.close();
            in.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static boolean delete(String fileName) {
        File file =new File(fileName);
        if (!file.exists()) {
            //System.out.println("刪除文件失敗:" + fileName +"不存在!");
            return false;
        }else {
            if (file.isFile())
                return deleteFile(fileName);
            else
                return deleteDirectory(fileName);
        }
    }

    /**
     * 刪除單個(gè)文件
     *
     * @param fileName:要?jiǎng)h除的文件的文件名
     * @return 單個(gè)文件刪除成功返回true,否則返回false
     */
    public static boolean deleteFile(String fileName) {
        File file =new File(fileName);
        // 如果文件路徑所對(duì)應(yīng)的文件存在,并且是一個(gè)文件,則直接刪除
        if (file.exists() && file.isFile()) {
            if (file.delete()) {
                //System.out.println("刪除單個(gè)文件" + fileName +"成功!");
                return true;
            }else {
                //System.out.println("刪除單個(gè)文件" + fileName +"失??!");
                return false;
            }
        }else {
            //System.out.println("刪除單個(gè)文件失?。?quot; + fileName +"不存在!");
            return false;
        }
    }

    /**
     * 刪除目錄及目錄下的文件
     *
     * @param dir:要?jiǎng)h除的目錄的文件路徑
     * @return 目錄刪除成功返回true,否則返回false
     */
    public static boolean deleteDirectory(String dir) {
        // 如果dir不以文件分隔符結(jié)尾,自動(dòng)添加文件分隔符
        if (!dir.endsWith(File.separator))
            dir = dir + File.separator;
        File dirFile =new File(dir);
        // 如果dir對(duì)應(yīng)的文件不存在,或者不是一個(gè)目錄,則退出
        if ((!dirFile.exists()) || (!dirFile.isDirectory())) {
            System.out.println("刪除目錄失?。?quot; + dir +"不存在!");
            return false;
        }
        boolean flag =true;
        // 刪除文件夾中的所有文件包括子目錄
        File[] files = dirFile.listFiles();
        for (int i =0; i < files.length; i++) {
            // 刪除子文件
            if (files[i].isFile()) {
                flag = deleteFile(files[i].getAbsolutePath());
                if (!flag)
                    break;
            }
            // 刪除子目錄
            else if (files[i].isDirectory()) {
                flag = deleteDirectory(files[i].getAbsolutePath());
                if (!flag)
                    break;
            }
        }
        if (!flag) {
            //System.out.println("刪除目錄失??!");
            return false;
        }
        // 刪除當(dāng)前目錄
        if (dirFile.delete()) {
            //System.out.println("刪除目錄" + dir +"成功!");
            return true;
        }else {
            return false;
        }
    }

}

外部靜態(tài)資源訪問(wèn)與優(yōu)先級(jí)設(shè)置

設(shè)置yml文件中的static-locations配置項(xiàng),多個(gè)使用,隔開(kāi),同時(shí)指定順序?yàn)樵L問(wèn)的優(yōu)先級(jí)

spring:
  resources:
    static-locations: classpath:static/,classpath:public/,file:static/

最終目錄結(jié)構(gòu)圖如下,框架部分完全是項(xiàng)目啟動(dòng)時(shí)自動(dòng)解壓拷貝的,項(xiàng)目部分則是由具體項(xiàng)目進(jìn)行開(kāi)發(fā),項(xiàng)目部分也可以很方便的進(jìn)行框架部分功能重構(gòu),例如登錄頁(yè),主頁(yè)面修改等,本方式支持jar包和war包兩種打包方式

SpringBoot怎么設(shè)置靜態(tài)資源訪問(wèn)控制和封裝集成

感謝各位的閱讀,以上就是“SpringBoot怎么設(shè)置靜態(tài)資源訪問(wèn)控制和封裝集成”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)SpringBoot怎么設(shè)置靜態(tài)資源訪問(wèn)控制和封裝集成這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI