Measures against garbled characters in Multipart Request with Quarkus

I got a little fit, so make a note.

TL;DR

This will fix the garbled characters

<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-undertow</artifactId>
</dependency>
@Provider
public class ContentTypeSetterPreProcessorInterceptor implements ContainerRequestFilter {
    private @Context HttpServletRequest request;

    @Override
    public void filter(ContainerRequestContext requestContext) {
        request.setAttribute(InputPart.DEFAULT_CHARSET_PROPERTY, StandardCharsets.UTF_8.name());
    }
}

background

I made a file upload function with Vue.js and Quarkus, but there was a phenomenon that the titles linked in the same form were garbled. The code I wrote is as follows.

Client side. I'm using new FormData () to use multipart / form-data.

let data = new FormData();
data.append("title", this.item.title);
data.append("myfile", this.item.files[0]);

this.axios.post(uri, data).then(() => {
    this.$swal({
        icon: "success",
        text: "Upload Success!"
    });
})

Server side. Use JAX-RS @ MultipartForm. Both titles and files are automatically mapped to beans.

public class MyFileFormBean {
    @FormParam("title")
    @PartType(MediaType.TEXT_PLAIN)
    private String title = null;

    @FormParam("myfile")
    @PartType(MediaType.APPLICATION_OCTET_STREAM)
    private byte[] myfile = null;
....

JAX-RS side.

@POST
@Consumes({MediaType.MULTIPART_FORM_DATA})
@Produces(MediaType.APPLICATION_JSON)
public Response upload(@MultipartForm MyFileFormBean form) throws IOException {
    System.out.println("title: " + form.getTitle());
...
}

I was planning to do this, but for some reason the Japanese characters were garbled. .. ..

title: ????????????

Cause

It seems that RESTEasy converts to ASCII (ISO-8859-1) by default when the character code is not included. It seems that you should specify ʻaccept-charset` in Form, but it seems a little troublesome to do it with JS, so it seems better to forcibly convert it on the server.

After googled there was a sample implementation in JBoss Community.

@Provider
@ServerInterceptor
public class ContentTypeSetterPreProcessorInterceptor implements PreProcessInterceptor {
    public ServerResponse preProcess(HttpRequest request, ResourceMethod method)
            throws Failure, WebApplicationException {
        request.setAttribute(InputPart.DEFAULT_CHARSET_PROPERTY, "UTF-8");
        return null;
    }
}

However, RestEasy used in Quarkus is JAX-RS 2.0 compliant, so the above writing method is not possible. So you need to use ContainerRequestFilter instead of PreProcessInterceptor.

Countermeasures

Rewrite according to JAX-RS 2.0 while referring to the sample. By default, Quarkus uses Vert.x HTTP server as described in Servlet compatibility, so HttpServletRequest cannot be used. So add quarkus-undertow as a dependency.

<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-undertow</artifactId>
</dependency>

The following code hooks a request based on JAX-RS 2.0 and forcibly converts DEFAULT_CHARSET_PROPERTY to ʻUTF-8`.

@Provider
public class ContentTypeSetterPreProcessorInterceptor implements ContainerRequestFilter {
    private @Context HttpServletRequest request;

    @Override
    public void filter(ContainerRequestContext requestContext) {
        request.setAttribute(InputPart.DEFAULT_CHARSET_PROPERTY, StandardCharsets.UTF_8.name());
    }
}

If you set @Provider, you don't need to add a configuration file. This solved the garbled characters.

Summary

I used to write a filter because it is garbled in JavaServlet, but I didn't think I would do it even in modern times, so I got into it a little. File uploads are still full of traps. Although it is different from RFC, UTF-8 has the same code in the ASCII area, and I feel that UTF-8 may be the default.

The issue on GitHub also mentions "UTF-8 encoding problem with MultiPart / RestEasy", so you can easily switch with the configuration file. It may be in the future.

Then Happy Hacking!

Recommended Posts

Measures against garbled characters in Multipart Request with Quarkus
Fix garbled characters in SceneBuilder 11
Zip compression with Java in Windows environment without garbled characters
CSV parsing with newline characters in fields
Japanese characters described in MessageResources.properties are garbled
Challenge to deal with garbled characters with Java AudioSystem.getMixerInfo ()