Springboot文件上传与文件映射(保存URL至数据库)完整代码

Springboot文件上传与文件映射(保存URL至数据库)完整代码

0.前言

场景:上传图片文件至服务器,并且在数据库中保存一个有效URL,用于获取该图片。

先看最终效果如下:
长传图片文件效果演示
我之前也看过很多相关的文章,大部分都只是之讲解了一部分,导致我看了很多…做了很多无用功,因此实现此功能后想记录并总结一下完整的过程,已被之后复习。
其实这个功能很简单,把它分为两步部分:

  • 上传文件
  • 文件映射

而且这两部分是独立的,互不影响。
上传文件有多种方法:

  • 使用Servlet的API,write()方法写入文件(本文采用的这种)
  • 使用MultipartFile对象获取上传的文件并使用该对象的transferTo()方法
  • 使用commons-fileupload工具包实现文件上传
    等等…
    这里不会具体把每一种都写,只写了第一种,也是本人认为最简洁的。

文件映射比较简单,只需添加一个配置类即可,即本文的第二点。

1.配置上传文件保存路径

1.1 Windows环境

首先,先搞定window环境下的本地测试。我是在D盘下新建了一个用于保存上传文件的restaurantRes文件夹。
application.properties中添加配置如下:

#文件上传路径
#windows环境下上传文件保存目录
spring.servlet.multipart.location=d:/restaurantRes

1.2 Linux环境

之后要在Linux环境下的服务器测试,我在根目录下创建了pic文件夹,pic下创建了upload文件夹。配置写法如下:
(区别:Linux文件系统没有分盘)

#文件上传路径
#linux环境下上传文件保存目录
spring.servlet.multipart.location=/pic/upload

2.添加文件路径映射

新建一个配置类Java文件:WebMvcConfig.Java(名字取啥不重要)
编码如下:

2.1 Windows环境下文件路径映射

上传文件路径:D盘下的restaurantRes目录中(D:/restaurantRes/)
访问路径举例:http://localhost:8080/restaurantRes/青豆玉米粒披萨.jpg

代码中:
addResourceHandler为添加访问前缀,及上述的访问路径中的restaurantRes
addResourceLocations为添加文件原本的存储路径,及上述的上传文件路径中的D:/restaurantRes/

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
        //windows本地文件目录
        registry.addResourceHandler("/restaurantRes/**").addResourceLocations("file:D:/restaurantRes/");
    }
}

2.2 Linux环境下文件路径映射

与上述基本一致,只是路径写法不一样。

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
        //linux服务器文件目录
        //registry.addResourceHandler("/restaurantRes/**").addResourceLocations("file:/pic/upload/");
    }
}

3.控制层/实体类代码

代码中包含每个操作的详细注释。
其中注释掉了URL中的端口,是因为本项目已经配置过Https了,默认会使用443,无需再写端口。如果是windows环境本地测试或没有配置hhtps那就加上那个端口就好啦。

@Controller
@RequestMapping(value = "/restaurantApi/admin")
public class AdminController {

    static String fileLocation = "/restaurantRes/";//图片资源访问路径
    //存储预返回页面的结果对象
    private Map<String, Object> result = new HashMap<>();
    //注入业务对象
    @Resource
    private AdminService adminService;
  @PostMapping("/addFood")
    @ResponseBody
    public Map<String, Object> uploadFood(String name, double prices, String description, Part pictureFile,
                                          HttpServletRequest request) {
        //获取提交文件名称
        String filename = pictureFile.getSubmittedFileName();
        //定义上传文件存放的路径
        String path = request.getSession().getServletContext().getRealPath(fileLocation);//此处为tomcat下的路径,服务重启路径会变化
        System.out.println(path);
        //返回保存的url,根据url可以进行文件查看或者下载
        String filePath = request.getScheme() + "://" + request.getServerName()
                //+ ":" + request.getServerPort() //端口 https443端口无需添加
                + fileLocation + filename;

        String pictureFileURL = filePath;//根路径+文件名

//插入这条Food数据
        adminService.addFood(new Food(name, prices, description, pictureFileURL));

        //写入文件
        try {
            pictureFile.write(filename);
            result.put("Result", "添加菜品信息成功");
        } catch (IOException e) {
            e.printStackTrace();
            result.put("Result", "添加菜品信息失败");
        }
        return result;
    }
}

其中Food实体类的具体定义如下,与数据库中food表字段一一对应:

/**
 * 菜品实体类
 * 1.菜名
 * 2.价格
 * 3.菜品详细描述
 * 4.菜对应的图片文件URL
 */
 //Lombok插件使用注释
@Data                              // get,set
//@NoArgsConstructor                 //无参构造
@AllArgsConstructor                //有参构造
public class Food {
    private String name;
    private double prices;
    private String description;
    private String pictureFileURL;
}

相信到这里,上传文件与文件映射功能已经基本了解过程了,与上传文件与文件映射功能本身的代码已经全部展示了,下面是完成插入这条food数据操作的其他代码.

4.其他代码

4.1服务层代码

只有插入菜品信息的代码。
AdminService.java

public interface AdminService {
    // 添加信息
    int addFood(Food food);
}

AdminServiceImpl.java

@Service
@Transactional
public class AdminServiceImpl implements AdminService {

    //注入Mapper接口对象
    @Resource
    private AdminMapper adminMapper;

    @Override
    public int addFood(Food food) {
        return adminMapper.insertFood(food);
    }
}

4.2 数据访问层

插入这条数据
AdminMapper.java

/**
 * 数据访问层-操控信息
 */
@Mapper
public interface AdminMapper {
    // 添加菜品信息
    int insertFood(Food food);
}

AdminMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.lipiao.traveltreasure.dao.restaurant.AdminMapper">
    <!-- 添加活动信息 -->
    <insert id="insertFood" parameterType="com.lipiao.traveltreasure.bean.restaurantBean.Food">
        INSERT INTO food(name, prices, description, pictureFileURL)
        VALUES (#{name}, #{prices}, #{description}, #{pictureFileURL})
    </insert>
</mapper>

4.3启动类

@SpringBootApplication
@MapperScan("com.lipiao.traveltreasure.dao") //扫描Mapper接口
public class TravelTreasureApplication {
    public static void main(String[] args) {
        SpringApplication.run(TravelTreasureApplication.class, args);
    }
}

5.总结

之前在这个功能花费了一些时间,是因为路径问题出错了,少写或多写了/。
还是得细心细心再细心!
文件路径映射+文件上传至此已完成了,希望这篇自我小结得笔记能够对你帮助!若有问题欢迎留言。

发布了67 篇原创文章 · 获赞 32 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_42391904/article/details/104102476