[JAVA] Mesures contre les caractères déformés dans la requête en plusieurs parties avec Quarkus

Je l'ai un peu, alors prenez note.

TL;DR

Cela corrigera les caractères déformés

<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());
    }
}

Contexte

J'ai créé une fonction de téléchargement de fichiers avec Vue.js et Quarkus, mais les titres liés sous la même forme étaient déformés. Le code que j'ai écrit est le suivant.

Côté client. J'utilise new FormData () pour utiliser 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!"
    });
})

Du côté serveur. Utilisez JAX-RS @ MultipartForm. Les titres et les fichiers sont automatiquement mappés aux 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;
....

Côté JAX-RS.

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

J'avais l'intention de le faire, mais pour une raison quelconque, les caractères japonais étaient déformés. .. ..

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

Cause

Il semble que RESTEasy se convertisse en ASCII (ISO-8859-1) par défaut lorsque le code de caractère n'est pas inclus. Il semble que vous deviez spécifier ʻaccept-charset` dans Form, mais cela semble un peu gênant de le faire avec JS, il semble donc préférable de le convertir de force sur le serveur.

Quand j'ai cherché sur Google il y avait un exemple d'implémentation dans la communauté JBoss.

@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;
    }
}

Cependant, RestEasy utilisé dans Quarkus est compatible JAX-RS 2.0, la méthode d'écriture ci-dessus n'est donc pas possible. Vous devez donc utiliser ContainerRequestFilter au lieu de PreProcessInterceptor.

Contre-mesures

Réécrivez conformément à JAX-RS 2.0 en vous référant à l'échantillon. Quarkus utilise le serveur HTTP Vert.x par défaut comme décrit dans Compatibilité des servlets, donc HttpServletRequest ne peut pas être utilisé. Ajoutez donc quarkus-Undertow comme dépendance.

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

Le code suivant accroche une requête basée sur JAX-RS 2.0 et convertit de force DEFAULT_CHARSET_PROPERTY en ʻ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());
    }
}

Si vous définissez @ Provider, vous n'avez pas besoin d'ajouter un fichier de paramètres. Cela a résolu les caractères brouillés.

Résumé

J'avais l'habitude d'écrire un filtre parce qu'il est brouillé avec JavaServlet, mais je ne pensais pas que je le ferais même dans les temps modernes, alors je me suis un peu intéressé. Le téléchargement de fichiers est toujours plein de pièges. Bien qu'il soit différent de RFC, UTF-8 a le même code dans la zone ASCII, et je pense que UTF-8 peut être la valeur par défaut.

Le problème sur GitHub mentionne également «problème d'encodage UTF-8 avec MultiPart / RestEasy» afin que vous puissiez facilement basculer entre eux dans le fichier de paramètres. C'est peut-être dans le futur.

Alors Happy Hacking!

Recommended Posts

Mesures contre les caractères déformés dans la requête en plusieurs parties avec Quarkus
Correction des caractères déformés dans SceneBuilder 11
Compression Zip qui ne brouille pas dans l'environnement Java
Analyse CSV avec des caractères de saut de champ
Les caractères japonais décrits dans MessageResources.properties sont déformés
Défi pour gérer les caractères déformés avec Java AudioSystem.getMixerInfo ()