完美解决springboot文件上传的虚拟路径问题 Not allowed to load local resource

问题一:Not allowed to load local resource
事故现场
这是我的本地路径位置

出现以上情况的原因是:浏览器不允许访问本地路径
所以你需要配置一个虚拟的路径代替本地的路径
接下来是我的解决办法
新建一个java配置类 文件名随意 我取了BrowserUploadConfigurer这个名字

package 这里是你自己的项目目录

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class BrowserUploadConfigurer implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/images/**") //这里是你自己设置的虚拟路径,我这里写的是/images/**,这里要对应controller写入的图片路径
                .addResourceLocations("file:D:\\workspace\\store\\src\\main\\resources\\static\\images\\");
    }
}

接下来是controller层关键代码

        String avatar = "/images/" + filename;
        //主要是这个地方要和addResourceHandler里对应上


        userService.changeAvatar(uid,avatar,username);
        //返回用户头像的路径给前端页面,将来用于头像展示使用
        return new JsonResult<>(OK,avatar);

以下是完整的controller代码

package 你自己的项目路径

import com.cy.store.controller.ex.*;
import com.cy.store.entity.User;
import com.cy.store.service.IUserService;
import com.cy.store.service.ex.InsertException;
import com.cy.store.service.ex.UsernameDuplicatedException;
import com.cy.store.util.JsonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpSession;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import static com.cy.store.controller.BaseController.OK;

@RestController //组合注解,@Controller+@ResponseBody
//@Controller    //交给spring接管
@RequestMapping("users")   //什么样的请求可以被拦截到此类当中呢,声明一个requestmapping的注解users
public class UserController extends BaseController{
    @Autowired  //交给spring 自动装配
    private IUserService userService; //业务层执行依赖于业务层接口

    @Value("${file.uploadFolder}")
    private String basePath;
    

    /**
     * MultipartFile接口是springmvc提供的一个接口,这个接口为
     * 我们包装了获取文件类型的数据(任何类型的file都可以接收),
     * springboot又整合了springmvc,只需要在处理请求的方法参数
     * 列表上声明一个类型为MultipartFile的参数,然后springboot
     * 自动将传递给服务器的文件数据赋值给这个参数
     */

    /** 设置上传文件最大路径*/
    public static final int AVATAR_MAX_SIZE = 10 * 1024 * 1024;


    /** 设置上传文件的类型*/
    public static final List<String> AVATAR_TYPE =
            new ArrayList<>();

    static {
        AVATAR_TYPE.add("image/jpeg");
        AVATAR_TYPE.add("image/png");
        AVATAR_TYPE.add("image/bmp");
        AVATAR_TYPE.add("image/gif");

    }

    /**
     * @RequestParm("vale="参数名",required=true/false),
     * 将请求方法绑定到你控制器的方法参数上
     * 传输文件的参数MultipartFile
     *
     * */

    @RequestMapping("change_avatar")
    public JsonResult<String> changeAvatar(
            HttpSession session,
            @RequestParam("file") MultipartFile file){
        if (file.isEmpty()){
            throw new FileEmptyException("文件为空");
        }

        if (file.getSize() > AVATAR_MAX_SIZE){
            throw new FileSizeException("文件大小超出设置");
        }

        //判断文件数据类型是否正确
        String contentType = file.getContentType();

        // 如果包含某个元素则返回true
        if (!AVATAR_TYPE.contains(contentType)){
            throw new FileTypeException("文件类型不支持");
        }


        //获取到文件后 用UUID生成字符串对文件进行重命名
        //工具生成一个新的字符串作为文件名(好处:避免了因文件名重复发生的覆盖)
        String originalFilename = file.getOriginalFilename();
        System.out.println("OriginalFilename="+originalFilename);
        int index = originalFilename.lastIndexOf(".");
        String suffix = originalFilename.substring(index);

        //看看这个suffix 后缀长啥样
        System.out.println(suffix);
        String filename = UUID.randomUUID().toString().toUpperCase() + suffix;


        // 保存头像文件的文件夹
        File dir = new File(basePath);
        if (!dir.exists()) {
            dir.mkdirs();
        }

        // 创建文件对象,表示保存的头像文件
        File dest = new File(dir, filename);
        // 执行保存头像文件
        try {
            file.transferTo(dest);
        } catch (IllegalStateException e) {
            // 抛出异常
            throw new FileStateException("文件状态异常,可能文件已被移动或删除");
        } catch (IOException e) {
            // 抛出异常
            throw new FileUploadIOException("上传文件时读写错误,请稍后重新尝试");
        }


        Integer uid = getuidFromSession(session);
        String username = getUsernameFromSession(session);
        //返回头像路径/images/test.png
        String avatar = "/images/" + filename;

       //调用service层方法
        userService.changeAvatar(uid,avatar,username);
        //返回用户头像的路径给前端页面,将来用于头像展示使用
        return new JsonResult<>(OK,avatar);
    }

}

头像上传测试

在这里插入图片描述
控制台也没有报错
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值