最近要实现一个发布博客功能,涉及到博文中图片的保存与访问了,在博文中图片对应:

。由用户上传图片,我们将其保存在 mongodb 数据库中,返回图片的 url 即可显示图片了。
在这里把基本实现步骤整理了一下记录下来
添加 MongoDB 依赖并配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
lombok 依赖,不使用也可以
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
spring:
data:
mongodb:
uri: mongodb://192.168.56.101:27017/sysblog
建立图片实体
import lombok.Data;
import lombok.experimental.Accessors;
import org.bson.types.Binary;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Data
@Document
@Accessors(chain = true)
public class UploadFile {
@Id
private String id;
/** 文件名 */
private String name;
/** 上传时间 */
private LocalDateTime createdTime;
/** 文件内容 */
private Binary content;
/** 文件类型 */
private String contentType;
/** 文件大小 */
private long size;
}
- 此处 id 的类型要设置为 String ,MongoDB 会自动分配 id ,设置为数值型会报错。
- BSON 是一个二进制序列化格式,在MongoDB里面被用来做文档存储和远程程序调用,我们使用 org.bson.types.Binary 类来封装文件内容。
new Binary(byte[] byte)
上传&访问图片
上传图片后,保存至 mongodb 数据库,并返回图片的访问 url
@Slf4j
@AllArgsConstructor
@RestController
@RequestMapping("/file")
public class UploadFileController {
private final MongoTemplate mongoTemplate;
/**
* 图片上传
*/
@PostMapping("/uploadImage")
public JSONResult<String> uploadImage(@RequestParam(value = "image") MultipartFile file) {
if (file.isEmpty())
return JSONResult.build(400, "请选择一张图片", null);
JSONResult<String> jsonResult;
try {
// 赋值上传图片的属性
String fileName = file.getOriginalFilename();
UploadFile uploadFile = new UploadFile()
.setName(fileName)
.setCreatedTime(LocalDateTime.now())
.setContent(new Binary(file.getBytes()))
.setContentType(file.getContentType())
.setSize(file.getSize());
// 通过 mongoTemplate 保存后,会把数据库自动生成的主键赋值到这个对象上
UploadFile savedFile = mongoTemplate.save(uploadFile);
// 构造好这个图片的请求地址返回给前端,我们后面实现这个请求
String url = "http://localhost:8080/file/image/" + savedFile.getId();
jsonResult = JSONResult.build(200, "图片上传成功", url);
} catch (IOException e) {
log.error("图片上传失败", e);
jsonResult = JSONResult.build(500, "图片上传失败", null);
}
return jsonResult;
}
/**
* 获取图片
*/
@GetMapping(value = "/image/{id}", produces = {MediaType.IMAGE_JPEG_VALUE, MediaType.IMAGE_PNG_VALUE})
public byte[] image(@PathVariable("id") String id) {
byte[] data = null;
UploadFile file = mongoTemplate.findById(id, UploadFile.class);
if (file != null) {
data = file.getContent().getData();
}
return data;
}
}
-
MongoTemplate:spring-boot-starter-data-mongodb 依赖提供的操作 MongoDB 的类,例如增删改查等。
你也可以创建一个 repository 层接口继承 MongoRepository,类似于 JPA 的操作。
-
JSONResult:自己封装的返回 JSON 数据的工具类,类似下面这样
@Data
@Accessors(chain = true)
public class JSONResult<T> implements Serializable {
/** 状态值 */
private Integer code;
/** 提示信息 */
private String msg;
/** 数据 */
private T data;
public static <T> JSONResult<T> build(int code, String msg, T data) {
return new JSONResult<T>()
.setCode(code)
.setMsg(msg)
.setData(data);
}
}
结果
在 markdown 编辑器中插入图片,简直完美: