博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring Boot 内置Tomcat——getServletContext().getRealPath()为临时目录问题解决方案
阅读量:2036 次
发布时间:2019-04-28

本文共 3179 字,大约阅读时间需要 10 分钟。

问题描述

 getServletContext().getRealPath()为临时目录

问题分析

默认情况下Spring Boot中request.getServletContext().getRealPath()返回的是一个临时文件夹的地址

org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory

protected void prepareContext(Host host, ServletContextInitializer[] initializers) {		File documentRoot = getValidDocumentRoot();		TomcatEmbeddedContext context = new TomcatEmbeddedContext();		if (documentRoot != null) {			context.setResources(new LoaderHidingResourceRoot(context));		}		context.setName(getContextPath());		context.setDisplayName(getDisplayName());		context.setPath(getContextPath());		File docBase = (documentRoot != null) ? documentRoot : createTempDir("tomcat-docbase");//关键创建临时文件夹		context.setDocBase(docBase.getAbsolutePath());		context.addLifecycleListener(new FixContextListener());		context.setParentClassLoader((this.resourceLoader != null) ? this.resourceLoader.getClassLoader()				: ClassUtils.getDefaultClassLoader());		resetDefaultLocaleMapping(context);		addLocaleMappings(context);

创建的临时目录位置

 

org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory

private final DocumentRoot documentRoot = new DocumentRoot(this.logger);    /**	 * Returns the absolute document root when it points to a valid directory, logging a	 * warning and returning {@code null} otherwise.	 * @return the valid document root	 */	protected final File getValidDocumentRoot() {		return this.documentRoot.getValidDirectory();	}

 org.springframework.boot.web.servlet.server.DocumentRoot

/**	 * Returns the absolute document root when it points to a valid directory, logging a	 * warning and returning {@code null} otherwise.	 * @return the valid document root	 */	final File getValidDirectory() {		File file = this.directory;        // If document root not explicitly set see if we are running from a war archive		file = (file != null) ? file : getWarFileDocumentRoot();        // If not a war archive maybe it is an exploded war		file = (file != null) ? file : getExplodedWarFileDocumentRoot();        // Or maybe there is a document root in a well-known location		file = (file != null) ? file : getCommonDocumentRoot();		if (file == null && this.logger.isDebugEnabled()) {			logNoDocumentRoots();		}		else if (this.logger.isDebugEnabled()) {			this.logger.debug("Document root: " + file);		}		return file;	}

发现有三种取路径方式: 

war包 getWarFileDocumentRoot

导出包 getExplodedWarFileDocumentRoot

文档 getCommonDocumentRoot

内置tomcat启动应该属于第三种。

private static final String[] COMMON_DOC_ROOTS = { "src/main/webapp", "public","static" };
private File getCommonDocumentRoot() {		for (String commonDocRoot : COMMON_DOC_ROOTS) {			File root = new File(commonDocRoot);			if (root.exists() && root.isDirectory()) {				return root.getAbsoluteFile();			}		}		return null;	}

百度得知 取的是

System.getProperty("user.dir")

相当于 

File root = new File(System.getProperty("user.dir")+"src/main/webapp");

输出 System.getProperty("user.dir") 是项目层目录 

解决方案

Spring Boot会尝试读取COMMON_DOC_ROOTS 配置里面的路径

在 Spring Boot 所在的jar包或者项目所在的根目录下新建一个src/main/webapp的目录、public或者static的目录

那么通过 request.getServletContext().getRealPath()就会得到src/main/webapp、public或者static的路径

其中优先级为src/main/webapp>public>static

需要修改到模块目录下

参考:

参考文章

转载地址:http://jiwof.baihongyu.com/

你可能感兴趣的文章
对比iOS中的四种数据存储
查看>>
iOS获取音频或者视频是时间长度
查看>>
ios 调用google api 实现语音识别
查看>>
Introduction to C++ for iOS Developers: Part 1
查看>>
Xcode非ARC项目中设置部分文件ARC支持
查看>>
UIWindow & UIWindowLevel笔记
查看>>
Creating an Xcode4 Plugin
查看>>
iOS截取视频某一帧图片(关键帧,AVAssetImageGenerator)
查看>>
SDWebImage缓存图片的机制
查看>>
更轻量的 View Controllers
查看>>
谈谈编程思想
查看>>
iOS MapKit导航及地理转码辅助类
查看>>
检测iOS的网络可用性并打开网络设置
查看>>
简单封装FMDB操作sqlite的模板
查看>>
iOS开发中Instruments的用法
查看>>
iOS:关于获取网络类型和运营商信息
查看>>
使用CoreTelephony获得SIM卡网络运营商名称
查看>>
IOS学习笔记(六)inputAccessoryView,inputView
查看>>
LSCTableView: Building an Open, Drop-in Replacement of UITableView
查看>>
Android 假冒建行网银病毒分析
查看>>