英文:
Java JSON String problem encoding Multipart
问题
我正在开发一个接收 MultipartFormDataInput 对象 (org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput)
的 REST API,这个对象是来自一个 form-data 的 Vue.js 应用。在数据字段中包含一个包含拉丁重音字符(á, é, í, ó, ú, ñ)的 JSON 字符串。在 Java 中打印 JSON 数据时,我得到了以下结果:
原始的 JSON 字符串:
{
"code": "123456789",
"form": "test",
"pot": "special character ñ",
"categoria": "acción",
"propiedad": "algún",
"diligencia": "ábaco",
"actual": "grabé",
"pais": "Abstraído",
"vivio_otro_pais_cual": "word without special characters... OK 1 2 3<>?!@#$%^&*()_+"
}
在 Java 中接收到的 JSON 字符串:
11:04:32,086 INFO [stdout] (default task-1) JSON VALUES.... {
11:04:32,087 INFO [stdout] (default task-1) "code": "123456789",
11:04:32,087 INFO [stdout] (default task-1) "form": "test",
11:04:32,087 INFO [stdout] (default task-1) "pot": "special character ??",
11:04:32,087 INFO [stdout] (default task-1) "categoria": "acci??n",
11:04:32,087 INFO [stdout] (default task-1) "propiedad": "alg??n",
11:04:32,087 INFO [stdout] (default task-1) "diligencia": "??baco",
11:04:32,087 INFO [stdout] (default task-1) "actual": "grab??",
11:04:32,087 INFO [stdout] (default task-1) "pais": "Abstra??do",
11:04:32,087 INFO [stdout] (default task-1) "vivio_otro_pais_cual": "word without special characters... OK 1 2 3<>?!@#$%^&*()_+"
11:04:32,087 INFO [stdout] (default task-1) }
要如何接收带有拉丁特殊字符的字符串?
我的代码(端点):
@POST
@Path("/testEncoding")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response testEncoding(@Context HttpHeaders headers, MultipartFormDataInput multipart){
return interfaceOperationService.testEncoding(headers, multipart);
}
实现:
public Response testEncoding(HttpHeaders headers, MultipartFormDataInput multipart) {
try {
String dataJson = multipart.getFormDataPart("data", String.class, null);
String valorCodificado = new String (dataJson.getBytes(StandardCharsets.US_ASCII), StandardCharsets.UTF_8);
System.out.println("JSON VALUES.... " + dataJson);
System.out.println("JSON ENCODING.... " + valorCodificado);
StringBuilder sb = new StringBuilder();
for (String header : headers.getRequestHeaders().keySet()) {
sb.append(header + ":" + headers.getRequestHeader(header) + "\n");
}
System.out.println(sb.toString());
return Response.status(200).entity(valorCodificado).build();
} catch (Exception e) {
// TODO: handle exception
return Response.status(500).entity("ERROR").build();
}
}
以及 pom 依赖:
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-multipart-provider</artifactId>
<version>4.5.8.Final</version>
<scope>provided</scope>
</dependency>
英文:
I’m developing a REST API that receives a MultipartFormDataInput object (org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput)
, this comes from a form-data Vue.js app. On the data field comes a json string that contains latin accent characters (á, é, í, ó, ú, ñ). When print the json data in Java I get this:
Original Json string
{
"code": "123456789",
"form": "test",
"pot": "special character ñ",
"categoria": "acción",
"propiedad": "algún",
"diligencia": "ábaco",
"actual": "grabé",
"pais": "Abstraído",
"vivio_otro_pais_cual": "word without special characters... OK 1 2 3<>?!@#$%^&*()_+"
}
Json string received in Java
11:04:32,086 INFO [stdout] (default task-1) JSON VALUES.... {
11:04:32,087 INFO [stdout] (default task-1) "code": "123456789",
11:04:32,087 INFO [stdout] (default task-1) "form": "test",
11:04:32,087 INFO [stdout] (default task-1) "pot": "special character ??",
11:04:32,087 INFO [stdout] (default task-1) "categoria": "acci??n",
11:04:32,087 INFO [stdout] (default task-1) "propiedad": "alg??n",
11:04:32,087 INFO [stdout] (default task-1) "diligencia": "??baco",
11:04:32,087 INFO [stdout] (default task-1) "actual": "grab??",
11:04:32,087 INFO [stdout] (default task-1) "pais": "Abstra??do",
11:04:32,087 INFO [stdout] (default task-1) "vivio_otro_pais_cual": "word without special characters... OK 1 2 3<>?!@#$%^&*()_+"
11:04:32,087 INFO [stdout] (default task-1) }
11:04:32,088 INFO [stdout] (default task-1) JSON ENCODING.... {
11:04:32,088 INFO [stdout] (default task-1) "code": "123456789",
11:04:32,088 INFO [stdout] (default task-1) "form": "test",
11:04:32,088 INFO [stdout] (default task-1) "pot": "special character ??",
11:04:32,088 INFO [stdout] (default task-1) "categoria": "acci??n",
11:04:32,088 INFO [stdout] (default task-1) "propiedad": "alg??n",
11:04:32,088 INFO [stdout] (default task-1) "diligencia": "??baco",
11:04:32,088 INFO [stdout] (default task-1) "actual": "grab??",
11:04:32,088 INFO [stdout] (default task-1) "pais": "Abstra??do",
11:04:32,088 INFO [stdout] (default task-1) "vivio_otro_pais_cual": "word without special characters... OK 1 2 3<>?!@#$%^&*()_+"
11:04:32,088 INFO [stdout] (default task-1) }
What can i do to receive the string with latin special characters?
My code (end point):
@POST
@Path("/testEncoding")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response testEncoding(@Context HttpHeaders headers, MultipartFormDataInput multipart){
return interfaceOperationService.testEncoding(headers, multipart);
}
Implementation:
public Response testEncoding(HttpHeaders headers, MultipartFormDataInput multipart) {
try {
String dataJson = multipart.getFormDataPart("data", String.class, null);
String valorCodificado = new String (dataJson.getBytes(StandardCharsets.US_ASCII), StandardCharsets.UTF_8);
System.out.println("JSON VALUES.... " + dataJson);
System.out.println("JSON ENCODING.... " + valorCodificado);
StringBuilder sb = new StringBuilder();
for (String header : headers.getRequestHeaders().keySet()) {
sb.append(header + ":" + headers.getRequestHeader(header) + "\n");
}
System.out.println(sb.toString());
return Response.status(200).entity(valorCodificado).build();
} catch (Exception e) {
// TODO: handle exception
return Response.status(500).entity("ERROR").build();
}
}
and pom dependency:
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-multipart-provider</artifactId>
<version>4.5.8.Final</version>
<scope>provided</scope>
</dependency>
答案1
得分: 1
所以在多部分内容中,每个消息体部分都是一个独立的实体,具有自己独立的内容类型。如果您在客户端请求中没有为每个部分设置内容类型,则会假定为 text/plain
。在 RESTEasy 实现的情况下,默认为 text/plain; charset=ISO-8859-1
。
>InputPart.DEFAULT_CONTENT_TYPE_PROPERTY
<br>
>如果在多部分消息的某个部分中未发送内容类型头,则会假定为 "text/plain; charset=ISO-8859-1"。
许多客户端无法为每个部分设置内容类型头。因此,您应该为它们设置内容类型头。对于这个部分,您希望它是 application/json; chartset=utf-8
。设置头的方法是从 MultiPartFormDataInput 获取 InputPart
。不要使用 getFormDataPart()
方法,而要使用 getFormDataMap()
方法,以获得返回类型为 Map<String, List<InputPart>>
。从那里获取 InputPart
并调用 InputPart#setMediaTye()
,然后可以使用 InputPart#getBody()
变体之一获取数据。类似于(未经测试):
Map<String, List<InputPart>> inputParts = multipart.getFormDataMap();
List<InputPart> dataParts = inputParts.get("data");
if (dataParts != null && !dataParts.isEmpty()) {
InputPart dataPart = dataParts.get(0);
dataPart.setMediaType(MediaType.APPLICATION_JSON + "; chartset=utf-8");
String dataPartJson = dataPart.getBody(String.class, null);
// 或者如果您创建了一个 POJO,则数据将由 Jackson 进行反序列化
DataPojo dataPartPogo = dataPart.getBody(DataPojo.class, null);
}
英文:
So in multipart, each body part is its own separate entity with its own separate content-type. If you don't set the content-type for each part in the client request, it is assumed to be text/plain
. In the case of RESTEasy implementation, it is text/plain; charset=ISO-8859-1
.
>InputPart.DEFAULT_CONTENT_TYPE_PROPERTY
<br>
>If no content-type header is sent in a multipart message part "text/plain; charset=ISO-8859-1" is assumed.
A lot of clients are not able to set the content-type header for each part. So what you should do is set the content-type header for them. For this part, you want it to be application/json; chartset=utf-8
. How you set the header is by getting the InputPart
from the MultiPartFormDataInput. Instead of using the getFormDataPart()
method, use the getFormDataMap()
method to get a Map<String, List<InputPart>>
return type. From there, get the InputPart
and call InputPart#setMediaTye()
, then you can get the data with one of the InputPart#getBody()
variants. Something like (not tested):
Map<String, List<InputPart>> inputParts = multipart.getFormDataMap();
List<InputPart> dataParts = inputParts.get("data");
if (dataParts != null && !dataParts.isEmpty()) {
InputPart dataPart = dataParts.get(0);
dataPart.setMediaType(MediaType.APPLICATION_JSON + "; chartset=utf-8");
String dataPartJson = dataPart.getBody(String.class, null);
// of if you make a POJO the data will get deserialized by Jackson
DataPojo dataPartPogo = dataPart.getBody(DataPojo.class, null);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论