π Introduction
In this guide, we'll build a Spring Boot Web Application that integrates Spring AI Markdown Document Reader. This application will allow users to upload Markdown files, process their content, and return structured data as JSON.
π₯ What We'll Cover:
βοΈ Project Setup (Spring Boot + Markdown Document Reader AI)
βοΈ Attractive Project Directory Structure
βοΈ Service & Controller Implementation
βοΈ Testing with Postman (Markdown File Upload)
βοΈ Unit Testing with JUnit 5
π οΈ 1. Setting Up the Spring Boot Project
We will use:
π Spring Boot 3.4.4 for the application framework
π Spring Web for building RESTful APIs
π Spring AI Markdown Document Reader to process Markdown files
π₯ 1.1 Create a New Spring Boot Project
Using Spring Initializr:
- Group:
com.example
- Artifact:
demo
- Dependencies:
- βοΈ
Spring Web
- βοΈ
Spring AI Markdown Document Reader
- βοΈ
Alternatively, create a pom.xml
file with the following dependencies:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.4</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Markdown Reader</name>
<properties>
<java.version>17</java.version>
<spring-ai.version>1.0.0-M6</spring-ai.version>
</properties>
<dependencies>
<!-- π οΈ Spring Web for REST API -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- π Spring AI Markdown Reader -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-markdown-document-reader</artifactId>
</dependency>
<!-- π§ͺ Spring Boot Testing -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
π 2. Project Directory Structure
Here's what our project will look like:

π― 3. Implementing Markdown Processing
π οΈ 3.1 Markdown Service
The MarkdownService reads uploaded Markdown files and extracts structured Document
objects using Spring AI Markdown Reader.
package com.example.demo.service;
import org.springframework.ai.document.Document;
import org.springframework.ai.markdown.reader.MarkdownDocumentReader;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
@Service
public class MarkdownService {
public List<Document> processMarkdown(MultipartFile file) throws IOException {
MarkdownDocumentReader reader = new MarkdownDocumentReader(file.getInputStream());
return reader.read();
}
}
π 3.2 REST Controller for Markdown Processing
package com.example.demo.controller;
import com.example.demo.service.MarkdownService;
import org.springframework.ai.document.Document;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
@RestController
@RequestMapping("/api/markdown")
public class MarkdownController {
private final MarkdownService markdownService;
public MarkdownController(MarkdownService markdownService) {
this.markdownService = markdownService;
}
@PostMapping("/process")
public ResponseEntity<List<Document>> processMarkdown(@RequestParam("file") MultipartFile file) {
try {
List<Document> documents = markdownService.processMarkdown(file);
return ResponseEntity.ok(documents);
} catch (IOException e) {
return ResponseEntity.internalServerError().build();
}
}
}
π 4. Testing with Postman (Markdown File Upload)
βΆοΈ 4.1 Running the Application
Run the Spring Boot application:
mvn spring-boot:run
π οΈ 4.2 Testing API in Postman
- Endpoint:
POST http://localhost:8080/api/markdown/process
- Request Type:
multipart/form-data
- Key:
file
- Value: Choose a Markdown file (
.md
)
βοΈ Expected JSON Response:
[
{
"content": "## Introduction\nThis is a sample markdown file.",
"metadata": {}
}
]
π§ͺ 5. Unit Testing
βοΈ 5.1 Markdown Service Test
package com.example.demo;
import com.example.demo.service.MarkdownService;
import org.junit.jupiter.api.Test;
import org.springframework.ai.document.Document;
import org.springframework.mock.web.MockMultipartFile;
import java.io.IOException;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
class MarkdownServiceTest {
private final MarkdownService markdownService = new MarkdownService();
@Test
void testProcessMarkdown() throws IOException {
MockMultipartFile file = new MockMultipartFile("file", "test.md", "text/markdown", "## Title\nHello World".getBytes());
List<Document> documents = markdownService.processMarkdown(file);
assertFalse(documents.isEmpty());
assertEquals("## Title\nHello World", documents.get(0).getContent());
}
}
βοΈ 5.2 Markdown Controller Test
package com.example.demo;
import com.example.demo.controller.MarkdownController;
import com.example.demo.service.MarkdownService;
import org.junit.jupiter.api.Test;
import org.springframework.ai.document.Document;
import org.springframework.http.ResponseEntity;
import org.springframework.mock.web.MockMultipartFile;
import java.io.IOException;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
class MarkdownControllerTest {
private final MarkdownService markdownService = new MarkdownService();
private final MarkdownController markdownController = new MarkdownController(markdownService);
@Test
void testProcessMarkdown() throws IOException {
MockMultipartFile file = new MockMultipartFile("file", "test.md", "text/markdown", "## Title\nHello World".getBytes());
ResponseEntity<List<Document>> response = markdownController.processMarkdown(file);
assertEquals(200, response.getStatusCodeValue());
assertFalse(response.getBody().isEmpty());
}
}
π Integrating Spring Boot with Spring AI Markdown Document Reader
Build a powerful Markdown document reader using Spring Boot and Spring AI for intelligent text processing.
π Clone on GitHub