mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-09-08 17:51:20 +02:00
fix(api): prevent MultipartFile
binding errors in StampController
(#4331)
# Description of Changes - **What was changed** - Added a Spring `@InitBinder` in `StampController` that registers a `PropertyEditorSupport` for `MultipartFile` to safely handle text inputs by setting the value to `null`. - Replaced multiple `switch` statements with modern Java **switch expressions**: - Margin selection (`customMargin`) now uses a concise expression. - Font selection (`alphabet` → font resource path) rewritten as an expression. - Position calculations (`calculatePositionX` / `calculatePositionY`) now return via switch expressions with `yield`. - Minor readability and maintainability improvements without changing public API or behavior (besides the binding fix). - **Why the change was made** - The `@InitBinder` prevents conversion/binding issues when Spring attempts to map string form fields to `MultipartFile`, which could cause exceptions or unexpected behavior in multipart/form-data requests. - Using switch expressions reduces boilerplate, clarifies intent, and makes the control flow safer and more maintainable. --- ## Checklist ### General - [x] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [x] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md) (if applicable) - [x] I have performed a self-review of my own code - [x] My changes generate no new warnings ### Documentation - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### UI Changes (if applicable) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing) for more details.
This commit is contained in:
parent
6f6f4a14dc
commit
a4a57cef92
@ -2,6 +2,7 @@ package stirling.software.SPDF.controller.api.misc;
|
|||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.beans.PropertyEditorSupport;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -25,6 +26,8 @@ import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
|
|||||||
import org.apache.pdfbox.util.Matrix;
|
import org.apache.pdfbox.util.Matrix;
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.http.ResponseEntity;
|
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.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
@ -52,6 +55,24 @@ public class StampController {
|
|||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
private final TempFileManager tempFileManager;
|
private final TempFileManager tempFileManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize data binder for multipart file uploads.
|
||||||
|
* This method registers a custom editor for MultipartFile to handle file uploads.
|
||||||
|
* It sets the MultipartFile to null if the uploaded file is empty.
|
||||||
|
* This is necessary to avoid binding errors when the file is not present.
|
||||||
|
*/
|
||||||
|
@InitBinder
|
||||||
|
public void initBinder(WebDataBinder binder) {
|
||||||
|
binder.registerCustomEditor(
|
||||||
|
MultipartFile.class,
|
||||||
|
new PropertyEditorSupport() {
|
||||||
|
@Override
|
||||||
|
public void setAsText(String text) throws IllegalArgumentException {
|
||||||
|
setValue(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/add-stamp")
|
@PostMapping(consumes = "multipart/form-data", value = "/add-stamp")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Add stamp to a PDF file",
|
summary = "Add stamp to a PDF file",
|
||||||
@ -91,25 +112,14 @@ public class StampController {
|
|||||||
float overrideY = request.getOverrideY(); // New field for Y override
|
float overrideY = request.getOverrideY(); // New field for Y override
|
||||||
|
|
||||||
String customColor = request.getCustomColor();
|
String customColor = request.getCustomColor();
|
||||||
float marginFactor;
|
float marginFactor =
|
||||||
|
switch (request.getCustomMargin().toLowerCase()) {
|
||||||
switch (request.getCustomMargin().toLowerCase()) {
|
case "small" -> 0.02f;
|
||||||
case "small":
|
case "medium" -> 0.035f;
|
||||||
marginFactor = 0.02f;
|
case "large" -> 0.05f;
|
||||||
break;
|
case "x-large" -> 0.075f;
|
||||||
case "medium":
|
default -> 0.035f;
|
||||||
marginFactor = 0.035f;
|
};
|
||||||
break;
|
|
||||||
case "large":
|
|
||||||
marginFactor = 0.05f;
|
|
||||||
break;
|
|
||||||
case "x-large":
|
|
||||||
marginFactor = 0.075f;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
marginFactor = 0.035f;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load the input PDF
|
// Load the input PDF
|
||||||
PDDocument document = pdfDocumentFactory.load(pdfFile);
|
PDDocument document = pdfDocumentFactory.load(pdfFile);
|
||||||
@ -185,27 +195,16 @@ public class StampController {
|
|||||||
throws IOException {
|
throws IOException {
|
||||||
String resourceDir = "";
|
String resourceDir = "";
|
||||||
PDFont font = new PDType1Font(Standard14Fonts.FontName.HELVETICA);
|
PDFont font = new PDType1Font(Standard14Fonts.FontName.HELVETICA);
|
||||||
switch (alphabet) {
|
resourceDir =
|
||||||
case "arabic":
|
switch (alphabet) {
|
||||||
resourceDir = "static/fonts/NotoSansArabic-Regular.ttf";
|
case "arabic" -> "static/fonts/NotoSansArabic-Regular.ttf";
|
||||||
break;
|
case "japanese" -> "static/fonts/Meiryo.ttf";
|
||||||
case "japanese":
|
case "korean" -> "static/fonts/malgun.ttf";
|
||||||
resourceDir = "static/fonts/Meiryo.ttf";
|
case "chinese" -> "static/fonts/SimSun.ttf";
|
||||||
break;
|
case "thai" -> "static/fonts/NotoSansThai-Regular.ttf";
|
||||||
case "korean":
|
case "roman" -> "static/fonts/NotoSans-Regular.ttf";
|
||||||
resourceDir = "static/fonts/malgun.ttf";
|
default -> "static/fonts/NotoSans-Regular.ttf";
|
||||||
break;
|
};
|
||||||
case "chinese":
|
|
||||||
resourceDir = "static/fonts/SimSun.ttf";
|
|
||||||
break;
|
|
||||||
case "thai":
|
|
||||||
resourceDir = "static/fonts/NotoSansThai-Regular.ttf";
|
|
||||||
break;
|
|
||||||
case "roman":
|
|
||||||
default:
|
|
||||||
resourceDir = "static/fonts/NotoSans-Regular.ttf";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!"".equals(resourceDir)) {
|
if (!"".equals(resourceDir)) {
|
||||||
ClassPathResource classPathResource = new ClassPathResource(resourceDir);
|
ClassPathResource classPathResource = new ClassPathResource(resourceDir);
|
||||||
@ -327,30 +326,30 @@ public class StampController {
|
|||||||
throws IOException {
|
throws IOException {
|
||||||
float actualWidth =
|
float actualWidth =
|
||||||
(text != null) ? calculateTextWidth(text, font, fontSize) : contentWidth;
|
(text != null) ? calculateTextWidth(text, font, fontSize) : contentWidth;
|
||||||
switch (position % 3) {
|
return switch (position % 3) {
|
||||||
case 1: // Left
|
case 1: // Left
|
||||||
return pageSize.getLowerLeftX() + margin;
|
yield pageSize.getLowerLeftX() + margin;
|
||||||
case 2: // Center
|
case 2: // Center
|
||||||
return (pageSize.getWidth() - actualWidth) / 2;
|
yield (pageSize.getWidth() - actualWidth) / 2;
|
||||||
case 0: // Right
|
case 0: // Right
|
||||||
return pageSize.getUpperRightX() - actualWidth - margin;
|
yield pageSize.getUpperRightX() - actualWidth - margin;
|
||||||
default:
|
default:
|
||||||
return 0;
|
yield 0;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private float calculatePositionY(
|
private float calculatePositionY(
|
||||||
PDRectangle pageSize, int position, float height, float margin) {
|
PDRectangle pageSize, int position, float height, float margin) {
|
||||||
switch ((position - 1) / 3) {
|
return switch ((position - 1) / 3) {
|
||||||
case 0: // Top
|
case 0: // Top
|
||||||
return pageSize.getUpperRightY() - height - margin;
|
yield pageSize.getUpperRightY() - height - margin;
|
||||||
case 1: // Middle
|
case 1: // Middle
|
||||||
return (pageSize.getHeight() - height) / 2;
|
yield (pageSize.getHeight() - height) / 2;
|
||||||
case 2: // Bottom
|
case 2: // Bottom
|
||||||
return pageSize.getLowerLeftY() + margin;
|
yield pageSize.getLowerLeftY() + margin;
|
||||||
default:
|
default:
|
||||||
return 0;
|
yield 0;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private float calculateTextWidth(String text, PDFont font, float fontSize) throws IOException {
|
private float calculateTextWidth(String text, PDFont font, float fontSize) throws IOException {
|
||||||
|
Loading…
Reference in New Issue
Block a user