这篇文章主要讲解了“SpringBoot怎么设置静态资源访问控制和封装集成”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“SpringBoot怎么设置静态资源访问控制和封装集成”吧!
最近在着手公司框架优化及项目实际应用,原先方案是springboot+html前后端分离单独部署,后端人员兼职前端开发,后续产品线业务进行优化,面向企业使用部分由移动网站人员负责设计开发,内部配置后台管理还是由后端负责,随着框架不停迭代与使用的项目越来越多,项目升级框架变得十分麻烦,后端部分可以通过maven私服进行版本迭代,后台管理页面升级则需要进行各个项目拷贝,所以决定对框架进行整合,将后台管理页面与框架后端代码进行整合发布。
框架打包后台管理相关标准资源及页面(框架public文件夹)
项目使用框架,开发具体业务配置管理页面(项目static文件夹)
项目需要个性化框架页面时,在项目static文件夹建立与框架同目录同名称资源文件进行覆盖,访问时优先级高于框架目录
自定义WebConfig实现WebMvcConfigurer,重写addResourceHandlers方法
@Configuration public class WebConfig implements WebMvcConfigurer { @Value("${system.projectName}") private String projectName; /** * 添加静态资源文件,外部可以直接访问地址 * * @param registry */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { //第一个方法设置访问路径前缀,第二个方法设置资源路径 registry.addResourceHandler("/" + projectName + "/**").addResourceLocations("classpath:/static/","classpath:/public/","file:static/"); } }
图标与字体文件夹访问失败问题
将静态文件拷贝到static/public/resource文件夹下访问时,图标与字体文件会进行过滤导致损坏,需要在pom文件中进行设置
<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>
在对静态内目录设置自定义访问路径替换原有的/**后,无法找到目录下的index页面,需要建立拦截器手动进行判断,效果为访问http://localhost:port/projectName 会自动跳转到 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; } }
在对静态内目录设置自定义访问路径替换原有的/**后,无法找到目录下的favcion.ico图标,需要在页面引用统一js统一设置,同时需要在配置文件中关闭默认图标,替换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>');
框架静态资源文件获取
项目启动时,因为是引用框架的jar包,我们需要先找到指定jar包,再将jar包进行解压,找到对应目录将资源拷贝到我们需要的地方便于访问
public static void copyFrameStaticFile() { String packageName = "com.haopan.frame"; // 获取包的名字 并进行替换 String packageDirName = packageName.replace('.', '/'); // 定义一个枚举的集合 并进行循环来处理这个目录下的things Enumeration<URL> dirs; try { dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName); // 循环迭代下去 while (dirs.hasMoreElements()) { // 获取下一个元素 URL url = dirs.nextElement(); // 得到协议的名称 String protocol = url.getProtocol(); if ("jar".equals(protocol)) { // 如果是jar包文件 // 定义一个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("框架静态文件复制完毕!"); } catch (IOException e) { e.printStackTrace(); } } } } catch (IOException e) { e.printStackTrace(); } }
对JarFile中的JarEntry对象进行遍历,判断是文件还是目录分类处理
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()+"出错---"+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()); //调用复制文件的方法 //System.out.println("原路径["+f.getPath()+"] 被复制路径["+f2+"/"+f.getName()+"]"); }else if(f.isDirectory()){ copyFileFolder(f.getPath(),f2+"/"+f.getName()); //调用复制文件夹的方法 //System.out.println("原路径["+f.getPath()+"] 被复制路径["+f2+"/"+f.getName()+"]"); } } } /** * 复制文件夹 * @throws IOException */ public static void copyFileFolder(String sourceFolderPath,String targetFolderPath) throws IOException { //创建文件夹 File file=new File(targetFolderPath); if(!file.exists()){ file.mkdirs(); } copy(sourceFolderPath,targetFolderPath); } /** * 复制文件 * @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); } } /** * 删除单个文件 * * @param fileName:要删除的文件的文件名 * @return 单个文件删除成功返回true,否则返回false */ public static boolean deleteFile(String fileName) { File file =new File(fileName); // 如果文件路径所对应的文件存在,并且是一个文件,则直接删除 if (file.exists() && file.isFile()) { if (file.delete()) { //System.out.println("删除单个文件" + fileName +"成功!"); return true; }else { //System.out.println("删除单个文件" + fileName +"失败!"); return false; } }else { //System.out.println("删除单个文件失败:" + fileName +"不存在!"); return false; } } /** * 删除目录及目录下的文件 * * @param dir:要删除的目录的文件路径 * @return 目录删除成功返回true,否则返回false */ public static boolean deleteDirectory(String dir) { // 如果dir不以文件分隔符结尾,自动添加文件分隔符 if (!dir.endsWith(File.separator)) dir = dir + File.separator; File dirFile =new File(dir); // 如果dir对应的文件不存在,或者不是一个目录,则退出 if ((!dirFile.exists()) || (!dirFile.isDirectory())) { System.out.println("删除目录失败:" + 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; } // 删除当前目录 if (dirFile.delete()) { //System.out.println("删除目录" + dir +"成功!"); return true; }else { return false; } } }
外部静态资源访问与优先级设置
设置yml文件中的static-locations配置项,多个使用,隔开,同时指定顺序为访问的优先级
spring: resources: static-locations: classpath:static/,classpath:public/,file:static/
最终目录结构图如下,框架部分完全是项目启动时自动解压拷贝的,项目部分则是由具体项目进行开发,项目部分也可以很方便的进行框架部分功能重构,例如登录页,主页面修改等,本方式支持jar包和war包两种打包方式
感谢各位的阅读,以上就是“SpringBoot怎么设置静态资源访问控制和封装集成”的内容了,经过本文的学习后,相信大家对SpringBoot怎么设置静态资源访问控制和封装集成这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。