有没有办法将UTF-8与app引擎一起使用?
我正在寻找关于app引擎如何处理字符编码的一些解释。 我正在研究服务器在应用程序引擎上的客户端 – 服务器应用程序。
这是一个从头开始构建的新应用程序,因此我们在任何地方都使用UTF-8。 客户端通过POST,x-www-form-urlencoded向服务器发送一些字符串。 我收到它们并回复它们。 当客户端收回它时,它是ISO-8859-1! 在POST到blobstore时我也看到了这种行为,参数发送为UTF-8,multipart / form-data编码。
为了记录,我在Wireshark中看到了这一点。 所以我100%确定我发送UTF-8并获得ISO-8859-1。 另外,我没有看到mojibake:ISO-8859-1编码的字符串非常好。 这也不是误解内容类型的问题。 这不是客户。 一路走来正确地认识到我正在发送UTF-8参数,但由于某种原因正在将它们转换为ISO-8859-1。
我认为ISO-8859-1是GAE servlet的默认字符编码。 我的问题是,有没有办法告诉GAE不要转换为ISO-8859-1而是在任何地方使用UTF-8?
假设servlet做了这样的事情:
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); }
我尝试设置响应的字符编码并请求“UTF-8”,但这并没有改变任何东西。
提前致谢,
我看到你应该做的两件事。
1) 在appengine-web.xml中将系统属性(如果使用它)设置为utf8
好的,上面是我的,但文档建议如下:
https://developers.google.com/appengine/docs/java/config/appconfig
2) 在设置内容类型时指定编码,否则它将恢复为默认值
内容类型可以包括所使用的字符编码的类型,例如text / html; 字符集= ISO-8859-4。
我试试
resp.setContentType("application/json; charset=UTF-8");
您还可以尝试使用编写器直接设置内容类型。
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)
对于它的价值,我需要utf8用于日语内容,我没有遇到麻烦。 我还没有使用filter或setContentType。 我正在使用上面的gwt和#1并且它有效。
找到了解决它的方法。 这就是我做的方式:
-
使用“application / json; charset = UTF-8”作为内容类型。 或者,将响应字符集设置为“UTF-8”(两者都可以正常工作,不需要同时执行这两个操作)。
-
Base64编码的输入字符串不是ASCII安全的,并且是UTF-8。 否则,当他们到达servlet时,他们会转换为ISO-8859-1。
-
使用resp.getWriter()而不是resp.getOutputStream()来打印JSON响应。
在满足所有条件后,我终于能够将UTF-8输出回客户端。
这不是GAE特有的,但如果你发现它很有用:我自己创建了filter:
在web.xml中
charsetencoding mypackage.CharsetEncodingFilter ... charsetencoding /*
(将filter映射片段放在filter映射的开头,并检查您的url模式。
和
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 { } }
解决方法(安全)
这些答案中没有任何一个对我有用,所以我编写了这个类来编码UTF-Strings到ASCII-Strings (使用AsciiEncoder.encode(yourString)
替换所有不在ASCII表中的字符,其中包含其表号,前面跟着一个标记) AsciiEncoder.encode(yourString)
然后可以使用AsciiEncoder.decode(yourAsciiEncodedString)
将String 解码回UTF 。
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 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; } }
希望这有助于某人。
- 如何使用来自Java / Python Web cron的聋人请求来运行App Engine / Java应用程序?
- Google App Engine + JSF 2会出错
- 约会和订单项
- JExcel中的编码问题
- java.lang.VerifyError:期望一个stackmap框架
- 在Google App Engine Java应用程序中加载自定义密钥库
- 持久保存@Embeddable的@ElementCollection(Google App Engine,datanucleus)
- 如何在谷歌应用引擎中使用不同版本的自定义域名?
- 如何在Google App Engine Java上减少Appstats的内存使用量