Replies: 4 comments
|
If I add |
|
It appears to be completely impossible to do it by just annotations. It is solely impossible due to the way MultipartForm handling is done in RestEasy Reactive. I found out that I have create web client using vertx. So I basically ditched the whole idea of using @MultipartForm and RestEasy Client in this particular context. I still use it in other places in my application. I created new "client" by using import This way I can actually defined each part in my form to be exactly what I want them to be. Here is the form that I pass to that function:
Now multipart form actually has correct information: attachment;filename=image.jpg;preview-type=image/jpg |
|
So for people who don't want to use In my case I solved using the following setup. @RegisterRestClient()
@RegisterProvider(HackyHTTPServiceFilter.class)
public interface MyHTTPService {
@POST
@Path("/binary")
String LaunchTransaction(@Nonnull @RestForm("Files") byte[] file,
@Nonnull @HeaderParam("FilesName") String fileName,
@Nonnull @HeaderParam("FilesMediaType") String mediaType);
}import jakarta.ws.rs.client.ClientRequestContext;
import jakarta.ws.rs.client.ClientRequestFilter;
import jakarta.ws.rs.ext.Provider;
import org.jboss.resteasy.reactive.client.impl.multipart.QuarkusMultipartForm;
import org.jboss.resteasy.reactive.client.impl.multipart.QuarkusMultipartFormDataPart;
import java.lang.reflect.Field;
@Provider
public class AbbyHTTPServiceFilter implements ClientRequestFilter {
private static final Field mediaTypeField;
private static final Field filenameField;
static {
try {
mediaTypeField = QuarkusMultipartFormDataPart.class.getDeclaredField("mediaType");
mediaTypeField.setAccessible(true);
filenameField = QuarkusMultipartFormDataPart.class.getDeclaredField("filename");
filenameField.setAccessible(true);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
}
@Override
public void filter(ClientRequestContext requestContext) {
if (!(requestContext.getEntity() instanceof QuarkusMultipartForm form)) {
return;
}
var headers = requestContext.getHeaders();
for (QuarkusMultipartFormDataPart f : form) {
String mediaTypeHeader = f.name() + "MediaType";
if (headers.getFirst(mediaTypeHeader) instanceof String mediaType) {
// Set mediaType
try {
mediaTypeField.set(f, mediaType);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
// Remove temp header
headers.remove(mediaTypeHeader);
}
String filenameHeader = f.name() + "Name";
if (headers.getFirst(filenameHeader) instanceof String filename) {
// Set name
try {
filenameField.set(f, filename);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
// Remove temp header
headers.remove(filenameHeader);
}
}
}
}It's not pretty but it seems to work. |
|
Another solution is to use Quarkus REST Client, programmatically building your multipart form with Rest Client Interface@POST
@Path("/create")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.MULTIPART_FORM_DATA)
Uni<MyResponse> createTask(
@HeaderParam("Trace-Id") String tradeId,
ClientMultipartForm form
);Multipart Form CreationClientMultipartForm.create()
.binaryFileUpload(
"content", // part name
"partFilename.jpg", // file name
Buffer.buffer(new byte[] { -1, -40, -1, -32 }), // file content as a byte array
"image/jpeg" // MIME type
)
.binaryFileUpload(
"content",
"anotherFilename.gif",
Buffer.buffer("GIF89a".getBytes()),
"image/gif"
);This should allow you to upload two files, along with their names and MIME types, to a Spring Boot application expecting a request body representable as Form Data EncodingFinally, to prevent Quarkus from encoding quarkus.rest-client.multipart-post-encoder-mode=HTML5 |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Hey,
I opened up a question in Stackoverflow where brought into light how I do not understand the construction part of MultipartForm
After initiating the request org.jbo.res.rea.cli.log.DefaultClientLogger logs such message:
POST http://api.service:8080/create Headers[Accept=application/json Trace-Id=traceId Authorization=Bearer Token Content-Type=multipart/form-data; boundary=595a37631607c32 transfer-encoding=chunked User-Agent=Resteasy Reactive Client], Body omittedHere is one of the the Resteasy Reactive client interface that I use to contact api.service:
Endpoint at http://api.service:8080/create expects
@RequestParam("content") List<MultipartFile> content. POST request above completes successfully and I am able to download the file back using different endpoint. When I request the file back from api.service the headers include Content-Disposition header with valueattachment;filename=content;preview-type=application/octet-streamwhich might indicate /create is only grabbing the @FormParam("content") and ditching the rest.Spring boot application expects
RequestParam("content") List<MultipartFile> content. How do I model my MyRequest in Quarkus so that Spring Boot understands it?All reactions