图片上传至本地服务器

使用element-ui中的Upload组件实现图片上传至本地服务器的功能的实现过程,以及遇到的问题和解决方案

1.前端解决跨域问题

vue.config.js 中的 module.exports = defineConfig({ }) 加入

1
2
3
4
5
6
7
8
9
10
11
//--跨域问题--
devServer: {
proxy: {
'/book': {
target: 'http://localhost:8080',
changeOrigin: true,
ws: false
}
}
}
//------------
  • “/book”:{} : 引号中代表监测的是以 /book 开头的接口
  • target : 代表监测到以 /book 开头的接口后,把axios请求中前面的本地服务器地址改为后端接口地址,实际发送给后端的请求就是下方后一个请求

​ axios.get(“/book/books”) —> http://localhost:8080/book/books

  • changeOrigin : 是否跨域
  • ws : 如果要代理 websockets,配置这个参数

详情参考:http://t.csdn.cn/YwDEA

2.upload组件发送请求

upload 组件 | Element

复制粘贴组件后,设置组件的 action 属性,值设置为请求地址

启动前端,部署在localhost:8081,点击组件上传图片

3.后端接收图片并保存

编写后端接口“localhsot:8080/book/imgTest”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@RequestMapping("/imgTest")
@ResponseBody
public String imgTest(MultipartFile file) throws UnsupportedEncodingException {
System.out.println(file.getOriginalFilename());
FileInputStream fis = null;
FileOutputStream fos = null;
byte[] bytes = new byte[20];

try {
fos = new FileOutputStream(
"E:\\IDEA\\SSM\\ssmBuild\\web\\WEB-INF\\img\\"
+file.getOriginalFilename());
fis = (FileInputStream) file.getInputStream();
int read = fis.read(bytes);
while(read!=-1){
fos.write(bytes,0,bytes.length);
read = fis.read(bytes);
}
}catch (Exception e){
return "500";
}finally {
try {
fos.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}

}
return "200";
}

使用MultipartFile对象作为接收参数

用FileInputStream和FileOutputStream读取接收的图片和写入服务器

4.导入相关依赖和解析器

完成第3步后,启动后端,然后前端上传图片,此时会发现后端控制台报错

这是由于没有为multipart请求配置合适的解析器而引起的。在处理上传文件等multipart请求时,需要使用合适的multipart解析器。Spring框架提供了多个multipart解析器,包括CommonsMultipartResolver、StandardServletMultipartResolver和其他一些解析器。

如果使用的是Spring Boot,可以在application.properties文件中添加以下配置:

1
2
3
4
spring.servlet.multipart.enabled=true
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB
spring.servlet.multipart.file-size-threshold=0

如果没有使用Spring Boot,则可以在Spring配置中手动配置multipart解析器。例如,如果你正在使用CommonsMultipartResolver解析器,可以在Spring配置文件中添加以下内容:

1
2
3
4
<bean id="multipartResolver" 
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10000000"/>
</bean>

这将创建一个名为multipartResolver的bean,并将CommonsMultipartResolver作为解析器。在这个例子中,设置了最大上传文件大小为10 MB。

导入解析器后,发现控制台仍然报错,在网上查找到解决办法:

这个异常是由一个类加载器错误,即在应用程序上下文中找不到 org.apache.commons.fileupload.FileItemFactory 类。这个类通常是 Apache Commons FileUpload 库中的一部分,是 Spring Multipart 解析器的一个依赖项。

解决这个问题,需要在应用程序中包含 Apache Commons FileUpload 库。可以在 Maven中添加以下依赖项来添加它:

Maven:

1
2
3
4
5
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>

导入后前端上传的图片就能保存在服务器上了

5.补充

后端接收图片并保存(改进)

编写一个工具类ImgProcessor,其中有静态方法saveImg(MultipartFile file)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import org.springframework.web.multipart.MultipartFile;
import java.io.*;

public class ImgProcessor {
public static String saveImg(MultipartFile file) throws IOException {
String originalFilename = file.getOriginalFilename(); // 获取上传的文件名
File destFolder = new File("这里写路径"); // 指定保存的文件夹路径
File destFile = new File(destFolder, originalFilename);//指定要保存文件的目标路径
file.transferTo(destFile); // 将上传的文件保存到指定文件夹中

return "Image uploaded successfully!";

}
}

在Controller中可以这么调用

1
2
3
4
5
@RequestMapping("/saveImg")
@ResponseBody
public String imgTest(MultipartFile file) throws IOException {
return ImgProcessor.saveImg(file);
}

调用后端接口返回图片

以我在小程序项目中获取头像的代码为例

1
2
3
4
5
6
7
8
9
//获取头像
@GetMapping("/getAvatar")
public ResponseEntity<Resource> getImage(@PathVariable("userId") String userId) {
String avatarName = "xxx.png"
Resource resource = new ClassPathResource("static/avatar/"+avatarName);
return ResponseEntity.ok()
.contentType(MediaType.IMAGE_PNG)
.body(resource);
}