Java后端对文件上传的操作

Java后端对文件上传的操作

在对前端传回的图片进行后端操作,我只知道用 MultipartFile进行操作,而不知道具体操作的代码,在网上百度过后有两种方法,第一种是把图片放到resource文件夹下面,但是后来发现这样写在把项目打包成jar包以后就不能放到jar包对应的文件夹下面,这样很不好啊,所以又查询到第二种方法

方法一

先写一个util来获取并放置文件路径

public class UploadUtils {
​
    // 项目根路径下的目录  -- SpringBoot static 目录相当于是根路径下(SpringBoot 默认)
    public final static String IMG_PATH_PREFIX = "static/upload/imgs";
​
    public static File getImgDirFile(){
​
        // 构建上传文件的存放 "文件夹" 路径
        String fileDirPath = "src/main/resources/" + IMG_PATH_PREFIX;
​
        File fileDir = new File(fileDirPath);
        if(!fileDir.exists()){
            // 递归生成文件夹
            fileDir.mkdirs();
        }
        return fileDir;
    }
}

然后后端controller这么写

    @PostMapping("/uploadImg")
    public Result insert(@RequestPart("blog_img") MultipartFile multipartFile, HttpSession session) throws IOException {
        // 拿到文件名
        String filename = multipartFile.getOriginalFilename();
​
        // 存放上传图片的文件夹
        File fileDir = UploadUtils.getImgDirFile();
        // 输出文件夹绝对路径  -- 这里的绝对路径是相当于当前项目的路径而不是“容器”路径
        log.info("图片绝对路径为{}",fileDir.getAbsolutePath());
        try {
            // 构建真实的文件路径
            File newFile = new File(fileDir.getAbsolutePath() + File.separator + filename);
            log.info("图片路径为{}",newFile.getAbsolutePath());
​
            // 上传图片到 -》 “绝对路径”
            multipartFile.transferTo(newFile);
​
            return Result.success("图片上传成功!",null);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return Result.fail("图片上传失败");
    }

这种方法就是用来放到resource文件夹下面的

方法二

@PostMapping("/uploadImg")
public Result insert(@RequestPart("blog_img") MultipartFile multipartFile, HttpSession session) throws IOException {
        String fileName=multipartFile.getOriginalFilename(); //获取文件名以及后缀名
        fileName= UUID.randomUUID()+"_"+fileName;//重新生成文件名(根据具体情况生成对应文件名)
​
        //获取jar包所在目录
        ApplicationHome h = new ApplicationHome(getClass());
        File jarF = h.getSource();
        //在jar包所在目录下生成一个upload文件夹用来存储上传的图片
        String dirPath = jarF.getParentFile().toString()+"/upload/";
        System.out.println(dirPath);
​
        File filePath=new File(dirPath);
        if(!filePath.exists()){
            filePath.mkdirs();
        }
        try{
            //将文件写入磁盘
            multipartFile.transferTo(new File(dirPath+fileName));
            //上传成功返回状态信息
            return Result.success("图片上传成功!",null);
        }catch (Exception e){
            e.printStackTrace();
            //上传失败,返回失败信息
            return Result.fail("图片上传失败");
        }
    }

注:在上传图片的时候我发现如果文件同名就会被覆盖调,这样肯定是不行的,那我们通过uuid这种方式给文件名进行重新命名就不会重复了

String fileName=multipartFile.getOriginalFilename(); //获取文件名以及后缀名
fileName= UUID.randomUUID()+"_"+fileName;//重新生成文件名(根据具体情况生成对应文件名)

方法三

前面两种方法我最后都没有用上去,在放到服务器上去的时候一是没有resource路径,二是我一开始没搞懂阅览器不允许直接读取服务器的图片,有危险,但是在后来解决了跨域问题我就解决了,在实际项目中,还有得有自己的云存储空间更靠谱

实际操作:

Service的接口


 

@Service
public class FileServiceImpl implements FileService {
    @Override
    public boolean upload(MultipartFile multipartFile) {
        String uuid = UUID.randomUUID().toString();
        String realFileName =   uuid +"."+ multipartFile.getOriginalFilename().split("\.")[1];
        try {
            //把文件直接传输到服务器的绝对路径
            File file = new File( "D:\db\"+ File.separator+realFileName);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            multipartFile.transferTo(file);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}

Controller

@RestController
public class FileController {
​
​
    @Autowired
    private FileService fileService;
    
    @PostMapping("/upload")
    public String upload(@RequestPart("file") MultipartFile multipartFile) {
​
        try {
            fileService.upload(multipartFile);
            return "success";
        } catch (Exception e) {
        }
        return "false";
    }
}

在这里贴上配置Java的跨域

@Configuration
public class CorsConfig {
    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        //  你需要跨域的地址  注意这里的 127.0.0.1 != localhost
        // * 表示对所有的地址都可以访问
        corsConfiguration.addAllowedOrigin("*");
        //  跨域的请求头
        corsConfiguration.addAllowedHeader("*");
        //  跨域的请求方法
        corsConfiguration.addAllowedMethod("*");
        //加上了这一句,大致意思是可以携带 cookie
        //最终的结果是可以 在跨域请求的时候获取同一个 session
        corsConfiguration.setAllowCredentials(true);
        return corsConfiguration;
    }
    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        //配置 可以访问的地址
        source.registerCorsConfiguration("/**", buildConfig()); // 4
        return new CorsFilter(source);
    }
}

那vue如何跨域呢

在项目路径下的config文件夹下面的index.js的文件里面

module.exports里面的dev下面的proxyTable里面配置

dev: {
    // 静态资源文件夹
    assetsSubDirectory: 'static',
    // 发布路径
    assetsPublicPath: '/',
    proxyTable: {
      '/api': {
        target: 'http://127.0.0.1:8082', //设置调用接口地址和端口号别忘了加http
        changeOrigin: true,// 如果接口跨域,需要进行这个参数配置,为true的话,请求的header将会设置为匹配目标服务器的规则(Access-Control-Allow-Origin
        pathRewrite: {
          '^/api': '/' //这里理解成用‘/api’代替target里面的地址,组件中我们调接口时直接用/api代替
          // 比如我要调用'http://0.0:300/user/add',直接写‘/api/user/add’即可 代理后地址栏显示/
        }
      }
    },
​
    // Various Dev Server settings
    host: 'localhost', // can be overwritten by process.env.HOST
    port: 9528, // 端口号
    autoOpenBrowser: true,
    errorOverlay: true,
    notifyOnErrors: false,
    poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
​
    // Use Eslint Loader?
    // If true, your code will be linted during bundling and
    // linting errors and warnings will be shown in the console.
    useEslint: true,
    // If true, eslint errors and warnings will also be shown in the error overlay
    // in the browser.
    showEslintErrorsInOverlay: false,
​
    /**
     * Source Maps
     */
​
    // https://webpack.js.org/configuration/devtool/#development
    devtool: 'cheap-source-map',
​
    // CSS Sourcemaps off by default because relative paths are "buggy"
    // with this option, according to the CSS-Loader README
    // (https://github.com/webpack/css-loader#sourcemaps)
    // In our experience, they generally work as expected,
    // just be aware of this issue when enabling this option.
    cssSourceMap: false
  },

你可能感兴趣的:(后端,java,前端,开发语言,架构,分布式)