Hi Andriy,

When looking at the classes MultipartProvider and JAXRSUtils (cxf v3.5.9)
then it shows that only object for which a 'Content-Disposition' header will
be written is a File Object. The problem is that my application is
generating the file content on the fly, so I have it either as a byte[] or
InputStream.
This surprises me as according to
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition:
"a multipart/form-data body requires a Content-Disposition header to provide
information about each subpart of the form (e.g., for every form field and
any files that are part of field data)".
Also the Multipart annotation class only allows to specify Content-Type,
Content-ID so there is no way for me to provide 'Content-Disposition'
information on objects like byte[] or InputStream.

Even passing a List<Attachment> doesn't work as the MultiPartProvider will
loop through the list and try to create a DataHandler for an Attachment
object which is also not supported (throws an exception).
The only way I see to pass it is to construct Attachment objects for each
multipart part, with 'Content-Disposition' set, and add them all to a
MultipartBody object and pass this as input parameter to my method
signature. But then I loose all swager information for input objects that
are not byte[] or InputStream.

Am I missing something?

Regards,

J.P.

-----Oorspronkelijk bericht-----
Van: Andriy Redko <drr...@gmail.com>
Verzonden: vrijdag 4 oktober 2024 2:52
Aan: Jean Pierre URKENS <jean-pierre.urk...@devoteam.com>;
dev@cxf.apache.org
Onderwerp: Re: CXF JAX-RS: working with multipart form-data

Hi Jean,

Yeah, I think the @Multipart + Attachment may not work, but you could accept
the List<Attachment> instead, right? (since you send many).

The logging configuration does not seem right: you use interceptors AND
feature (as per snippet below).

                 factory.getOutInterceptors().add(new
LoggingOutInterceptor());
                 factory.getInInterceptors().add(new
LoggingInInterceptor());
                 LoggingFeature feature = new LoggingFeature();
                 feature.setLogMultipart(true);
                 feature.setLogBinary(true);
                 ...

You only need one of those, either interceptors (please configure
setLogBinary & setLogMultipart for them):

                 factory.getOutInterceptors().add(new
LoggingOutInterceptor());
                 factory.getInInterceptors().add(new
LoggingInInterceptor());

Or feature:
                 LoggingFeature feature = new LoggingFeature();
                 feature.setLogMultipart(true);
                 feature.setLogBinary(true);
                 ...

Hope it helps, thanks!

Best Regards,
    Andriy Redko


JPU> Hi Andriy,

JPU> Thanks for the swift response, but I could still use some
clarifications on:

JPU> 1) You mention that passing an Attachment object as service method
JPU> parameter should work.
JPU>     My initial test setup did pass an Attachment object as input
JPU> parameter
as shown in ">> 1)API interface declaration" in my mail. However when the
JPU> client (see code below) tries to send a request with this
JPU> signature, the
JPU> JAXRSUtils.writeMessageBody(...) method that is called by the CXF
JPU> stack throws an exception on the Attachment parameter saying:

JPU>         okt 03, 2024 9:46:54 AM
JPU> org.apache.cxf.jaxrs.provider.MultipartProvider
JPU> getHandlerForObject SEVERE: No message body writer found for class
JPU> : class org.apache.cxf.jaxrs.ext.multipart.Attachment.
JPU>         okt 03, 2024 9:47:05 AM
JPU> org.apache.cxf.jaxrs.utils.JAXRSUtils
JPU> logMessageHandlerProblem SEVERE: Problem with writing the data,
JPU> class java.util.ArrayList, ContentType: multipart/form-data
JPU>         okt 03, 2024 9:47:14 AM
JPU> org.apache.cxf.phase.PhaseInterceptorChain
JPU> doDefaultLogging WARNING: Interceptor for
JPU> {http://api.documenten.magda.common.aeo.dvtm.be/}MessagesApi has
JPU> thrown exception, unwinding now
JPU>                 org.apache.cxf.interceptor.Fault: Problem with
JPU> writing the data, class java.util.ArrayList, ContentType:
multipart/form-data
JPU>                 at
JPU>
org.apache.cxf.jaxrs.client.ClientProxyImpl$BodyWriter.doWriteBody(ClientProxyImpl.java:1142)
JPU>                 at
JPU> org.apache.cxf.jaxrs.client.AbstractClient$AbstractBodyWriter.handl
JPU> eMessage(AbstractClient.java:1223)

JPU> The JAXRSUtils.writeMessageBody(...) method takes an 'entity'
JPU> Object that is a List<Attachment>. The first Attachment in the list
JPU> contains an object of type MessageToSend, while the second one
JPU> contains an object of type Attachment for which 'no message body
writer' could be found.
JPU> The stack creates itself an Attachment object for each parameter of
JPU> the multipart body, that is why I though that I can not pass it as
JPU> a parameter to my service method. I guess I am not allowed to annotate
an 'Attachment'
JPU> parameter with @Multipart annotation as currently done in the
JPU> method
JPU> signature:

JPU>         @FormDataParam(value="upfile1") @Parameter(schema =
JPU> @Schema(type = "string", format = "binary")) @Multipart(value =
JPU> "upfile1", type="application/pdf", required = false) Attachment
JPU> upfile1Detail

JPU> However leaving the @Multipart annotation for the Attachment
JPU> parameter away leads to the error:

JPU>         javax.ws.rs.ProcessingException: Resource method
JPU> be.dvtm.aeo.common.magda.documenten.api.MessagesApi.createMessage2
JPU> has more than one parameter representing a request body

JPU> I.e. now it is no longer clear that the Attachment parameter is
JPU> part of the 'multipart'. That's why I switched to using an
JPU> InputStream as parameter with @Multipart annotation but then I loose
the Content-Disposition information.
JPU> The @Multipart annotation doesn't allow to specify
JPU> Content-Disposition information. Is there an alternative here?

JPU> 2) Logging of Binary Data. I create my client with:
JPU>         private static MessagesApi getThreadsafeProxy(String
baseAddress) {
JPU>                 JacksonJsonProvider jjProvider = new
JPU> JacksonJsonProvider(new CustomObjectMapper());
JPU>                 List<Object> providers = Arrays.asList(new
JPU> MultipartProvider(), jjProvider);
JPU>                 final JAXRSClientFactoryBean factory = new
JAXRSClientFactoryBean();
JPU>                 factory.setAddress(baseAddress);
JPU>                 factory.setServiceClass(MessagesApi.class);
JPU>                 factory.setProviders(providers);
JPU>                 factory.getOutInterceptors().add(new
LoggingOutInterceptor());
JPU>                 factory.getInInterceptors().add(new
LoggingInInterceptor());
JPU>                 factory.setThreadSafe(true);
JPU>                 LoggingFeature feature = new LoggingFeature();
JPU>                 feature.setLogMultipart(true);
JPU>                 feature.setLogBinary(true);
JPU>
feature.addBinaryContentMediaTypes(MediaType.APPLICATION_OCTET_STREAM);
JPU>                 feature.addBinaryContentMediaTypes("application/pdf");
JPU>                 factory.setFeatures(Arrays.asList(feature));
JPU>                 MessagesApi api = factory.create(MessagesApi.class);
JPU>                 ClientConfiguration config = WebClient.getConfig(api);
JPU>                 addTLSClientParameters(config.getHttpConduit());
JPU>                 return api;
JPU>         }
JPU>  Here I do activate the logging for multipart and binary and also
JPU> added some mediatypes (although couldn't find what it actually
JPU> does). So I was expecting to see the whole message (attachments are
JPU> rather small as it is a test).
JPU>  Well I used wireshark to get the full message and it doesn't show
JPU> any Content-Disposition headers for the multipart elements.

JPU> Regards,

JPU> J.P. Urkens

JPU> -----Original Message-----
JPU> From: Andriy Redko <drr...@gmail.com>
JPU> Sent: donderdag 3 oktober 2024 1:01
JPU> To: Jean Pierre URKENS <jean-pierre.urk...@devoteam.com>;
JPU> dev@cxf.apache.org
JPU> Subject: Re: CXF JAX-RS: working with multipart form-data

JPU> Hi Jean,

JPU>> What is the correct way to annotate a file attachment as part of a
JPU>> mutlipart/form-data content body?

JPU> We have many examples in our test suites over here [1], it really
JPU> depends on the problem at hand.

JPU>>         -> Question-01: Is this the appropriate way to pass files
JPU>> (PDF documents) as attachment in a mutlipart/form-data request, or
JPU>> are
JPU> there better ways?

JPU> You would probably better of with "multipart/mixed" [2] as in you
JPU> case, you are sending different data types. But
JPU> "multipart/form-data" should be fine as well. The right answer
JPU> answer depends on how large the files are. In many cases you are
JPU> better off using chunked transfer (no need to read the whole file in
memory), like you do with InputStream.

JPU>>         -> Question-02: When I activate logging, I can't see
JPU>> anything about the file attachment, not is content, nor the
JPU>> appropriate Content-Disposition settings? I get '--Content
JPU> suppressed--', e.g.:

JPU> Correct, by default the logging interceptors do not log binary
JPU> data, you could checks the docs here [3].

JPU>>         -> Question-03: Don't I need to set anything regarding the
JPU>> Content-Disposition header? The example here is simplified in a
JPU>> sense that I used a test setup with just one file attachment. In
JPU>> the real interface up to
JPU>> 20 attachments can be passed. Somehow I need to know which part
JPU>> relates
JPU> to
JPU>> which                   attachment or not?

JPU> This is probably caused by the fact you are sending the InputStream
JPU> and not an Attachment, if my understanding is correct. I am pretty
JPU> sure passing the Attachment (as you did initially) should work.

JPU>>         -> Question-04: At the server implemtation side, since
JPU>> upfile1Detail is passed as a method parameter, who is going to
JPU>> close this InputStream at the server side?

JPU> The stream should be closed by the service implementation (since
JPU> the stream is expected to be consumed). The Apache CXF runtime will
JPU> try to close the stream in most cases as well but sometimes it may not
be able to.

JPU> Hope it answers your questions. Thanks!

JPU> [1]
JPU> https://github.com/apache/cxf/blob/main/systests/jaxrs/src/test/jav
JPU> a/org/apache/cxf/systest/jaxrs/MultipartStore.java
JPU> [2]
JPU> https://learn.microsoft.com/en-us/exchange/troubleshoot/administrat
JPU> ion/multipart-mixed-mime-message-format
JPU> [3] https://cxf.apache.org/docs/message-logging.html

JPU> Best Regards,
JPU>     Andriy Redko


JPU>> Hi Andriy,

JPU>> What is the correct way to annotate a file attachment as part of a
JPU>> mutlipart/form-data content body?
JPU>> I currently have the following (only the relevant parts):

JPU>> 1)API interface declaration
JPU>> ======================
JPU>>         @POST
JPU>>         @Path("/messages1")
JPU>>         @Consumes("multipart/form-data")
JPU>>         @Produces({ "application/json" })
JPU>>         @Operation(...)
JPU>>         @ApiResponses(...)
JPU>>         Response createMessage1(
JPU>>                         @HeaderParam("x-correlation-id") @NotNull
JPU>> @Size(min = 10, max = 36) @Parameter(description="ID of the
JPU>> transaction. Use this ID for log tracing and incident handling.")
JPU> String xCorrelationId,
JPU>>                         @HeaderParam("Idempotency-Key") @NotNull
JPU>> @Size(min = 10, max = 36) @Parameter(description="When retrying a
JPU>> failed call, the retry call should have the same Idempotency
JPU>> Key.")
JPU> String idempotencyKey,
JPU>>                         @FormDataParam(value="messageToSend")
JPU>> @Parameter(required=true,schema =
JPU>> @Schema(implementation=MessageToSend.class)) @Multipart(value =
JPU>> "messageToSend", type="application/json", required= true)
JPU>> MessageToSend messageToSend,
JPU>>                         @FormDataParam(value="upfile1")
JPU>> @Parameter(schema = @Schema(type = "string", format = "binary"))
JPU>> @Multipart(value = "upfile1", type="application/octet-stream",
JPU>> required = false) Attachment upfile1Detail);

JPU>> So I pass the file to upload as an Attachment object.

JPU>> 2)API client test code
JPU>> =================
JPU>>                 String xCorrelationId = UUID.randomUUID().toString();
JPU>>                 String idempotencyKey =
JPU>> UUID.randomUUID().toString();

JPU>>                 //01. Get the attachment to include
JPU>>                 String fileName = "test.pdf";
JPU>>                 try (InputStream is =
JPU>> this.getClass().getClassLoader().getResourceAsStream(fileName);
JPU>>                                  BufferedReader reader = new
JPU>> BufferedReader(new InputStreamReader(is))) {
JPU>>                         if (is == null) {
JPU>>                                 Assert.fail("Couldn't load
JPU>> test.pdf
JPU> from classpath!");
JPU>>                         }
JPU>>                         DataHandler dataHandler = new
JPU>> DataHandler(is,
JPU> "application/pdf");
JPU>>                         ContentDisposition cd = new
JPU>> ContentDisposition("attachment;name=upfile1;filename="+fileName);
JPU>>                         Attachment upfile1Detail = new
JPU> AttachmentBuilder()
JPU>>                                 .id("upfile1")
JPU>>                                 .dataHandler(dataHandler)
JPU>>                                 .contentDisposition(cd)
JPU>>                                 .mediaType("application/pdf")
JPU>>                                 .build();

JPU>>                 //02. create the message to send
JPU>>                 MessageToSend mts = new MessageToSend();

JPU>>                 //03. Call the server
JPU>>                 Response resp =
JPU>> apiClient.createMessage1(xCorrelationId, idempotencyKey, mts,
JPU>> upfile1Detail);


JPU>> When running the API client test code and getting at '03.' The method:
JPU>>         JAXRSUtils.writeMessageBody(List<WriterInterceptor>
JPU>> writers,Object entity,Class<?> type, Type genericType,Annotation[]
JPU>> annotations,MediaType mediaType,MultivaluedMap<String, Object>
JPU>> httpHeaders,Message message)

JPU>> is called. The 'entity' object is a list of Attachment objects where:
JPU>>  - the first Attachment object contains an object of type
JPU>> MessageToSend
JPU>>  - the second Attachment object contains an object of type
JPU>> Attachment

JPU>> This second object leads to a fatal error within the
JPU>> JAXRSUtils.writeMessageBody(...) method:
JPU>>         okt 02, 2024 1:36:02 PM
JPU>> org.apache.cxf.jaxrs.provider.MultipartProvider
JPU>> getHandlerForObject
JPU>>         SEVERE: No message body writer found for class : class
JPU>> org.apache.cxf.jaxrs.ext.multipart.Attachment.
JPU>>         okt 02, 2024 1:36:02 PM
JPU>> org.apache.cxf.jaxrs.utils.JAXRSUtils
JPU>> logMessageHandlerProblem
JPU>>         SEVERE: Problem with writing the data, class
JPU>> java.util.ArrayList,
JPU>> ContentType: multipart/form-data


JPU>> I  modified the interface and implementation classes to use
JPU>> 'InputStream upfile1Detail' as type for the input parameter of the
JPU>> service method. And in this case my 'dummy' server implementation
JPU>> can read the file and save it to disk.
JPU>>         -> Question-01: Is this the appropriate way to pass files
JPU>> (PDF documents) as attachment in a mutlipart/form-data request, or
JPU>> are
JPU> there better ways?
JPU>>         -> Question-02: When I activate logging, I can't see
JPU>> anything about the file attachment, not is content, nor the
JPU>> appropriate Content-Disposition settings? I get '--Content
JPU> suppressed--', e.g.:

JPU>>                 [MAGDADOC] 2024-10-02 14:29:08,911 [main] INFO
JPU>> $--$
JPU>> (org.apache.cxf.ext.logging.slf4j.Slf4jEventSender:84) - REQ_OUT
JPU>>                     Address:
JPU>> http://localhost:8091/services/magdadoc/api/v1/messages/messages1
JPU>>                     HttpMethod: POST
JPU>>                     Content-Type: multipart/form-data;
JPU>> boundary="uuid:3c3fa9c0-8470-4655-b026-3ed09f79e862"
JPU>>                     ExchangeId: a583a695-d881-4fa7-b65a-8961cdbbd412
JPU>>                     Headers: {Authorization=Bearer
JPU>> f4262ccf-3250-4bcf-a1bc-7ee1bf9a56cf,
JPU>> Accept=application/json,
JPU>> Idempotency-Key=bd06c05d-9fe2-4b60-b8db-5ad1121b74dc,
JPU>> x-correlation-id=511c51ba-95fe-4f69-9443-f05c377cffab}
JPU>>                     Payload:
JPU>>                 --uuid:3c3fa9c0-8470-4655-b026-3ed09f79e862
JPU>>                 Content-Type: application/json
JPU>>                 Content-Transfer-Encoding: binary
JPU>>                 Content-ID: <messageToSend>

JPU>>                 {
JPU>>                   "delivery" : "AUTOMATIC",
JPU>>                   "eboxDeliveryData" : { /* all fine */},
JPU>>                   "paperDeliveryData" : {/* all fine */},
JPU>>                   "emailDeliveryData" : null,
JPU>>                   "businessData" : [ ]
JPU>>                 }
JPU>>                 --uuid:3c3fa9c0-8470-4655-b026-3ed09f79e862
JPU>>                 --- Content suppressed ---

JPU>>         -> Question-03: Don't I need to set anything regarding the
JPU>> Content-Disposition header? The example here is simplified in a
JPU>> sense that I used a test setup with just one file attachment. In
JPU>> the real interface up to
JPU>> 20 attachments can be passed. Somehow I need to know which part
JPU>> relates
JPU> to
JPU>> which                   attachment or not?
JPU>>         -> Question-04: At the server implemtation side, since
JPU>> upfile1Detail is passed as a method parameter, who is going to
JPU>> close this InputStream at the server side?

JPU>> Regards,

JPU>> J.P. Urkens

JPU>> P.S.: Is there a migration document describing upgrading CXF-3.5.6
JPU>> (my current version) to CXF-3.5.8 (latest JDK8 version). I'd like
JPU>> to know whether upgrading can happen without too much burden.


JPU>> -----Original Message-----
JPU>> From: Jean Pierre URKENS <jean-pierre.urk...@devoteam.com>
JPU>> Sent: vrijdag 5 juli 2024 13:04
JPU>> To: 'Andriy Redko' <drr...@gmail.com>; 'dev@cxf.apache.org'
JPU>> <dev@cxf.apache.org>
JPU>> Subject: RE: CXF JAX-RS: working with multipart form-data

JPU>> Hi Andriy,

JPU>> When searching the net I came along this Jersey annotation but
JPU>> since I was not depending on 'Jersey' components I skipped it. So
JPU>> apparently swagger-core has processing for externally defined
JPU>> annotations (like this FormDataParam in Jersey), indeed inside
JPU> know-how.

JPU>> I included it in my project as
JPU>> io.swagger.v3.oas.annotations.FormDataParam,
JPU>> since it should somehow be included in the supported  swagger
JPU>> annotations (maybe we should submit a request for it to the
JPU>> swagger-core team) and this indeed generates an appropriate
JPU> openapi.json spec.

JPU>> Thanks alot,

JPU>> J.P. Urkens



JPU>> -----Original Message-----
JPU>> From: Andriy Redko <drr...@gmail.com>
JPU>> Sent: vrijdag 5 juli 2024 2:16
JPU>> To: Jean Pierre URKENS <jean-pierre.urk...@devoteam.com>;
JPU>> dev@cxf.apache.org
JPU>> Subject: Re: CXF JAX-RS: working with multipart form-data

JPU>> Hi Jean,

JPU>> Here is how you could make it work (there is some magic knowledge
JPU>> involved sadly). First of all, define such annotation anywhere in
JPU>> your codebase (where it dims appropriate):

JPU>> import java.lang.annotation.ElementType; import
JPU>> java.lang.annotation.Retention; import
JPU>> java.lang.annotation.RetentionPolicy;
JPU>> import java.lang.annotation.Target;

JPU>> @Target({ElementType.PARAMETER, ElementType.METHOD,
JPU>> ElementType.FIELD})
JPU>> @Retention(RetentionPolicy.RUNTIME)
JPU>> public @interface FormDataParam {
JPU>>     String value();
JPU>> }

JPU>> Use this annotation on each Attachment parameter:

JPU>> /* Skipping other annotations as those are not important here */
JPU>> public Response createMessage(
JPU>>          @HeaderParam("x-correlation-id") @NotNull @Size(min = 10,
JPU>> max = 36) @Parameter(description="ID of the transaction. Use this
JPU>> ID for log tracing and incident handling.") String xCorrelationId,
JPU>>          @HeaderParam("Idempotency-Key") @Size(min = 10, max = 36)
JPU>> @Parameter(description="When retrying a failed call, the retry
JPU>> call should have the same Idempotency Key.") String idempotencyKey,
JPU>>          @FormDataParam("upfile1") @Parameter(schema =
JPU>> @Schema(type = "string", format = "binary")) @Multipart(value =
JPU>> "upfile1", type="application/octet-stream", required = false)
JPU>> InputStream upfile1Detail,
JPU>>          @FormDataParam("upfile2") @Parameter(schema =
JPU>> @Schema(type = "string", format = "binary")) @Multipart(value =
JPU>> "upfile2", type="application/octet-stream", required = false)
JPU>> InputStream upfile2Detail,
JPU>>          @FormDataParam("upfile3") @Parameter(schema =
JPU>> @Schema(type = "string", format = "binary")) @Multipart(value =
JPU>> "upfile3", type="application/octet-stream", required = false)
JPU>> Attachment
JPU> upfile3Detail,
JPU>>          @FormDataParam("upfile4") @Parameter(schema =
JPU>> @Schema(type = "string", format = "binary")) @Multipart(value =
JPU>> "upfile4", type="application/octet-stream", required = false)
JPU>> Attachment
JPU> upfile4Detail,
JPU>>          @FormDataParam("upfile5") @Parameter(schema =
JPU>> @Schema(type = "string", format = "binary")) @Multipart(value =
JPU>> "upfile5", type="application/octet-stream", required = false)
JPU>> Attachment
JPU> upfile5Detail,
JPU>>          @FormDataParam("upfile6") @Parameter(schema =
JPU>> @Schema(type = "string", format = "binary")) @Multipart(value =
JPU>> "upfile6", type="application/octet-stream", required = false)
JPU>> Attachment
JPU> upfile6Detail,
JPU>>          @FormDataParam("upfile7") @Parameter(schema =
JPU>> @Schema(type = "string", format = "binary")) @Multipart(value =
JPU>> "upfile7", type="application/octet-stream", required = false)
JPU>> Attachment
JPU> upfile7Detail,
JPU>>          @FormDataParam("upfile8") @Parameter(schema =
JPU>> @Schema(type = "string", format = "binary")) @Multipart(value =
JPU>> "upfile8", type="application/octet-stream", required = false)
JPU>> Attachment
JPU> upfile8Detail,
JPU>>          @FormDataParam("upfile9") @Parameter(schema =
JPU>> @Schema(type = "string", format = "binary")) @Multipart(value =
JPU>> "upfile9", type="application/octet-stream", required = false)
JPU>> Attachment
JPU> upfile9Detail,
JPU>>          @FormDataParam("upfile10") @Parameter(schema =
JPU>> @Schema(type = "string", format = "binary")) @Multipart(value =
JPU>> "upfile10", type="application/octet-stream", required = false)
JPU>> Attachment upfile10Detail,
JPU>>          @FormDataParam("upfile11") @Parameter(schema =
JPU>> @Schema(type = "string", format = "binary")) @Multipart(value =
JPU>> "upfile11", type="application/octet-stream", required = false)
JPU>> Attachment upfile11Detail,
JPU>>          @FormDataParam("upfile12") @Parameter(schema =
JPU>> @Schema(type = "string", format = "binary")) @Multipart(value =
JPU>> "upfile12", type="application/octet-stream", required = false)
JPU>> Attachment upfile12Detail,
JPU>>          @FormDataParam("upfile13") @Parameter(schema =
JPU>> @Schema(type = "string", format = "binary")) @Multipart(value =
JPU>> "upfile13", type="application/octet-stream", required = false)
JPU>> Attachment upfile13Detail,
JPU>>          @FormDataParam("upfile14") @Parameter(schema =
JPU>> @Schema(type = "string", format = "binary")) @Multipart(value =
JPU>> "upfile14", type="application/octet-stream", required = false)
JPU>> Attachment upfile14Detail,
JPU>>          @FormDataParam("upfile15") @Parameter(schema =
JPU>> @Schema(type = "string", format = "binary")) @Multipart(value =
JPU>> "upfile15", type="application/octet-stream", required = false)
JPU>> Attachment upfile15Detail,
JPU>>          @FormDataParam("upfile16") @Parameter(schema =
JPU>> @Schema(type = "string", format = "binary")) @Multipart(value =
JPU>> "upfile16", type="application/octet-stream", required = false)
JPU>> Attachment upfile16Detail,
JPU>>          @FormDataParam("upfile17") @Parameter(schema =
JPU>> @Schema(type = "string", format = "binary")) @Multipart(value =
JPU>> "upfile17", type="application/octet-stream", required = false)
JPU>> Attachment upfile17Detail,
JPU>>          @FormDataParam("upfile18") @Parameter(schema =
JPU>> @Schema(type = "string", format = "binary")) @Multipart(value =
JPU>> "upfile18", type="application/octet-stream", required = false)
JPU>> Attachment upfile18Detail,
JPU>>          @FormDataParam("upfile19") @Parameter(schema =
JPU>> @Schema(type = "string", format = "binary")) @Multipart(value =
JPU>> "upfile19", type="application/octet-stream", required = false)
JPU>> Attachment upfile19Detail,
JPU>>          @FormDataParam("upfile20") @Parameter(schema =
JPU>> @Schema(type = "string", format = "binary")) @Multipart(value =
JPU>> "upfile20", type="application/octet-stream", required = false)
JPU>> Attachment upfile20Detail,
JPU>>          @FormDataParam("qrfile") @Parameter(schema = @Schema(type
JPU>> = "string", format = "binary")) @Multipart(value = "qrfile",
JPU>> type="application/octet-stream", required = false) Attachment
JPU> qrfileDetail
JPU>>      ) {
JPU>>  ....
JPU>> }

JPU>> With that, you will get a nice request body schema (publishing a
JPU>> bit large YAML snippet to preserve the context):

JPU>> paths:
JPU>>   /sample/messages:
JPU>>     post:
JPU>>       tags:
JPU>>       - messages
JPU>>       summary: "Send a message, using a channel (email, paper
JPU>> mail,
JPU>> ebox) and delivery\
JPU>>         \ method (registered or normal) of your choice. More than
JPU>> 6 upfiles only supported\
JPU>>         \ for PAPER delivery."
JPU>>       operationId: createMessage
JPU>>       parameters:
JPU>>       - name: x-correlation-id
JPU>>         in: header
JPU>>         description: ID of the transaction. Use this ID for log
JPU>> tracing and incident
JPU>>           handling.
JPU>>         required: true
JPU>>         schema:
JPU>>           maxLength: 36
JPU>>           minLength: 10
JPU>>           type: string
JPU>>       - name: Idempotency-Key
JPU>>         in: header
JPU>>         description: "When retrying a failed call, the retry call
JPU>> should have the\
JPU>>           \ same Idempotency Key."
JPU>>         schema:
JPU>>           maxLength: 36
JPU>>           minLength: 10
JPU>>           type: string
JPU>>       requestBody:
JPU>>         content:
JPU>>           multipart/form-data:
JPU>>             schema:
JPU>>               type: object
JPU>>               properties:
JPU>>                 upfile1:
JPU>>                   type: string
JPU>>                   format: binary
JPU>>                 upfile2:
JPU>>                   type: string
JPU>>                   format: binary
JPU>>                 upfile3:
JPU>>                   type: string
JPU>>                   format: binary
JPU>>                 upfile4:
JPU>>                   type: string
JPU>>                   format: binary
JPU>>                 upfile5:
JPU>>                   type: string
JPU>>                   format: binary
JPU>>                 upfile6:
JPU>>                   type: string
JPU>>                   format: binary
JPU>>                 upfile7:
JPU>>                   type: string
JPU>>                   format: binary
JPU>>                 upfile8:
JPU>>                   type: string
JPU>>                   format: binary
JPU>>                 upfile9:
JPU>>                   type: string
JPU>>                   format: binary
JPU>>                 upfile10:
JPU>>                   type: string
JPU>>                   format: binary
JPU>>                 upfile11:
JPU>>                   type: string
JPU>>                   format: binary
JPU>>                 upfile12:
JPU>>                   type: string
JPU>>                   format: binary
JPU>>                 upfile13:
JPU>>                   type: string
JPU>>                   format: binary
JPU>>                 upfile14:
JPU>>                   type: string
JPU>>                   format: binary
JPU>>                 upfile15:
JPU>>                   type: string
JPU>>                   format: binary
JPU>>                 upfile16:
JPU>>                   type: string
JPU>>                   format: binary
JPU>>                 upfile17:
JPU>>                   type: string
JPU>>                   format: binary
JPU>>                 upfile18:
JPU>>                   type: string
JPU>>                   format: binary
JPU>>                 upfile19:
JPU>>                   type: string
JPU>>                   format: binary
JPU>>                 upfile20:
JPU>>                   type: string
JPU>>                   format: binary
JPU>>                 qrfile:
JPU>>                   type: string
JPU>>                   format: binary

JPU>> The key here is @FormDataParam annotation which (originally) comes
JPU>> from Jersey but has special treatment in Swagger Core (but,
JPU>> likely, no attribution to Jersey).

JPU>> Hope it helps!
JPU>> Thank you.

JPU>> Best Regards,
JPU>>     Andriy Redko

>>> V2.2.22 (15/05/2024) is the latest version of io.swagger.core.v3
>>> libraries.
>>> I upgrade to this  version to make sure I had the latest swagger
>>> implementation.

>>> -----Original Message-----
>>> From: Andriy Redko <drr...@gmail.com>
>>> Sent: donderdag 4 juli 2024 4:44
>>> To: Jean Pierre URKENS <jean-pierre.urk...@devoteam.com>;
>>> dev@cxf.apache.org
>>> Subject: Re: CXF JAX-RS: working with multipart form-data

>>> Hi Jean,

>>> Interesting, I was experimenting with different ways to express what
>>> you need, but no luck so far, I will try to spend a bit more time on
>>> that this week since OAS 3.x does support multipart [1] but we may
>>> indeed hit the
>>> limitation(s) of this particular Swagger Core version. Thank you.

>>> [1]
>>> https://swagger.io/docs/specification/describing-request-body/multip
>>> a
>>> r
>>> t-requests/

>>> Best Regards,
>>>    Andriy Redko


>>>> Hi Andriy,

>>>> I already tried this but it didn't work. E.g. for following API
>>>> interface
>>>> specification:
>>>>                     /**
>>>>                     * Send a message, using a channel (email, paper
>>>> mail,
>>>> ebox) and delivery method (registered or normal) of your choice.
>>>> More than
>>>> 6 upfiles only supported for PAPER delivery.
>>>>                     *
>>>>                     */
>>>>                     @POST
>>>>                     @Path("/messages")
>>>>                     @Consumes("multipart/form-data")
>>>>                     @Produces({ "application/json" })
>>>>                     @Operation(
>>>>                                                             summary
>>>> = "Send a message, using a channel (email, paper mail, ebox) and
>>>> delivery method (registered or normal) of your choice. More than 6
>>>> upfiles only supported for PAPER delivery.",
>>>>                                                             tags =
>>>> {"messages" }, operationId="createMessage",
>>>> security=@SecurityRequirement(name="BearerAuthentication"))
>>>>                     @ApiResponses({ @ApiResponse( responseCode =
>>>> "201", description = "Created", content =
>>>> @Content(mediaType=MediaType.APPLICATION_JSON,array=@ArraySchema(sc
>>>> h e m a=@Schema(implementation=SendStatusMessage.class))),
>>>> headers = {@Header(
>>>> name="X-Magda-Exceptions",
>>>> required=false,
>>>> description="Only used in the context of EBOX delivery and if there
>>>> was a problem with the consent of the receiver's ebox.",
>>>> schema=@Schema(implementation=MagdaExceptionList.class))
>>>> }),
>>>> @ApiResponse(
>>>> responseCode = "400",
>>>> description = "Invalid data supplied", content =
>>>> @Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implem
>>>> e
>>>> n
>>>> t
>>>> ation=ErrorMessage.class))),
>>>> @ApiResponse(
>>>> responseCode = "401",
>>>> description = "Invalid authorization", content =
>>>> @Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implem
>>>> e
>>>> n
>>>> t
>>>> ation=ErrorMessage.class))),
>>>> @ApiResponse(
>>>> responseCode = "500",
>>>> description = "Unexpected Server Error", content =
>>>> @Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implem
>>>> e
>>>> n
>>>> t
>>>> ation=ErrorMessage.class))),
>>>> @ApiResponse(
>>>> responseCode = "502",
>>>> description = "Bad Gateway",
>>>> content =
>>>> @Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implem
>>>> e
>>>> n
>>>> t
>>>> ation=ErrorMessage.class))),
>>>> @ApiResponse(
>>>> responseCode = "503",
>>>> description = "Service unavailable", content =
>>>> @Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implem
>>>> e
>>>> n
>>>> t
>>>> ation=ErrorMessage.class))),
>>>> @ApiResponse(
>>>> responseCode = "504",
>>>> description = "Gateway Timeout",
>>>> content =
>>>> @Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implem
>>>> e
>>>> n
>>>> t
>>>> ation=ErrorMessage.class)))
>>>>                     })
>>>>                     public Response createMessage(
>>>> @HeaderParam("x-correlation-id") @NotNull @Size(min = 10, max = 36)
>>>> @Parameter(description="ID of the transaction. Use this ID for log
>>>> tracing and incident handling.") String xCorrelationId,
>>>> @HeaderParam("Idempotency-Key") @Size(min = 10, max = 36)
>>>> @Parameter(description="When retrying a failed call, the retry call
>>>> should have the same Idempotency Key.") String idempotencyKey,
>>>> @Parameter(required=true,schema =
>>>> @Schema(implementation=MessageToSend.class)) @Multipart(value =
>>>> "messageToSend", type="application/json", required= true)
>>>> MessageToSend messageToSend, @Parameter(schema = @Schema(type =
>>>> "string", format = "binary")) @Multipart(value = "upfile1",
>>>> type="application/octet-stream", required = false) Attachment
>>>> upfile1Detail, @Parameter(schema = @Schema(type = "string", format
>>>> =
>>>> "binary")) @Multipart(value = "upfile2",
>>>> type="application/octet-stream", required = false) Attachment
>>>> upfile2Detail, @Parameter(schema = @Schema(type = "string", format
>>>> =
>>>> "binary")) @Multipart(value = "upfile3",
>>>> type="application/octet-stream", required = false) Attachment
>>>> upfile3Detail, @Parameter(schema = @Schema(type = "string", format
>>>> =
>>>> "binary")) @Multipart(value = "upfile4",
>>>> type="application/octet-stream", required = false) Attachment
>>>> upfile4Detail, @Parameter(schema = @Schema(type = "string", format
>>>> =
>>>> "binary")) @Multipart(value = "upfile5",
>>>> type="application/octet-stream", required = false) Attachment
>>>> upfile5Detail, @Parameter(schema = @Schema(type = "string", format
>>>> =
>>>> "binary")) @Multipart(value = "upfile6",
>>>> type="application/octet-stream", required = false) Attachment
>>>> upfile6Detail, @Parameter(schema = @Schema(type = "string", format
>>>> =
>>>> "binary")) @Multipart(value = "upfile7",
>>>> type="application/octet-stream", required = false) Attachment
>>>> upfile7Detail, @Parameter(schema = @Schema(type = "string", format
>>>> =
>>>> "binary")) @Multipart(value = "upfile8",
>>>> type="application/octet-stream", required = false) Attachment
>>>> upfile8Detail, @Parameter(schema = @Schema(type = "string", format
>>>> =
>>>> "binary")) @Multipart(value = "upfile9",
>>>> type="application/octet-stream", required = false) Attachment
>>>> upfile9Detail, @Parameter(schema = @Schema(type = "string", format
>>>> =
>>>> "binary")) @Multipart(value = "upfile10",
>>>> type="application/octet-stream", required = false) Attachment
>>>> upfile10Detail, @Parameter(schema = @Schema(type = "string", format
>>>> =
>>>> "binary")) @Multipart(value = "upfile11",
>>>> type="application/octet-stream", required = false) Attachment
>>>> upfile11Detail, @Parameter(schema = @Schema(type = "string", format
>>>> =
>>>> "binary")) @Multipart(value = "upfile12",
>>>> type="application/octet-stream", required = false) Attachment
>>>> upfile12Detail, @Parameter(schema = @Schema(type = "string", format
>>>> =
>>>> "binary")) @Multipart(value = "upfile13",
>>>> type="application/octet-stream", required = false) Attachment
>>>> upfile13Detail, @Parameter(schema = @Schema(type = "string", format
>>>> =
>>>> "binary")) @Multipart(value = "upfile14",
>>>> type="application/octet-stream", required = false) Attachment
>>>> upfile14Detail, @Parameter(schema = @Schema(type = "string", format
>>>> =
>>>> "binary")) @Multipart(value = "upfile15",
>>>> type="application/octet-stream", required = false) Attachment
>>>> upfile15Detail, @Parameter(schema = @Schema(type = "string", format
>>>> =
>>>> "binary")) @Multipart(value = "upfile16",
>>>> type="application/octet-stream", required = false) Attachment
>>>> upfile16Detail, @Parameter(schema = @Schema(type = "string", format
>>>> =
>>>> "binary")) @Multipart(value = "upfile17",
>>>> type="application/octet-stream", required = false) Attachment
>>>> upfile17Detail, @Parameter(schema = @Schema(type = "string", format
>>>> =
>>>> "binary")) @Multipart(value = "upfile18",
>>>> type="application/octet-stream", required = false) Attachment
>>>> upfile18Detail, @Parameter(schema = @Schema(type = "string", format
>>>> =
>>>> "binary")) @Multipart(value = "upfile19",
>>>> type="application/octet-stream", required = false) Attachment
>>>> upfile19Detail, @Parameter(schema = @Schema(type = "string", format
>>>> =
>>>> "binary")) @Multipart(value = "upfile20",
>>>> type="application/octet-stream", required = false) Attachment
>>>> upfile20Detail, @Parameter(schema = @Schema(type = "string", format
>>>> =
>>>> "binary")) @Multipart(value = "qrfile",
>>>> type="application/octet-stream", required = false) Attachment
>>>> qrfileDetail); I’ve attached the generated openapi specification.
>>>> It only contains the ‘messageToSend’ as part of the
>>>> multipart/form-data requestBody content, all attachments are ignored.
>>>> Below I’ve listed the libraries I’ve included in the project (cxf
>>>> v3.5.8 and swagger v2.2.2). Which of these libraries is acutal
>>>> responsible for generating the openapi.json specification from the
>>>> interface description?
>>>> * cxf-rt-rs-service-description-common-openapi:3.5.8
>>>> * cxf-rt-rs-service-description-openapi:3.5.8
>>>> * cxf-rt-rs-service-description-swagger-ui:3.5.8
>>>> * swagger-core:2.2.2
>>>> * swagger-annotations:2.2.2
>>>> * swagger-integration:2.2.2
>>>> * swagger-jaxrs2: 2.2.2
>>>> * swagger-model: 2.2.2
>>>> Note that I am still on JDK8, so I guess I can’t upgrade to a
>>>> higher version (currently our projects use cxf-v3.5.6 and swagger
>>>> 2.1.13).
>>>> Regards,
>>>> J.P. Urkens
>>>> -----Original Message-----
>>>> From: Andriy Redko <drr...@gmail.com>
>>>> Sent: woensdag 3 juli 2024 5:57
>>>> To: Jean Pierre URKENS <jean-pierre.urk...@devoteam.com>;
>>>> dev@cxf.apache.org
>>>> Subject: Re: CXF JAX-RS: working with multipart form-data Hi Jean
>>>> Pierre, I suspect the @Multipart annotation is coming from CXF
>>>> (org.apache.cxf.jaxrs.ext.multipart.Multipart), right? If yes, this
>>>> is not a part of JAX-RS specification but CXF specific extension.
>>>> You may need to add Swagger API annotation to the parameters in
>>>> question:
>>>>    @Parameter(schema = @Schema(type = "string", format = "binary"))
>>>> Hope it helps.
>>>> Thank you.
>>>> Best Regards,
>>>>     Andriy Redko
>>>> Monday, July 1, 2024, 12:09:17 PM, you wrote:
>>>>> Hi all,
>>>>> I am having problems to correctly annotate service methods which
>>>>> consumes multipart/form-data that contains attachments next to
>>>>> other model objects.
>>>>> I’ve an openapi specification that contains following requestBody
>>>>> definition:
>>>>> /messages:
>>>>>     post:
>>>>>       tags:
>>>>>         - "messages"
>>>>>       summary: "Send a message, using a channel (email, paper
>>>>> mail,
>>>>> ebox) and delivery method (registered or normal) of your choice.
>>>>> More than 6 upfiles only supported for PAPER delivery."
>>>>>       operationId: createMessage
>>>>>       parameters:
>>>>>         - $ref: '#/components/parameters/CorrelationId'
>>>>>         - $ref: '#/components/parameters/Idempotency-Key'
>>>>>       requestBody:
>>>>>         content:
>>>>>           multipart/form-data:
>>>>>             schema:
>>>>>               type: object
>>>>>               required:
>>>>>                 - messageToSend
>>>>>               properties:
>>>>>                 messageToSend:
>>>>>                   $ref: '#/components/schemas/MessageToSend'
>>>>>                 upfile1:
>>>>>                   type: string
>>>>>                   format: binary
>>>>>                   nullable: true
>>>>>                 upfile2:
>>>>>                   type: string
>>>>>                   format: binary
>>>>>                   nullable: true
>>>>>                 upfile3:
>>>>>                   type: string
>>>>>                   format: binary
>>>>>                   nullable: true
>>>>>                 upfile4:
>>>>>                   type: string
>>>>>                   format: binary
>>>>>                   nullable: true
>>>>>                 upfile5:
>>>>>                   type: string
>>>>>                   format: binary
>>>>>                   nullable: true
>>>>>                 upfile6:
>>>>>                   type: string
>>>>>                   format: binary
>>>>>                   nullable: true
>>>>>                 upfile7:
>>>>>                   type: string
>>>>>                   format: binary
>>>>>                   nullable: true
>>>>>                 upfile8:
>>>>>                   type: string
>>>>>                   format: binary
>>>>>                   nullable: true
>>>>>                 upfile9:
>>>>>                   type: string
>>>>>                   format: binary
>>>>>                   nullable: true
>>>>>                 upfile10:
>>>>>                   type: string
>>>>>                   format: binary
>>>>>                   nullable: true
>>>>>                 upfile11:
>>>>>                   type: string
>>>>>                   format: binary
>>>>>                   nullable: true
>>>>>                 upfile12:
>>>>>                   type: string
>>>>>                   format: binary
>>>>>                   nullable: true
>>>>>                 upfile13:
>>>>>                   type: string
>>>>>                   format: binary
>>>>>                   nullable: true
>>>>>                 upfile14:
>>>>>                   type: string
>>>>>                   format: binary
>>>>>                   nullable: true
>>>>>                 upfile15:
>>>>>                   type: string
>>>>>                   format: binary
>>>>>                   nullable: true
>>>>>                 upfile16:
>>>>>                   type: string
>>>>>                   format: binary
>>>>>                   nullable: true
>>>>>                 upfile17:
>>>>>                   type: string
>>>>>                   format: binary
>>>>>                   nullable: true
>>>>>                 upfile18:
>>>>>                   type: string
>>>>>                   format: binary
>>>>>                   nullable: true
>>>>>                 upfile19:
>>>>>                   type: string
>>>>>                   format: binary
>>>>>                   nullable: true
>>>>>                 upfile20:
>>>>>                   type: string
>>>>>                   format: binary
>>>>>                   nullable: true
>>>>>                 qrfile:
>>>>>                   type: string
>>>>>                   format: binary
>>>>>                   nullable: true
>>>>>         required: true
>>>>> When using the openapi-generator-maven-plugin v7.6.0 it generates
>>>>> following method signature:
>>>>>         @POST
>>>>>         @Path("/messages")
>>>>>         @Consumes("multipart/form-data")
>>>>>         @Produces({ "application/json" })
>>>>>         @Operation(
>>>>>                         summary = "Send a message, using a channel

>>>>> (email, paper mail, ebox) and delivery method (registered or
>>>>> normal) of your choice. More than 6 upfiles only supported for
>>>>> PAPER delivery.",
>>>>>                         tags = {"messages" },
>>>>>                         operationId="createMessage",
>>>>> security=@SecurityRequirement(name="BearerAuthentication"),
>>>>>                         responses= {
>>>>>                                         @ApiResponse(
>>>>>
>>>>> responseCode = "201",
>>>>>
>>>>> description = "Created",
>>>>>                                                         content =
>>>>> @Content(mediaType=MediaType.APPLICATION_JSON,array=@ArraySchema(s
>>>>> c h em a=@Schema(implementation=SendStatusMessage.class))),
>>>>>                                                         headers =
>>>>> {@Header( name="X-Magda-Exceptions", required=false,
>>>>> description="Only used in the context of EBOX delivery and if
>>>>> there was a problem with the consent of the receiver's ebox.",
>>>>> schema=@Schema(implementation=MagdaExceptionList.class))
>>>>> }),
>>>>>                                         @ApiResponse(
>>>>>
>>>>> responseCode = "400",
>>>>>
>>>>> description = "Invalid data supplied",
>>>>>                                                         content =
>>>>> @Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(imple
>>>>> m
>>>>> e
>>>>> nt
>>>>> ation=ErrorMessage.class))),
>>>>>                                         @ApiResponse(
>>>>>
>>>>> responseCode = "401",
>>>>>
>>>>> description = "Invalid authorization",
>>>>>                                                         content =
>>>>> @Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(imple
>>>>> m
>>>>> e
>>>>> nt
>>>>> ation=ErrorMessage.class))),
>>>>>                                         @ApiResponse(
>>>>>
>>>>> responseCode = "500",
>>>>>
>>>>> description = "Unexpected Server Error",
>>>>>                                                         content =
>>>>> @Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(imple
>>>>> m
>>>>> e
>>>>> nt
>>>>> ation=ErrorMessage.class))),
>>>>>                                         @ApiResponse(
>>>>>
>>>>> responseCode = "502",
>>>>>
>>>>> description = "Bad Gateway",
>>>>>                                                         content =
>>>>> @Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(imple
>>>>> m
>>>>> e
>>>>> nt
>>>>> ation=ErrorMessage.class))),
>>>>>                                         @ApiResponse(
>>>>>
>>>>> responseCode = "503",
>>>>>
>>>>> description = "Service unavailable",
>>>>>                                                         content =
>>>>> @Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(imple
>>>>> m
>>>>> e
>>>>> nt
>>>>> ation=ErrorMessage.class))),
>>>>>                                         @ApiResponse(
>>>>>
>>>>> responseCode = "504",
>>>>>
>>>>> description = "Gateway Timeout",
>>>>>                                                         content =
>>>>> @Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(imple
>>>>> m
>>>>> e
>>>>> nt
>>>>> ation=ErrorMessage.class)))
>>>>>                         })
>>>>>         public Response createMessage(
>>>>>                         @HeaderParam("x-correlation-id") @NotNull
>>>>> @Size(min = 10, max = 36) @Parameter(description="ID of the
>>>>> transaction. Use this ID for log tracing and incident handling.")
>>>>> String xCorrelationId,
>>>>>                         @HeaderParam("Idempotency-Key") @Size(min
>>>>> = 10, max = 36) @Parameter(description="When retrying a failed
>>>>> call, the retry call should have the same Idempotency Key.")
>>>>> String idempotencyKey,
>>>>>                         @Multipart(value = "messageToSend”,
>>>>> required=
>>>>> true) MessageToSend messageToSend,
>>>>>                         @Multipart(value = "upfile1", required =
>>>>> false) Attachment upfile1Detail,
>>>>>                         @Multipart(value = "upfile2", required =
>>>>> false) Attachment upfile2Detail,
>>>>>                         @Multipart(value = "upfile3", required =
>>>>> false) Attachment upfile3Detail,
>>>>>                         @Multipart(value = "upfile4", required =
>>>>> false) Attachment upfile4Detail,
>>>>>                         @Multipart(value = "upfile5", required =
>>>>> false) Attachment upfile5Detail,
>>>>>                         @Multipart(value = "upfile6", required =
>>>>> false) Attachment upfile6Detail,
>>>>>                         @Multipart(value = "upfile7", required =
>>>>> false) Attachment upfile7Detail,
>>>>>                         @Multipart(value = "upfile8", required =
>>>>> false) Attachment upfile8Detail,
>>>>>                         @Multipart(value = "upfile9", required =
>>>>> false) Attachment upfile9Detail,
>>>>>                         @Multipart(value = "upfile10", required =
>>>>> false) Attachment upfile10Detail,
>>>>>                         @Multipart(value = "upfile11", required =
>>>>> false) Attachment upfile11Detail,
>>>>>                         @Multipart(value = "upfile12", required =
>>>>> false) Attachment upfile12Detail,
>>>>>                         @Multipart(value = "upfile13", required =
>>>>> false) Attachment upfile13Detail,
>>>>>                         @Multipart(value = "upfile14", required =
>>>>> false) Attachment upfile14Detail,
>>>>>                         @Multipart(value = "upfile15", required =
>>>>> false) Attachment upfile15Detail,
>>>>>                         @Multipart(value = "upfile16", required =
>>>>> false) Attachment upfile16Detail,
>>>>>                         @Multipart(value = "upfile17", required =
>>>>> false) Attachment upfile17Detail,
>>>>>                         @Multipart(value = "upfile18", required =
>>>>> false) Attachment upfile18Detail,
>>>>>                         @Multipart(value = "upfile19", required =
>>>>> false) Attachment upfile19Detail,
>>>>>                         @Multipart(value = "upfile20", required =
>>>>> false) Attachment upfile20Detail,
>>>>>                         @Multipart(value = "qrfile", required =
>>>>> false)  Attachment qrfileDetail); If I now generate the swagger
>>>>> from this code (I modified the annotations in the generated code
>>>>> for using OAS v3 annotations through swagger-jaxrs2 v2.1.13 and I
>>>>> am using cxf-v3.5.6 having swagger-ui v4.18.2 generate the user
>>>>> interface) none of the upload files appears as request parameter,
>>>>> only the messageToSend is shown.
>>>>> Is the above signature for the method createMessage(...) incorrect?
>>>>> If I look at the generated openapi.json all the Attachment upFiles
>>>>> are missing from the specification? So is it a
>>>>> problem/short-coming(?) of the used software libraries, which then:
>>>>> ·       cxf-rt-rs-service-description-common-openapi  v3.5.6     ->
>>>>> this library references swagger-jaxrs2 v2.1.13  ·       swagger-jaxrs2
>>>>> v2.1.13                                          -> can I upgradethis
>>>>> to
>>>>> e.g. swagger-jaxrs2 v2.2.22 (latest) while retaining cxf v3.5.6?
>>>>> ·       ...another?
>>>>> Regards,
>>>>> J.P.

Reply via email to