[JAVA] Maßnahmen gegen verstümmelte Charaktere in Multipart Request mit Quarkus

Ich habe es ein wenig verstanden, also mach dir eine Notiz.

TL;DR

Dadurch werden die verstümmelten Zeichen behoben

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

Hintergrund

Ich habe mit Vue.js und Quarkus eine Funktion zum Hochladen von Dateien erstellt, aber die in derselben Form verknüpften Titel waren verstümmelt. Der Code, den ich geschrieben habe, lautet wie folgt.

Client-Seite. Ich benutze "new FormData ()", um "multipart / form-data" zu verwenden.

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!"
    });
})

Serverseite. Verwenden Sie JAX-RS @ MultipartForm. Sowohl Titel als auch Dateien werden automatisch Beans zugeordnet.

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 Seite.

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

Ich hatte vor, dies zu tun, aber aus irgendeinem Grund waren die japanischen Schriftzeichen verstümmelt. .. ..

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

Ursache

Es scheint, dass RESTEasy standardmäßig in ASCII (ISO-8859-1) konvertiert, wenn der Zeichencode nicht enthalten ist. Es scheint, dass Sie in Form "accept-charset" angeben sollten, aber es scheint ein wenig mühsam mit JS zu sein, daher scheint es besser, die Konvertierung auf dem Server zu erzwingen.

Als ich googelte gab es eine Beispielimplementierung in der 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;
    }
}

In Quarkus verwendetes RestEasy ist jedoch JAX-RS 2.0-kompatibel, sodass die oben beschriebene Schreibmethode nicht möglich ist. Sie müssen also "ContainerRequestFilter" anstelle von "PreProcessInterceptor" verwenden.

Gegenmaßnahmen

Schreiben Sie in Übereinstimmung mit JAX-RS 2.0 neu, während Sie sich auf das Beispiel beziehen. Quarkus verwendet standardmäßig den Vert.x-HTTP-Server, wie unter Servlet-Kompatibilität beschrieben, sodass HttpServletRequest nicht verwendet werden kann. Fügen Sie also "Quarkus-Sog" als Abhängigkeit hinzu.

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

Der folgende Code verknüpft eine auf JAX-RS 2.0 basierende Anforderung und konvertiert "DEFAULT_CHARSET_PROPERTY" zwangsweise in "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());
    }
}

Wenn Sie "@ Provider" festlegen, müssen Sie keine Einstellungsdatei hinzufügen. Dies löste die verstümmelten Charaktere.

Zusammenfassung

Früher habe ich einen Filter geschrieben, weil er mit JavaServlet verstümmelt ist, aber ich dachte nicht, dass ich es auch in modernen Zeiten tun würde, also habe ich mich ein wenig damit beschäftigt. Das Hochladen von Dateien ist immer noch voller Fallen. Obwohl es sich von RFC unterscheidet, hat UTF-8 den gleichen Code im ASCII-Bereich, und ich bin der Meinung, dass UTF-8 möglicherweise die Standardeinstellung ist.

Das Problem auf GitHub erwähnt auch "UTF-8-Codierungsproblem mit MultiPart / RestEasy", damit Sie in der Einstellungsdatei problemlos zwischen ihnen wechseln können. Es kann in der Zukunft sein.

Dann viel Spaß beim Hacken!

Recommended Posts

Maßnahmen gegen verstümmelte Charaktere in Multipart Request mit Quarkus
Korrigieren Sie verstümmelte Zeichen in SceneBuilder 11
Zip-Komprimierung, die in einer Java-Umgebung nicht beeinträchtigt wird
CSV-Analyse mit Feldumbruchzeichen
In MessageResources.properties beschriebene japanische Zeichen sind verstümmelt
Herausforderung, mit verstümmelten Zeichen mit Java AudioSystem.getMixerInfo () umzugehen