一、环境准备
系统:win11
开发环境:IDEA 2023.1.2 + Jdk8 + Springboot2.7.10
数据库:mysql5.7
二:背景
实现一个前端上传图片到后台服务器指定路径,并将路径存储在数据库中。
三、代码架构
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.12</version>
<!--<scope>runtime</scope>-->
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!-- alibaba的druid数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>20.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.2</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
springboot配置application.yml,这里最大文件设置默认是1MB,可以修改设置大一点,避免出现文件大小受限的错误。
server:
port: 8888
web:
upload-path: F:/zp/uploadImageDir
spring:
datasource:
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 346498
driver-class-name: com.mysql.jdbc.Driver
servlet:
multipart:
enabled: true
max-file-size: 10MB
max-request-size: 50MB
mybatis:
mapper-locations: classpath:mapping/*.xml
注意:此处使用com.mysql.jdbc.Driver驱动器,启动项目会报一个告警
四、代码实战
sql
DROP TABLE IF EXISTS `tbl_imageInfo`;
CREATE TABLE `tbl_imageInfo` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`imgPath` varchar(300) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
Controller
为了避免产生上传重名文件导致的问题,在后台重新用UUID重新生成一个随机的文件名来保存
import com.pyy.service.ImageUploadService;
import com.pyy.utils.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
@RestController
public class UploadImageController {
private static final Logger logger = LoggerFactory.getLogger(UploadImageController.class);
@Autowired
private ImageUploadService imageUploadService;
@Value("${web.upload-path}")
private String path;
@Value("${server.port}")
private String port;
@PostMapping("fileUpload")
public String upload(@RequestParam("file") MultipartFile file) {
if (file.isEmpty()) {
return "Upload file failed. File should not be empty.";
}
String contentType = file.getContentType();
String fileName = file.getOriginalFilename();
logger.error("Original file content type is {} name is: {}", contentType, fileName);
String newRandomFileName = FileUtils.generateRandomFileName(fileName);
try {
FileUtils.upload(file, path, newRandomFileName);
} catch (Exception e) {
System.out.println("Upload file exception: " + e.getMessage());
}
return "Upload img success,请到上传路径查看!" + imageUploadService.imageUpload(path + File.separator + newRandomFileName);
}
}
FileUtils
public class FileUtils {
private static final Logger logger = LoggerFactory.getLogger(FileUtils.class);
/**
* @param file 文件
* @param fileName 新的随机文件名
*/
public static void upload(MultipartFile file, String destPath, String fileName) {
File dest = new File(destPath + File.separator + fileName);
//判断文件父目录是否存在
if (!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();
}
try {
//保存文件
file.transferTo(dest);
} catch (Exception e) {
logger.error("Save file exception. {}", e.getMessage());
}
}
public static String getSuffix(String fileName) {
return fileName.substring(fileName.lastIndexOf("."));
}
public static String generateRandomFileName(String fileName) {
return UUID.randomUUID() + getSuffix(fileName);
}
}
数据库映射接口mapper
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Component;
@Mapper
@Component
public interface UploadImageMapper {
int insertImgPath(String imagePath);
}
Service:调用数据库接口保存文件路径
import com.pyy.mapper.UploadImageMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service("imageUploadService")
public class ImageUploadService {
@Autowired
private UploadImageMapper uploadImageMapper;
public String imageUpload(String filePath) {
int count = uploadImageMapper.insertImgPath(filePath);
return count >= 1 ? "Upload success." : "Upload failed.";
}
}
mybatis映射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.pyy.mapper.UploadImageMapper" >
<insert id="insertImgPath" parameterType="string">
insert into tbl_imageInfo(imgPath) values (#{imagePath})
</insert>
</mapper>
首页index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Upload Image</title>
</head>
<body>
<form enctype="multipart/form-data" method="post" action="/fileUpload">
图片<input id="file_upload" type="file" name="file" onchange="imgChange(this)"/>
<input type="submit" value="上传"/>
</form>
<img id="uploaded_images" src="" style="width: 200px; height: 300px;" />
</body>
<script type="text/javascript">
<!--显示需要上传图片的所路途-->
// 选择图片显示
function imgChange(obj) {
// 获取点击的文本框
var file = document.getElementById("file_upload");
var imgUrl = window.URL.createObjectURL(file.files[0]);
var img = document.getElementById('uploaded_images');
img.setAttribute('src', imgUrl); // 修改img标签src属性值
};
</script>
</html>
五、效果
点击上传之后,可以在指定的F:/zp/uploadImageDir目录下看到一个随机名称的图片,
然后查询数据库,可以看到图片保存的路径