> ## Documentation Index
> Fetch the complete documentation index at: https://docs.markpdf.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Ejemplos

> Real Java SDK use cases: Spring Boot, large PDFs, BYOS, RAG and ZIPs.

# Ejemplos

## Upload endpoint with Spring Boot

```java theme={null}
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import tech.markpdf.*;

@RestController
public class ConvertController {

    private final MarkpdfClient client = new MarkpdfClient(System.getenv("MARKPDF_API_KEY"));

    @PostMapping(value = "/upload", produces = "text/markdown")
    public String upload(@RequestParam("file") MultipartFile file) throws Exception {
        ConvertOptions options = ConvertOptions.builder()
            .mode(ConvertOptions.Mode.FAST)
            .build();

        ConvertResult result = client.convertBytes(file.getBytes(), file.getOriginalFilename(), options);

        return switch (result) {
            case ConvertResult.Markdown md -> md.markdown();
            case ConvertResult.Json j -> j.result().markdown();
            case ConvertResult.Queued q -> throw new IllegalStateException("unexpected queued result");
        };
    }
}
```

## Endpoint reactive with `CompletableFuture`

```java theme={null}
@PostMapping(value = "/upload-async", produces = "text/markdown")
public CompletableFuture<String> uploadAsync(@RequestParam("file") MultipartFile file) throws Exception {
    return client.convertBytesAsync(file.getBytes(), file.getOriginalFilename(), ConvertOptions.defaults())
        .thenApply(result -> switch (result) {
            case ConvertResult.Markdown md -> md.markdown();
            case ConvertResult.Json j -> j.result().markdown();
            case ConvertResult.Queued q -> throw new IllegalStateException("unexpected queued result");
        });
}
```

## PDF large with page range

```java theme={null}
ConvertOptions options = ConvertOptions.builder()
    .pages("120-145")
    .mode(ConvertOptions.Mode.FAST)
    .build();

ConvertResult result = client.convertFromUrl(
    "https://bucket.example.com/manual-800-papages.pdf?sig=...",
    "manual.pdf",
    options
);
```

Combine it with [`pdfIndex`](/docs/sdks/java/reference#pdfindex) to know what range to order without downloading the entire PDF client-side.

## BYOS: upload the result directly to your storage

```java theme={null}
ConvertOptions options = ConvertOptions.builder()
    .responseFormat(ConvertOptions.ResponseFormat.JSON)
    .outputUrl(presignedPutUrl)     // pre-signed PUT to your bucket
    .outputHeadUrl(presignedHeadUrl) // optional: detect cache hits
    .build();

ConvertResult result = client.convertFromUrl(pdfUrl, "report.pdf", options);

if (result instanceof ConvertResult.Json json) {
    System.out.println(json.result().markdown()); // vacío si se usó outputUrl
}
```

With `outputUrl`, the API uploads the Markdown directly to your storage and returns a lightweight JSON instead of the full body. See [Compression](/docs/concepts/compression) for `outputEncoding`.

## Pipeline RAG with `pdfIndex`

```java theme={null}
String PDF = "https://bucket.example.com/informe-anual.pdf?sig=...";

// 1. Index without converting the entire document
Map<String, Object> spine = client.pdfIndex(PDF, null);
List<Map<String, Object>> sections = (List<Map<String, Object>>) spine.get("sections");

// 2. Choose the section of interest
Map<String, Object> target = sections.stream()
    .filter(s -> ((String) s.get("text")).contains("Resultados"))
    .findFirst()
    .orElseThrow();

int targetPage = (int) target.get("page");
int pageCount = (int) spine.get("pageCount");

// 3. Bring Markdown only from that section
ConvertOptions options = ConvertOptions.builder()
    .pages(targetPage + "-" + pageCount)
    .mode(ConvertOptions.Mode.FAST)
    .build();

ConvertResult result = client.convertFromUrl(PDF, "informe-anual.pdf", options);
```

See [PDF Index for AI agents](/docs/concepts/pdf-index-for-ai-agents).

## Process a ZIP

```java theme={null}
byte[] zipBytes = Files.readAllBytes(Path.of("documents.zip"));

ConvertOptions options = ConvertOptions.builder()
    .inputFormat(ConvertOptions.InputFormat.ZIP)
    .responseFormat(ConvertOptions.ResponseFormat.JSON)
    .build();

ConvertResult result = client.convertBytes(zipBytes, "documents.zip", options);

if (result instanceof ConvertResult.Json json) {
    System.out.println(json.result().markdown()); // Markdown concatenated from the documents inside the ZIP
}
```

<Warning>
  The file size and quantity limits within ZIP are in [Limits](/docs/concepts/limits). An out-of-range ZIP casts `MarkpdfException.PayloadTooLargeException`.
</Warning>
