在Java中如何像docsify一样处理MarkDown文件

概述

现在自己搭建博客越来越常见。在程序员的世界里更加流行用 markdown 来写博客,本文就 docsify 的后端实现部分做简单模拟。

原理

基本流程如下:

  1. 前端上传MarkDown文件
  2. 后端将文件存储在文件服务器(OSS、FastDFS、本地…)
  3. 前端根据文件名请求接口url
  4. 后端将MarkDown文件以流的形式返回
  5. 前端获取到流后根据MarkDown语法标签映射为css对应选择器(markdown-it…)
  6. 浏览器渲染

基本实现

application.yml

1
2
3
4
5
6
spring:
servlet:
multipart:
max-file-size: 10240
max-request-size: 10240
enabled: true

UploadController

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
@Slf4j
@RestController
@RequestMapping("/test")
public class UploadController {

String filePath = "";

/**
* localhost:8080/test/upload
* @param file markdown文件
* @return
*/
@RequestMapping(value = "/upload", method = {RequestMethod.GET, RequestMethod.POST})
public Object upload(@RequestParam(value = "file", required = false) MultipartFile file) {

String dir = System.getProperty("user.dir");
filePath = dir + "\\src\\main\\resources\\static\\md\\";

String filename = file.getOriginalFilename();
File dest = new File(filePath + filename);
try {
file.transferTo(dest);
log.info("上传成功");
return "upload success";
} catch (IOException e) {
e.printStackTrace();
return "upload failed";
}
}

/**
* http://localhost:8080/test/render/TEST.md
* @param name markdown文件名
* @param response 以字节流的形式返回
* @throws IOException
*/
@GetMapping("/render/{name}")
public void md(@PathVariable String name, HttpServletResponse response) throws IOException {

String dir = System.getProperty("user.dir");
filePath = dir + "\\src\\main\\resources\\static\\md\\";

InputStream inputStream = new FileInputStream(new File(filePath, name));
OutputStream outputStream = response.getOutputStream();
response.addHeader("Content-Length", String.valueOf(inputStream.available()));
response.setHeader("Accept-Ranges", "bytes");
response.setContentType("text/markdown");
IOUtils.copy(inputStream, outputStream);
outputStream.flush();
}

/**
* http://localhost:8080/test/download/TEST.md
* @param name markdown文件名
* @param response 文件下载
* @throws IOException
*/
@GetMapping("/download/{name}")
public void download(@PathVariable String name, HttpServletResponse response) throws IOException {
InputStream inputStream = new FileInputStream(new File(filePath, name));
OutputStream outputStream = response.getOutputStream();
response.setContentType("application/x-download");
response.setHeader("Content-Disposition", "attachment;filename=" + name);
IOUtils.copy(inputStream, outputStream);
outputStream.flush();
}
}

响应头

request
1
2
3
4
5
6
Accept-Ranges: bytes
Connection: keep-alive
Content-Length: 23
Content-Type: text/markdown
Date: Mon, 18 May 2020 04:50:00 GMT
Keep-Alive: timeout=60

响应体

访问 http://localhost:8080/test/render/TEST.md , 可见响应体就是我们上传的markdown文件内容

1
2
3
4
5
# Test

- 1
- 2
- 3

最后

本文到此结束,感谢阅读。如果您觉得不错,请关注公众号【当我遇上你】支持一下。