文章目录
前言
- 后端在没有文件服务器的情况下,图片可通过Base64编码的格式进行上传下载。
- Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是 一种基于64个可打印字符来表示二进制数据的方法。
- Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。采用Base64编码具有不可读性,需要解码后才能阅读。
1、方式一:前端进行Base64转码
提示:前端进行文件图片的转码可减小后端处理的压力,推荐此方式。
1.1、使用步骤
1.1.1.前端HTML代码
代码如下(示例):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>上传图片</title>
</head>
<body>
<form action="xxxx" method="post" enctype="multipart/form-data">
<input type="file" name="upload" id="upImageFile" onchange="function ImageToBase64() {
let files = document.getElementById('upImageFile').files[0];
const reader = new FileReader();
reader.readAsDataURL(files)
reader.onload = () => {
console.log('base结果:' + reader.result)
}
}
ImageToBase64()"/>
</form>
</body>
<script>
</script>
</html>
2.2.2.前端console日志
前端进行图片的Base64转码,传入后端,后端用String接收 入库即可。
2、方式二:后端进行Base64转码(前端上传文件)
提示:mysql存储二进制图片类型为mediumblob(最大可存储16M)。
对应Java实体类型为byte[]
2.1、库表
2.1.1、建表语句
CREATE TABLE `test_icon` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`icon` mediumblob,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='测试图片存储'
2.1.2、ER图
2.2、后端代码
2.2.1、实体类
package com.erba.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
@TableName("test_icon")
public class Icon implements Serializable {
@TableId(value = "id",type = IdType.AUTO)
private Long id;
@TableField(value = "icon")
private byte[] icon;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public byte[] getIcon() {
return icon;
}
public void setIcon(byte[] icon) {
this.icon = icon;
}
public Icon(byte[] icon) {
this.icon = icon;
}
}
2.2.2、controller
package com.erba.controller;
import com.erba.entity.Icon;
import com.erba.service.IconService;
import com.erba.util.Base64Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
@Controller
@ResponseBody
@RequestMapping("/hello")
public class HelloController {
@Autowired
private IconService iconService;
@RequestMapping("/test")
@CrossOrigin
public List<Icon> test() {
List<Icon> list = iconService.list();
String s = Base64Util.byteToBase64(list.get(0).getIcon());
System.out.println(s);
return list;
}
@PostMapping("/upload")
public void uploadFile(MultipartFile file) throws IOException {
String fileName = file.getName();
System.out.println("文件名:" + fileName);
String s = Base64Util.fileToBase64Str(file);
byte[] arr = file.getBytes();
System.out.println(Arrays.toString(arr));
System.out.println("base64:" + s);
iconService.save(new Icon(arr));
}
}
2.2.3、Base64工具类(需自取)
package com.erba.util;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;
/**
* @author xxx
* @description Base64工具类
**/
public class Base64Util {
/**
* @Description: base64转文件
* @Param: [file64Str, outPath]
* @Return: boolean
**/
public static boolean base64StrToFile(String file64Str, String outPath) {
if (file64Str == null)
return false;
Decoder decoder = Base64.getDecoder();
try {
// 解密
byte[] b = decoder.decode(file64Str);
// 处理数据
for (int i = 0; i < b.length; ++i) {
if (b[i] < 0) {
b[i] += 256;
}
}
// 文件夹不存在则自动创建
File tempFile = new File(outPath);
if (!tempFile.getParentFile().exists()) {
tempFile.getParentFile().mkdirs();
}
OutputStream out = new FileOutputStream(tempFile);
out.write(b);
out.flush();
out.close();
return true;
} catch (Exception e) {
return false;
}
}
/**
* @Description: base64转MultipartFile
* @Param: [base64Str]
* @Return: org.springframework.web.multipart.MultipartFile
**/
public static MultipartFile base64StrToMultipartFile(String base64Str){
if (StringUtils.isEmpty(base64Str)){
return null;
}
Decoder decoder = Base64.getDecoder();
MultipartFile multipartFile = null;
try {
// 解密
byte[] b = decoder.decode(base64Str);
multipartFile = new MockMultipartFile("file.png", b);
} catch (Exception e) {
e.printStackTrace();
}
return multipartFile;
}
/**
* @Description: 文件转base64(路径入参)
* @Param: [filePath]
* @Return: java.lang.String
**/
public static String fileToBase64Str(String filePath) {
InputStream inputStream;
byte[] data = null;
try {
inputStream = new FileInputStream(filePath);
data = new byte[inputStream.available()];
inputStream.read(data);
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
// 加密
Encoder encoder = Base64.getEncoder();
return encoder.encodeToString(data);
}
/**
* @Description: 文件转base64(文件入参)
* @Param: [file]
* @Return: java.lang.String
**/
public static String fileToBase64Str(MultipartFile file) {
InputStream inputStream;
byte[] data = null;
try {
inputStream = file.getInputStream();
data = new byte[inputStream.available()];
inputStream.read(data);
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
// 加密
Encoder encoder = Base64.getEncoder();
return encoder.encodeToString(data);
}
/**
* @Description: byte转Base64
* @Param: [data]
* @Return: java.lang.String
**/
public static String byteToBase64(byte[] data){
// 加密
Encoder encoder = Base64.getEncoder();
return encoder.encodeToString(data);
}
}
2.2.4、Http测试(http文件)
POST http://localhost:8080/hello/upload
Content-Type: multipart/form-data; boundary=WebAppBoundary
--WebAppBoundary
Content-Disposition: form-data; name="file"; filename="111.png"
< C:\Users\hzf\Desktop\111.png
--WebAppBoundary--
###
###
GET http://localhost:8080/hello/test
Accept: application/json
###
2.2.5、控制台输出
2.2.6、数据库
总结
在MySQL中Blob是一个二进制的对象,它是一个可以存储大量数据的容器(如图片,音乐等等),且能容纳不同大小的数据,在MySQL中有四种Blob类型,他们的区别就是可以容纳的信息量不容分别是以下四种:
①TinyBlob类型 最大能容纳255B的数据
②Blob类型 最大能容纳65KB的
③MediumBlob类型 最大能容纳16MB的数据
④LongBlob类型 最大能容纳4GB的数据
而在我们实际使用的时候,可以根据自己的需求选择这几种类型,但是如果Blob中存储的文件的大小过大的话,会导致数据库的性能很差。