Fix ClassCastException in extractBookmarks endpoint (#5578) (#5604)

## Description

Fixes #5578

This PR fixes a `ClassCastException` that occurs when calling
`/api/v1/general/extract-bookmarks`. The method was returning
`List<Map<String, Object>>` directly, but Spring MVC was wrapping it in
a `ResponseEntity`, causing a type mismatch.

## Changes

- Changed return type from `List<Map<String, Object>>` to
`ResponseEntity<List<Map<String, Object>>>`
- Wrapped return values with `ResponseEntity.ok(...)` to match Spring
MVC pattern
- Removed `@ResponseBody` annotation as it is not needed with
`ResponseEntity`

## Verification

This fix follows the same pattern used in other similar endpoints:
- `VerifyPDFController.verifyPDF()` returns
`ResponseEntity<List<PDFVerificationResult>>`
- `ValidateSignatureController.validateSignature()` returns
`ResponseEntity<List<SignatureValidationResult>>`

## Testing

The endpoint should now return a proper JSON response with the list of
bookmarks instead of throwing a 500 error.

---------

Co-authored-by: GitTensor Miner <miner@gittensor.io>
Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
This commit is contained in:
PandaMan
2026-02-03 02:48:09 -07:00
committed by GitHub
parent 79bc62a5d2
commit ffd1abbdb3
2 changed files with 20 additions and 12 deletions

View File

@@ -46,18 +46,18 @@ public class EditTableOfContentsController {
@Operation(
summary = "Extract PDF Bookmarks",
description = "Extracts bookmarks/table of contents from a PDF document as JSON.")
@ResponseBody
public List<Map<String, Object>> extractBookmarks(@RequestParam("file") MultipartFile file)
public ResponseEntity<List<Map<String, Object>>> extractBookmarks(@RequestParam("file") MultipartFile file)
throws Exception {
try (PDDocument document = pdfDocumentFactory.load(file)) {
PDDocumentOutline outline = document.getDocumentCatalog().getDocumentOutline();
if (outline == null) {
log.info("No outline/bookmarks found in PDF");
return new ArrayList<>();
return ResponseEntity.ok(new ArrayList<>());
}
return extractBookmarkItems(document, outline);
List<Map<String, Object>> bookmarks = extractBookmarkItems(document, outline);
return ResponseEntity.ok(bookmarks);
}
}

View File

@@ -85,10 +85,12 @@ class EditTableOfContentsControllerTest {
when(mockOutlineItem.getNextSibling()).thenReturn(null);
// When
List<Map<String, Object>> result = editTableOfContentsController.extractBookmarks(mockFile);
ResponseEntity<List<Map<String, Object>>> response = editTableOfContentsController.extractBookmarks(mockFile);
// Then
assertNotNull(result);
assertNotNull(response);
assertNotNull(response.getBody());
List<Map<String, Object>> result = response.getBody();
assertEquals(1, result.size());
Map<String, Object> bookmark = result.get(0);
@@ -107,10 +109,12 @@ class EditTableOfContentsControllerTest {
when(mockCatalog.getDocumentOutline()).thenReturn(null);
// When
List<Map<String, Object>> result = editTableOfContentsController.extractBookmarks(mockFile);
ResponseEntity<List<Map<String, Object>>> response = editTableOfContentsController.extractBookmarks(mockFile);
// Then
assertNotNull(result);
assertNotNull(response);
assertNotNull(response.getBody());
List<Map<String, Object>> result = response.getBody();
assertTrue(result.isEmpty());
verify(mockDocument).close();
}
@@ -141,10 +145,12 @@ class EditTableOfContentsControllerTest {
when(childItem.getNextSibling()).thenReturn(null);
// When
List<Map<String, Object>> result = editTableOfContentsController.extractBookmarks(mockFile);
ResponseEntity<List<Map<String, Object>>> response = editTableOfContentsController.extractBookmarks(mockFile);
// Then
assertNotNull(result);
assertNotNull(response);
assertNotNull(response.getBody());
List<Map<String, Object>> result = response.getBody();
assertEquals(1, result.size());
Map<String, Object> parentBookmark = result.get(0);
@@ -177,10 +183,12 @@ class EditTableOfContentsControllerTest {
when(mockOutlineItem.getNextSibling()).thenReturn(null);
// When
List<Map<String, Object>> result = editTableOfContentsController.extractBookmarks(mockFile);
ResponseEntity<List<Map<String, Object>>> response = editTableOfContentsController.extractBookmarks(mockFile);
// Then
assertNotNull(result);
assertNotNull(response);
assertNotNull(response.getBody());
List<Map<String, Object>> result = response.getBody();
assertEquals(1, result.size());
Map<String, Object> bookmark = result.get(0);