首页 > 解决方案 > 在Linux服务器上部署的Java Web应用程序中上传文件时权限被拒绝

问题描述

我有一个 java web 应用程序,spring 4 和 jstl 部署在安装在 linux 服务器上的 wildfly 上。在这个应用程序中,我必须上传 Excel 文件以提取数据并在某个表中注入漏洞。为此,我为 multipart 定义了此配置:

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 服务器中,在 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)

有人可以帮我解决这个问题吗?在 Windows 中一切正常。

标签: javalinuxspringwildfly

解决方案


我感谢每个人的回应。最后,我找到了错误。它来自这一行:

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 上传文件时,发现了错误。正如我稍后所说,我通过 concat file.getOriginalFilename() 使用容器文件夹的绝对路径进行了修复。


推荐阅读