• 文件上传时各配置目录优先级详解


    Tomcat配置目录有以下两个

    1.spring.servlet.multipart.location:文件上传路径

    2.server.tomcat.basedir:配置Tomcat运行日志和临时文件的目录。

    如果生产中配置了这两个目录,当上传文件时,他们的优先级是?

           当上传文件时,代码执行到Request类,在发现使用时spring.servlet.multipart.location优先级高,源码可见Request类中的parseParts方法中的以下代码段。

    1. File location;
    2. //取MultipartConfigElement这个对象中的location属性即
    3. //spring.servlet.multipart.location配置的值
    4. String locationStr = mce.getLocation();
    5. if (locationStr == null || locationStr.length() == 0) {
    6. //取server.tomcat.basedir配置的值
    7. location = ((File) context.getServletContext().getAttribute(
    8. ServletContext.TEMPDIR));
    9. } else {
    10. // If relative, it is relative to TEMPDIR
    11. location = new File(locationStr);
    12. if (!location.isAbsolute()) {
    13. location = new File(
    14. (File) context.getServletContext().getAttribute(
    15. ServletContext.TEMPDIR),
    16. locationStr).getAbsoluteFile();
    17. }
    18. }

    在上面的代码段中可以得出上传文件时

    spring.servlet.multipart.location的优先级比server.tomcat.basedir的高。

    源码分析:

     spring.servlet.multipart.location通过MultipartAutoConfiguration 这个类进行赋值。并通过该类中的以下方法注入MultipartConfigElement这个Bean。

    spring.servlet.multipart.location未配置时取ServletContext.TEMPDIR属性的值。

    1. context.getServletContext().getAttribute(
    2. ServletContext.TEMPDIR)

    其中ServletContext.TEMPDIR值为javax.servlet.context.tempdir,以该值为KEY.其值对应的value是在StandardContext类中的postWorkDirectory方法中设置到Map里去的。postWorkDirectory方法在tomcat启动时调用的startInternal方法里被调用。

    其赋值源于

    1. try {
    2. catalinaHomePath = getCatalinaBase().getCanonicalPath();
    3. dir = new File(catalinaHomePath, workDir);
    4. } catch (IOException e) {
    5. log.warn(sm.getString("standardContext.workCreateException",
    6. workDir, catalinaHomePath, getName()), e);
    7. }

    catalinaHomePath的值源自Tomcat类中的initBaseDir方法赋值,赋的值依赖Tomcat类中的basedir属性,该属性是通过TomcatReactiveWebServerFactory类里的getWebServer方法赋值。basedir的值源自this.baseDirecotry。

    1. public WebServer getWebServer(HttpHandler httpHandler) {
    2. Tomcat tomcat = new Tomcat();
    3. //baseDirectory属性来源于TomcatWebServerFactoryCustomizer#customize方法
    4. File baseDir = (this.baseDirectory != null) ? this.baseDirectory
    5. : createTempDir("tomcat");
    6. tomcat.setBaseDir(baseDir.getAbsolutePath());
    7. Connector connector = new Connector(this.protocol);
    8. tomcat.getService().addConnector(connector);
    9. customizeConnector(connector);
    10. tomcat.setConnector(connector);
    11. tomcat.getHost().setAutoDeploy(false);
    12. configureEngine(tomcat.getEngine());
    13. TomcatHttpHandlerAdapter servlet = new TomcatHttpHandlerAdapter(httpHandler);
    14. prepareContext(tomcat.getHost(), servlet);
    15. return new TomcatWebServer(tomcat, getPort() >= 0);
    16. }

    其中的baseDirectory是通过WebServerFactoryCustomizerBeanPostProcessor后置处理器通过         postProcessBeforeInitialization调用了函数的WebServerFactoryCustomizercustomize方法。该函数方法实际调用的时TomcatWebServerFactoryCustomizer中的customize方法。在该方法中可以看到下面的一段代码。该代码将server.tomcat.basedir配置的值赋值到ConfigurableTomcatWebServerFactory类型的对象中。

    1. propertyMapper.from(tomcatProperties::getBasedir).whenNonNull()
    2. .to(factory::setBaseDirectory);

  • 相关阅读:
    了解网络黑客的关键攻击方法
    Java集合collection map stream流
    语法基础(数组)
    VBA实现全文件快速替换
    矩阵分析与应用-11-向量子空间的基
    微信小程序组件传值
    笔记1.6:计算机网络发展历史
    React(2)-函数组件
    hyperf 模型批量更新数据
    大模型管理工具Ollama搭建及整合springboot
  • 原文地址:https://blog.csdn.net/xl649138628/article/details/133912294