mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-11-16 01:21:16 +01: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