Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Merge PDFs with API call #2502

Open
1 task done
hal-berto opened this issue Dec 19, 2024 · 3 comments
Open
1 task done

[Bug]: Merge PDFs with API call #2502

hal-berto opened this issue Dec 19, 2024 · 3 comments
Labels
API API-related issues or pull requests Done

Comments

@hal-berto
Copy link

Installation Method

None

The Problem

Greetings,
I'm trying to implement a call to StirlingPDF APIs to merge different PDF documents (I'm referring to API /general/merge-pdfs).
I tried with the following cURL calls:

curl -X 'POST'
'https://stirlingpdf.io/api/v1/general/merge-pdfs'
-H 'accept: /'
-H 'Content-Type: multipart/form-data'
-F 'fileInput=path_to_file_1.pdf'
-F 'fileInput=path_to_file_2.pdf'
-F 'sortType=orderProvided'
-F 'removeCertSign=true'

and this variation:

curl -X 'POST'
'https://stirlingpdf.io/api/v1/general/merge-pdfs'
-H 'accept: /'
-H 'Content-Type: multipart/form-data'
-F 'fileInput[]=path_to_file_1.pdf'
-F 'fileInput[]=path_to_file_2.pdf'
-F 'sortType=orderProvided'
-F 'removeCertSign=true'

In both cases I receive an error:

"Bad Request","exception":"org.springframework.web.bind.MethodArgumentNotValidException","trace":"org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public org.springframework.http.ResponseEntity<byte[]> stirling.software.SPDF.controller.api.MergeController.mergePdfs(stirling.software.SPDF.model.api.general.MergePdfsRequest) throws java.io.IOException: [Field error in object 'mergePdfsRequest' on field 'fileInput': rejected value [Array]; codes [typeMismatch.mergePdfsRequest.fileInput,typeMismatch.fileInput,typeMismatch.[Lorg.springframework.web.multipart.MultipartFile;,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [mergePdfsRequest.fileInput,fileInput]; arguments []; default message [fileInput]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'org.springframework.web.multipart.MultipartFile[]' for property 'fileInput'; Cannot convert value of type 'java.lang.String' to required type 'org.springframework.web.multipart.MultipartFile' for property 'fileInput[0]': no matching editors or conversion strategy found]

I know for sure that the file path is correct, since I succesfully called other StirlingPDF APIs with the same path.
Is there something wrong with my cURL?

Version of Stirling-PDF

0.36.4

Last Working Version of Stirling-PDF

No response

Page Where the Problem Occurred

No response

Docker Configuration

No response

Relevant Log Output

"Bad Request","exception":"org.springframework.web.bind.MethodArgumentNotValidException","trace":"org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public org.springframework.http.ResponseEntity<byte[]> stirling.software.SPDF.controller.api.MergeController.mergePdfs(stirling.software.SPDF.model.api.general.MergePdfsRequest) throws java.io.IOException: [Field error in object 'mergePdfsRequest' on field 'fileInput': rejected value [Array]; codes [typeMismatch.mergePdfsRequest.fileInput,typeMismatch.fileInput,typeMismatch.[Lorg.springframework.web.multipart.MultipartFile;,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [mergePdfsRequest.fileInput,fileInput]; arguments []; default message [fileInput]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'org.springframework.web.multipart.MultipartFile[]' for property 'fileInput'; Cannot convert value of type 'java.lang.String' to required type 'org.springframework.web.multipart.MultipartFile' for property 'fileInput[0]': no matching editors or conversion strategy found]] \\n\\tat org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:158)\\n\\tat org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:122)\\n\\tat org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:224)\\n\\tat org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:178)\\n\\tat org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)\\n\\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:986)\\n\\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:891)\\n\\tat org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)\\n\\tat org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1088)\\n\\tat org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:978)\\n\\tat org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)\\n\\tat org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914)\\n\\tat jakarta.servlet.http.HttpServlet.service(HttpServlet.java:547)\\n\\tat org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)\\n\\tat jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614)\\n\\tat org.eclipse.jetty.ee10.servlet.ServletHolder.handle(ServletHolder.java:736)\\n\\tat org.eclipse.jetty.ee10.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1614)\\n\\tat org.eclipse.jetty.ee10.websocket.servlet.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:195)\\n\\tat org.eclipse.jetty.ee10.servlet.FilterHolder.doFilter(FilterHolder.java:205)\\n\\tat org.eclipse.jetty.ee10.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1586)\\n\\tat stirling.software.SPDF.config.security.IPRateLimitingFilter.doFilter(IPRateLimitingFilter.java:62)\\n\\tat org.eclipse.jetty.ee10.servlet.FilterHolder.doFilter(FilterHolder.java:205)\\n\\tat org.eclipse.jetty.ee10.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1586)\\n\\tat stirling.software.SPDF.config.security.UserBasedRateLimitingFilter.doFilterInternal(UserBasedRateLimitingFilter.java:48)\\n\\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)\\n\\tat org.eclipse.jetty.ee10.servlet.FilterHolder.doFilter(FilterHolder.java:205)\\n\\tat org.eclipse.jetty.ee10.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1586)\\n\\tat stirling.software.SPDF.config.security.UserAuthenticationFilter.doFilterInternal(UserAuthenticationFilter.java:53)\\n\\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)\\n\\tat org.eclipse.jetty.ee10.servlet.FilterHolder.doFilter(FilterHolder.java:205)\\n\\tat org.eclipse.jetty.ee10.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1586)\\n\\tat stirling.software.SPDF.config.security.FirstLoginFilter.doFilterInternal(FirstLoginFilter.java:74)\\n\\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)\\n\\tat org.eclipse.jetty.ee10.servlet.FilterHolder.doFilter(FilterHolder.java:205)\\n\\tat org.eclipse.jetty.ee10.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1586)\\n\\tat stirling.software.SPDF.config.MetricsFilter.doFilterInternal(MetricsFilter.java:48)\\n\\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)\\n\\tat org.eclipse.jetty.ee10.servlet.FilterHolder.doFilter(FilterHolder.java:205)\\n\\tat org.eclipse.jetty.ee10.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1586)\\n\\tat org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:108)\\n\\tat org.springframework.security.web.FilterChainProxy.lambda$doFilterInternal$3(FilterChainProxy.java:231)\\n\\tat org.springframework.security.web.ObservationFilterChainDecorator$FilterObservation$SimpleFilterObservation.lambda$wrap$1(ObservationFilterChainDecorator.java:479)\\n\\tat org.springframework.security.web.ObservationFilterChainDecorator$AroundFilterObservation$SimpleAroundFilterObservation.lambda$wrap$1(ObservationFilterChainDecorator.java:340)\\n\\tat org.springframework.security.web.ObservationFilterChainDecorator.lambda$wrapSecured$0(ObservationFilterChainDecorator.java:82)\\n\\tat org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:128)\\n\\tat org.springframework.security.web.access.intercept.AuthorizationFilter.doFilter(AuthorizationFilter.java:101)\\n\\tat org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240)\\n\\tat org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227)\\n\\tat org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137)\\n\\tat org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:126)\\n\\tat org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:120)\\n\\tat org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240)\\n\\tat org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227)\\n\\tat org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137)\\n\\tat org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:100)\\n\\tat org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240)\\n\\tat org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227)\\n\\tat org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137)\\n\\tat org.springframework.security.web.servletapi.SecurityContextHolderAware

Additional Information

No response

Browsers Affected

No response

No Duplicate of the Issue

  • I have verified that there are no existing issues raised related to my problem.
@dosubot dosubot bot added the needs investigation Issues that require further investigation label Dec 19, 2024
Copy link

dosubot bot commented Dec 19, 2024

Hey @hal-berto! I'm here to help you with any bugs, questions, or contributions. Let's work together to resolve this issue.

The error you're encountering suggests that the fileInput field is not being correctly interpreted as an array of MultipartFile objects. In your cURL request, you should ensure that each file is specified correctly as a file upload. Here's how you can structure your cURL command to properly send multiple files:

curl -X POST \
  'https://stirlingpdf.io/api/v1/general/merge-pdfs' \
  -H 'accept: */*' \
  -H 'Content-Type: multipart/form-data' \
  -F 'fileInput=@path_to_file_1.pdf' \
  -F 'fileInput=@path_to_file_2.pdf' \
  -F 'sortType=orderProvided' \
  -F 'isRemoveCertSign=true' \
  -H 'Authorization: Bearer YOUR_API_KEY'

Key points to note:

  • Use @ before the file path to indicate that the file should be uploaded.
  • Ensure that you include the Authorization header with a valid API key, as the StirlingPDF API requires authentication [1].

Make sure to replace YOUR_API_KEY with your actual API key. This should help resolve the issue with the fileInput field not being recognized correctly.

To continue talking to Dosu, mention @dosu.


Help Dosu learn! Give it feedback: Great Response | Irrelevant Answer | Incorrect Sources | Too Verbose | Hallucination | Other

@Ludy87
Copy link
Contributor

Ludy87 commented Dec 19, 2024

Hi @hal-berto try this:

windows prompt

curl -X POST "http://127.0.0.1:8080/api/v1/general/merge-pdfs" ^
-H "accept: */*" ^
-H "Content-Type: multipart/form-data" ^
-F "fileInput=@path_to_file_1.pdf" ^
-F "fileInput=@path_to_file_2.pdf" ^
-F "sortType=orderProvided" ^
-F "removeCertSign=false" ^
--output path_to_file_3.pdf

linux terminal

curl -X POST "http://127.0.0.1:8080/api/v1/general/merge-pdfs" \
-H "accept: */*" \
-H "Content-Type: multipart/form-data" \
-F "fileInput=@path_to_file_1.pdf" \
-F "fileInput=@path_to_file_2.pdf" \
-F "sortType=orderProvided" \
-F "removeCertSign=false" \
--output @path_to_file_3.pdf

@Ludy87 Ludy87 added API API-related issues or pull requests and removed needs investigation Issues that require further investigation labels Dec 19, 2024
@hal-berto
Copy link
Author

Many thanks. The missing part was the "@" character before the file path. Now it's working properly

@Ludy87 Ludy87 added the Done label Dec 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API API-related issues or pull requests Done
Projects
None yet
Development

No branches or pull requests

2 participants