SpringBoot: On the file upload and access pit (MultiPartFile)

The project environment is SpringBoot 2.0.4, JDK8.0. Server environment for CentOS7.0, Nginx forgot version.


Foreword


SpringBoot use MultiPartFile receiving a file from a form file, and then upload the server is the most basic needs of a project, the project is based on my previous SpringMVC build the framework, so be MultiPartFile upload pit encountered when using SpringBoot, saying here look, which mainly consists of two pits.

  • Use transferTo () method can not find a file path when writing File.

  • Nginx when accessing files 403 forbidden issue.


Use transferTo () method can not find a file path when writing File


Before we solve the problem, we look at the method of packaging and uploading error log.

    public static final String BASE_PATH = "/test/";

    public static String upload(MultipartFile imageFile) {

        if (imageFile.isEmpty()) {
            return null;
        }
        String filename = imageFile.getOriginalFilename();
        
        String ext= null;
        if(filename.contains(".")){
            ext = filename.substring(filename.lastIndexOf("."));
        }else{
            ext = "";
        }
        
        String uuid =  UUID.randomUUID().toString().replaceAll("-", "");
        String nfileName = uuid + ext;
        String dirPath = DateFormatUtils.format(new Date(), "yyyyMMdd");
        String filepath = BASE_PATH.endsWith("/") ? BASE_PATH+dirPath : BASE_PATH+"/"+dirPath;
        File targetFile = new File(filepath, nfileName);
        if (!targetFile.exists()) {
            targetFile.mkdirs();
        } else {
            targetFile.delete();
        }
        try {
            imageFile.transferTo(targetFile);
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        String accessUrl =  "/"+nfileName;
        logger.debug("上传文件成功 URL:" + nfileName);
        return accessUrl;
    }

As shown in the following error log.

java.io.IOException: java.io.FileNotFoundException: /test/20181025/be3676dffca94c6dac5e96a1a41dcd97.jpg (Is a directory)
    at org.apache.catalina.core.ApplicationPart.write(ApplicationPart.java:122)
    at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile.transferTo(StandardMultipartHttpServletRequest.java:255)
    at com.dong.runline.common.utils.UploadUtils.upload(UploadUtils.java:56)
    at com.dong.runline.controller.TimeLineController.createTimeLineAction(TimeLineController.java:55)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)

Here appeared java.io.FileNotFoundException mistake, this is how it caused? By breakpoint in the Debug we found the following position error has occurred.

Here I use the local environment has been tested and found locally created this kind of a path, the final picture is to create such a path.

In SpringMVC environment and no such problems have emerged in SpringBoot such a problem, then in the end how is causing it? Many online blog written by querying transferTo () method to find the source of the crux of the issue.

@Override
public void transferTo(File dest) throws IOException, IllegalStateException {
    this.part.write(dest.getPath());
}

We then enter the write () method.

    @Override
    public void write(String fileName) throws IOException {
        File file = new File(fileName);
        if (!file.isAbsolute()) {
            file = new File(location, fileName);
        }
        try {
            fileItem.write(file);
        } catch (Exception e) {
            throw new IOException(e);
        }
    }

This time we see that if !file.isAbsolute()established, that is, we do not use an absolute path, then file = new File(location,fileName);will add location based on the original path. This is the reason, it is also very easy to solve, total online there are two options.

  • Use an absolute path
  • Modify the value of location

The first option we will not explain too much, we look at how to modify the value of the location, and we just need to start following Bean to inject in class. The path to the path our store.

    @Bean
    MultipartConfigElement multipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        factory.setLocation(UploadUtils.BASE_PATH);
        return factory.createMultipartConfig();
    }

Then we modified the method to create a File under UploadUtils in the can.

        String uuid =  UUID.randomUUID().toString().replaceAll("-", "");
        String nfileName = uuid + ext;
        File targetFile = new File(nfileName);
        if (!targetFile.exists()) {
            targetFile.mkdirs();
        } else {
            targetFile.delete();
        }


Nginx when accessing files 403 forbidden issue


403 so-called Nginx error in fact access error. The current user does not have permission to access the resource, this understanding, we have two options feasible. First, reduce the level of file access permissions . Second, increased user access rights Here we look at how one by one to achieve.

  • Reduce file access permission levels

Reduced access to files, we only need to use the chmod command can be here briefly explain the chmod command.

In the process of using the Mac we often modify the permissions of a file, for example:

chmod 777 file

If the above set, then any user will have full access to the file file.

So why is a three-digit number? This is because the three digits representing the file owner User, Groups Group, other Other rights of the three. That authority level owner of 7, the group permission levels 7, 7 other authority level also.

So why is it 7? This is because a total of three linux file permissions are read r, write w, operating x. Corresponding values ​​are 4,2,1. When a user has a value of 7 on a file when, this time for the 4 + 2 + 1, which means he has all the rights to the file.

It says the chmod how to use the command, then the next we can use the file server chmod 664 file command, and then reduce the level of file access permissions. So that all users have access to files, but the question is, do users Upload once, we need to manually modify a file permissions, which is obviously not true, then how can we do? this time we need to improve the user's access rights.

  • Increased user access rights

Improve the user's access rights, here is actually modify the initiator of Nginx, we start by setting a maximum authorized person, then we can have access to the files.

First, we look at who started the following instructions need to use Nginx.

 ps aux | grep "nginx: worker process" | awk '{print $1}'

Here I've made changes, as shown in the screenshot below.

Originally set up access, if any Nginx configuration does not, then the first root should be nobody, that is, the initiator of Nginx. Previously been used ** ls -l file ** command queries the case file permissions, root has read write permissions, other without any permission. Therefore, we should start to root person can be.

Nginx open position where the configuration file, {nginx} represents your nginx installation path.

vi {nginx}/conf/nginx.conf

Add initiator, as shown below.

user root

Return to the sbin directory, ready to detect the configuration file and restart Ngnix.

cd ../sbin/

The accuracy of detection of the configuration file

./nginx -t

Detection without any problems, restart

./nginx -s reload

This time can be normal access to the files.


Epilogue


This blog collect it be everyday problems, tidy. Nothing more to say, just do something. Welcome attention Sao Dong



Original Address: https: //www.jianshu.com/p/d8666f2e698f

Guess you like

Origin www.cnblogs.com/jpfss/p/10984123.html