supported example encodings charset java google-app-engine servlets character-encoding

example - java encoding windows 1252



¿Hay alguna forma de usar UTF-8 con el motor de aplicaciones? (4)

Estoy buscando alguna explicación sobre cómo el motor de la aplicación se ocupa de las codificaciones de caracteres. Estoy trabajando en una aplicación cliente-servidor donde el servidor está en el motor de la aplicación.

Esta es una nueva aplicación construida desde cero, por lo que estamos usando UTF-8 en todas partes. El cliente envía algunas cadenas al servidor a través de POST, x-www-form-urlencoded. Los recibo y los echo de vuelta. Cuando el cliente lo recupera, ¡es ISO-8859-1! También veo este comportamiento al realizar la POST en la tienda de blob, con los parámetros enviados como UTF-8, multipart / form-data codificada.

Para el registro, estoy viendo esto en Wireshark. Así que estoy 100% seguro de enviar UTF-8 y recibir ISO-8859-1. Además, no estoy viendo mojibake: las cadenas codificadas ISO-8859-1 están perfectamente bien. Esto tampoco es un problema de malinterpretar el tipo de contenido. No es el cliente. Algo en el camino es reconocer correctamente que estoy enviando parámetros UTF-8, pero por algún motivo los está convirtiendo a ISO-8859-1.

Me hacen creer que ISO-8859-1 es la codificación de caracteres predeterminada para los servlets de GAE. Mi pregunta es, ¿hay alguna manera de decirle a GAE que no convierta a ISO-8859-1 y en su lugar use UTF-8 en todas partes?

Digamos que el servlet hace algo como esto:

public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { resp.setContentType("application/json"); String name = req.getParameter("name"); String json = "{/"name/":/"" + name + "/"}"; resp.getOutputStream().print(json); }

Traté de configurar la codificación de caracteres de la respuesta y la solicitud a "UTF-8", pero eso no cambió nada.

Gracias por adelantado,


Solución (segura)

Ninguna de estas respuestas funcionó para mí, así que escribí esta clase para codificar UTF-Strings en ASCII-Strings (reemplazando todos los caracteres que no están en la tabla ASCII con su número de tabla, precedido y seguido de una marca), usando AsciiEncoder.encode(yourString)

La cadena se puede decodificar de nuevo a UTF con AsciiEncoder.decode(yourAsciiEncodedString) .

package <your_package>; import java.util.ArrayList; /** * Created by Micha F. aka Peracutor. * 04.06.2017 */ public class AsciiEncoder { public static final char MARK = ''%''; //use whatever ASCII-char you like (should be occurring not often in regular text) public static String encode(String s) { StringBuilder result = new StringBuilder(s.length() + 4 * 10); //buffer for 10 special characters (4 additional chars for every special char that gets replaced) for (char c : s.toCharArray()) { if ((int) c > 127 || c == MARK) { result.append(MARK).append((int) c).append(MARK); } else { result.append(c); } } return result.toString(); } public static String decode(String s) { int lastMark = -1; ArrayList<Character> chars = new ArrayList<>(); try { //noinspection InfiniteLoopStatement while (true) { String charString = s.substring(lastMark = s.indexOf(MARK, lastMark + 1) + 1, lastMark = s.indexOf(MARK, lastMark)); char c = (char) Integer.parseInt(charString); chars.add(c); } } catch (IndexOutOfBoundsException | NumberFormatException ignored) {} for (char c : chars) { s = s.replace("" + MARK + ((int) c) + MARK, String.valueOf(c)); } return s; } }

Espero que esto ayude a alguien.


Encontré una forma de evitarlo. Así es como lo hice:

  • Se utilizó "application / json; charset = UTF-8" como tipo de contenido. Alternativamente, configure el conjunto de caracteres de respuesta en "UTF-8" (cualquiera funcionará bien, no es necesario que haga ambas cosas).

  • Base64 codifica las cadenas de entrada que no son ASCII-safe y vienen como UTF-8. De lo contrario, se convierten a ISO-8859-1 cuando llegan al servlet, al parecer.

  • Usado resp.getWriter () en lugar de resp.getOutputStream () para imprimir la respuesta JSON.

Después de que se cumplieron todas esas condiciones, finalmente pude devolver UTF-8 al cliente.


Esto no es específico de GAE, pero en caso de que lo encuentre útil: hice mi propio filtro:

En web.xml

<filter> <filter-name>charsetencoding</filter-name> <filter-class>mypackage.CharsetEncodingFilter</filter-class> </filter> ... <filter-mapping> <filter-name>charsetencoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

(coloque el fragmento de mapeo de filtro bastante al comienzo de las asignaciones de filtro y verifique su patrón de url).

Y

public class CharsetEncodingFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; req.setCharacterEncoding("UTF-8"); chain.doFilter(req, res); res.setCharacterEncoding("UTF-8"); } public void destroy() { } public void init(FilterConfig filterConfig) throws ServletException { } }


Veo dos cosas que debes hacer.

1) configure las propiedades del sistema (si lo está usando) para utf8 en su appengine-web.xml

<system-properties> <property name="java.util.logging.config.file" value="WEB-INF/logging.properties" /> <property name="file.encoding" value="UTF-8" /> <property name="DEFAULT_ENCODING" value="UTF-8" /> </system-properties>

De acuerdo que arriba es lo que tengo pero los documentos sugieren esto a continuación:

<env-variables> <env-var name="DEFAULT_ENCODING" value="UTF-8" /> </env-variables>

https://developers.google.com/appengine/docs/java/config/appconfig

2) especifique la codificación cuando configure el tipo de contenido o volverá a ser el predeterminado

El tipo de contenido puede incluir el tipo de codificación de caracteres utilizada, por ejemplo, text / html; charset = ISO-8859-4.

Lo intentaría

resp.setContentType("application/json; charset=UTF-8");

También puede probar con un escritor que le permita establecer el tipo de contenido directamente.

http://docs.oracle.com/javaee/1.3/api/javax/servlet/ServletResponse.html#getWriter%28%29
http://docs.oracle.com/javaee/1.3/api/javax/servlet/ServletResponse.html#setContentType(java.lang.String)

Por lo que vale, necesito utf8 para contenido japonés y no tengo problemas. No estoy usando un filtro o setContentType de todos modos. Estoy usando gwt y # 1 arriba y funciona.