CODE WITH SIBIN

Solving Real Problems with Real Code


Integrating Spring Boot with Spring AI Markdown Document Reader

πŸ“Œ 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

Leave a Reply

Your email address will not be published. Required fields are marked *