From b7da84d2579e17c4c492b1f0745a901e10fce215 Mon Sep 17 00:00:00 2001 From: Omar Ahmed Hassan <98468609+omar-ahmed42@users.noreply.github.com> Date: Tue, 3 Dec 2024 10:28:34 +0200 Subject: [PATCH] Fix deserialization failure in Change Metadata (#2382) * Fix deserialization failure from String to Map Fix deserialization failure from String to Map that caused the following exception: Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public org.springframework.http.ResponseEntity stirling.software.SPDF.controller.api.misc.MetadataController.metadata(stirling.software.SPDF.model.api.misc.MetadataRequest) throws java.io.IOException: [Field error in object 'metadataRequest' on field 'allRequestParams': rejected value [{"customKey1" : "YourCustomKey", "customKeyValue1", "YourCustomValue"}]; codes [typeMismatch.metadataRequest.allRequestParams,typeMismatch.allRequestParams,typeMismatch.java.util.Map,typeMismatch]; * Fix form binding for dynamic Map entries in Change Metadata - Implemented support for dynamic key-value inputs in Change Metadata form using proper `name` attributes for Map (`allRequestParams`) binding. - Fix form binding for dynamic Map (`allRequestParams`) entries in Change Metadata as the `allRequestParams` (Map name) was being sent as an empty map. --- .../api/misc/MetadataController.java | 8 ++++++ .../StringToMapPropertyEditor.java | 26 +++++++++++++++++++ .../templates/misc/change-metadata.html | 4 +-- 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 src/main/java/stirling/software/SPDF/utils/propertyeditor/StringToMapPropertyEditor.java diff --git a/src/main/java/stirling/software/SPDF/controller/api/misc/MetadataController.java b/src/main/java/stirling/software/SPDF/controller/api/misc/MetadataController.java index 4d51e0f8..274bea10 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/misc/MetadataController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/misc/MetadataController.java @@ -14,6 +14,8 @@ import org.apache.pdfbox.pdmodel.PDDocumentInformation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -26,6 +28,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import stirling.software.SPDF.model.api.misc.MetadataRequest; import stirling.software.SPDF.utils.WebResponseUtils; +import stirling.software.SPDF.utils.propertyeditor.StringToMapPropertyEditor; @RestController @RequestMapping("/api/v1/misc") @@ -44,6 +47,11 @@ public class MetadataController { return entry; } + @InitBinder + public void initBinder(WebDataBinder binder) { + binder.registerCustomEditor(Map.class, "allRequestParams", new StringToMapPropertyEditor()); + } + @PostMapping(consumes = "multipart/form-data", value = "/update-metadata") @Operation( summary = "Update metadata of a PDF file", diff --git a/src/main/java/stirling/software/SPDF/utils/propertyeditor/StringToMapPropertyEditor.java b/src/main/java/stirling/software/SPDF/utils/propertyeditor/StringToMapPropertyEditor.java new file mode 100644 index 00000000..6c3135e8 --- /dev/null +++ b/src/main/java/stirling/software/SPDF/utils/propertyeditor/StringToMapPropertyEditor.java @@ -0,0 +1,26 @@ +package stirling.software.SPDF.utils.propertyeditor; + +import java.beans.PropertyEditorSupport; +import java.util.HashMap; +import java.util.Map; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class StringToMapPropertyEditor extends PropertyEditorSupport { + + private final ObjectMapper objectMapper = new ObjectMapper(); + + @Override + public void setAsText(String text) throws IllegalArgumentException { + try { + TypeReference> typeRef = + new TypeReference>() {}; + Map map = objectMapper.readValue(text, typeRef); + setValue(map); + } catch (Exception e) { + throw new IllegalArgumentException( + "Failed to convert java.lang.String to java.util.Map"); + } + } +} diff --git a/src/main/resources/templates/misc/change-metadata.html b/src/main/resources/templates/misc/change-metadata.html index c056b757..50ba318b 100644 --- a/src/main/resources/templates/misc/change-metadata.html +++ b/src/main/resources/templates/misc/change-metadata.html @@ -164,13 +164,13 @@ keyInput.type = "text"; keyInput.placeholder = 'Key'; keyInput.className = "form-control"; - keyInput.name = "customKey" + count; + keyInput.name = `allRequestParams[customKey${count}]`; const valueInput = document.createElement("input"); valueInput.type = "text"; valueInput.placeholder = 'Value'; valueInput.className = "form-control"; - valueInput.name = "customValue" + count; + valueInput.name = `allRequestParams[customValue${count}]`; count = count + 1; const formGroup = document.createElement("div");