代码之家  ›  专栏  ›  技术社区  ›  Salim Hamidi

在Linux服务器上部署的Java Web应用程序中上载文件时权限被拒绝

  •  0
  • Salim Hamidi  · 技术社区  · 6 年前

    我有一个Java Web应用程序,它的Spring4和JSTL部署在Linux服务器上的Wildfly上。在这个应用程序中,我必须上传excel文件到extrat数据,并在某个表中注入漏洞。为此,我为多部分定义了此配置:

    public class myAppServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    ... 
    
    private static final String TEMP_FOLDER_NAME = "tmp"; // Temporary location where files will be stored
    
    private static final long MAX_FILE_SIZE = 5242880; // 5MB : Max file size.
    // Beyond that size spring will throw exception.
    private static final long MAX_REQUEST_SIZE = 20971520; // 20MB : Total request size containing Multi part.
    
    private static final int FILE_SIZE_THRESHOLD = 0; // Size threshold after which files will be written to disk
    
    private MultipartConfigElement getMultipartConfigElement() {
            StringBuilder uploadTempDirectoryUrl = new StringBuilder();
            uploadTempDirectoryUrl.append(System.getenv(XeryaConstants.HOME_ENV_VARIABLE_NAME)).append(File.separator)
                    .append(TEMP_FOLDER_NAME);
            File tempDirectory = new File(uploadTempDirectoryUrl.toString());
            if (!tempDirectory.exists()) {
                log.info("XeryaServletInitializer - Create temp directory " + uploadTempDirectoryUrl);
                tempDirectory.mkdir();
            }
    
            log.info("XeryaServletInitializer - Multiplart temporal directory: " + uploadTempDirectoryUrl);
            MultipartConfigElement multipartConfigElement = new MultipartConfigElement(System.getenv(AppConstants.HOME_ENV_VARIABLE_NAME),
                    MAX_FILE_SIZE, MAX_REQUEST_SIZE, FILE_SIZE_THRESHOLD);
            return multipartConfigElement;
        }
    
        @Override
        protected void customizeRegistration(ServletRegistration.Dynamic registration) {
            registration.setMultipartConfig(getMultipartConfigElement());
        }
    }
    

    这是泛型错误方法的代码(beetween**)

        public static File convert(MultipartFile file) throws IOException
    {
        File convFile = new File(file.getOriginalFilename());
        **convFile.createNewFile();**
        FileOutputStream fos = new FileOutputStream(convFile);
        fos.write(file.getBytes());
        fos.close();
        return convFile;
    }
    

    在Linux服务器中,在configuration floder out off wildfly中创建的tmp文件夹具有以下凭据:

    root@VM-XITS01-DEV:/opt/xerya_home# ls -ld
    drwxr-xr-x 9 wildfly wildfly 4096 juil. 25 02:21
    

    问题是,当我从Windows操作系统上载Excel文件时,出现以下错误:

        2018-07-25 03:06:25,192 ERROR [stderr] (default task-47) java.io.IOException: Permission denied
    2018-07-25 03:06:25,192 ERROR [stderr] (default task-47)        at java.io.UnixFileSystem.createFileExclusively(Native Method)
    2018-07-25 03:06:25,193 ERROR [stderr] (default task-47)        at java.io.File.createNewFile(File.java:1012)
    2018-07-25 03:06:25,193 ERROR [stderr] (default task-47)        at com.xerya.school.util.XeryaUtils.convert(XeryaUtils.java:103)
    2018-07-25 03:06:25,193 ERROR [stderr] (default task-47)        at com.xerya.school.web.validator.rest.importdata.RestImportDataStudentController.uploadFile(RestImportDataStudentController.java:75)
    

    有人能帮我解决这个问题吗?在窗户里一切正常。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Salim Hamidi    6 年前

    我感谢每个人的反应。 最后,我找到了窃听器。它来自这一行:

    File convFile = new File(file.getOriginalFilename());
    

    为了解决这个问题,我将其更改为:

    String fileName = System.getenv(XeryaConstants.HOME_ENV_VARIABLE_NAME)
                .concat(File.separator)
                .concat(TEMP_FOLDER_NAME).concat(File.separator)
                .concat(file.getOriginalFilename());
        File convFile = new File(fileName);
    

    当我查看getoriginalfilename文档时,它会说:“返回客户端文件系统中的原始文件名。这可能包含路径信息,具体取决于所使用的浏览器,但它通常不会与opera以外的任何浏览器一起使用。

    我想这解释了我的行为: 当应用程序部署在windows上,并且我从chrome开始上传文件时,没有发现错误。但是当应用程序部署在linux上,我从chrome上传文件时,发现了这个bug。我被concat file.getoriginalfilename()用容器文件夹的绝对路径修复了。