【问题标题】:How to use utf8 with javascript, javaservlets, mysql and back?如何将 utf8 与 javascript、javaservlets、mysql 和 back 一起使用?
【发布时间】:2018-03-26 19:44:12
【问题描述】:

我正在尝试在我的应用程序上处理希伯来语字符。 我的应用程序构建如下:

  1. 带有 java servlet、jsp 的 ui。

  2. 带有 java servlet 的服务器,mysql。

我的应用程序所做的是通过 UI 获取数据,创建一个 javascript 对象,使用 JSON.stringify 将其转换为 JSON 字符串并使用 XMLHttpRequest 和xhr.send("data=".concat(jsonString)); 发送它然后 JavaScript 代码将 jsonString 发送到 ui servlet将其转发到服务器的 servlet,然后使用 hibernate api 将其保存在数据库顶部。

我被这个希伯来语问题困扰了一段时间,所以在研究

我要做的是:

  1. 我的 JSP 文件以

    开头

<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

并且拥有

&lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8"&gt;

&lt;head&gt; 标签内。

  1. 在 javascript 构造函数中,我在可能包含希伯来字符的字段上使用 encodeURIComponent()

  2. 我在 UI servlet 和服务器 servlet 过滤器上都有将字符编码设置为 utf-8(如果为空)。

  3. 我用new String(originalString.toBytes() , "UTF8") 调用db 对象的构造函数(我正在使用hibernate),其中originalString 是可能包含希伯来字符的字符串。

  4. 在我的 persistence.xml 文件中

    <property name="hibernate.connection.CharSet" value="utf8mb4" /> <property name="hibernate.connection.characterEncoding" value="utf8" /> <property name="hibernate.connection.useUnicode" value="true" />

一切就绪。

  1. 在 Eclipse 中,我将 project->properties->resource->文本文件编码设置为 UTF8。

  2. 我尝试过使用 xhr.overrideMimeType("UTF-8")xhr.setRequestHeader("charset" , "utf-8"),但它们没有帮助,所以我将它们注释掉。

我就是这样。 我其实有一种感觉,我弄得有点乱……

现在,当我尝试通过 ui 在数据库中保存希伯来字符时:

  1. 当我在 ui servlet 上执行 s.o.p 时,我得到了这种东西:"×××¢" 而不是希伯来字符。当我尝试在 UI 上显示 habrew 字符时也是如此。

  2. 当我在服务器 servlet 上执行 s.o.p 时,我得到了这种东西:"Ã\u0097Â\u0092Ã\u0097Â\u0096Ã\u0097¢"

  3. 在 mysql 工作台上,我看到 A 的顶部带有带有 4 位数字的小方块的标志。

我非常希望能够在 mysql 工作台和我的 UI 中查看希伯来语字符。

谢谢!

------------------编辑---------------------

我已添加到我的 servlet

request.setCharacterEncoding("UTF-8");

现在我在我的 ui servlet 中获得了希伯来语字符。

ui servlet 使用下面的代码将请求转发到服务器 servlet,过去几个小时我一直在尝试调试,但没有成功。我认为问题可能在这里:

public static String forwardToServer(String servletName , 
                                         Map<String, Object> params , 
                                         String encoding , String method , 
                                         HttpSession session) {
        try {
            URL url = new URL(settings.LocationSettings.SERVER_ADDRESS.concat(servletName));
            StringBuilder postData = new StringBuilder();
            for (Map.Entry<String,Object> param : params.entrySet()) {
                if (postData.length() != 0) postData.append('&');
                /*postData.append(URLEncoder.encode(param.getKey(), encoding));
                postData.append('=');
                postData.append(URLEncoder.encode(String.valueOf(param.getValue()), encoding));
               */
                postData.append(param.getKey());
                postData.append('=');
                postData.append(String.valueOf(param.getValue()));
            }
            System.out.println("postData = " + postData.toString());
            byte[] postDataBytes = postData.toString().getBytes(encoding);
            System.out.println("postDataBytes.toString() = " + new String(postDataBytes));
            byte[] postDataBytes2 = postData.toString().getBytes();
            System.out.println("postDataBytes2.toString() = " + new String(postDataBytes2));




            HttpURLConnection conn = (HttpURLConnection)url.openConnection();

            String mySessionCookie = "JSESSIONID="+session.getAttribute(Login.SERVER_SESSION_ID_ATT_NAME);
            conn.setRequestMethod(method);
            conn.setRequestProperty("Cookie", mySessionCookie);
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
            conn.setRequestProperty("charset" , "utf-8");
            conn.setDoOutput(true);

            if (postDataBytes != null && postDataBytes.length > 0) {
                BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), "UTF-8"));
                bw.write(postData.toString());
                bw.flush();
                bw.close();

                //conn.getOutputStream().write(postDataBytes);
            }



            Reader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), encoding));
            StringBuilder sb = new StringBuilder("");
            for (int c; (c = in.read()) >= 0;) {
                sb.append((char)c);
            }
            return sb.toString();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } 
        return null;
    }

第一个注释掉的部分 (/*postData.append ..... encoding));*/) 是我调试的一部分,System.out.println("postData = " + postData.toString()); 在两种情况下都显示完全相同的内容(希伯来字符显示正确)

两个System.out.println("postDataBytes.... 也显示相同的内容(正确的希伯来字符)。

这个//conn.getOutputStream().write(postDataBytes); 注释掉的代码是我以前的版本(直到几个小时前),在调试时我把它改成了现有的。

现在在 ui servlet 中显示为

"race":"לול","flockId":"לול"

在服务器中显示为:

“种族”:“×\u009c×\u0095×\u009c”,“flockId”:“×\u009c×\u0095×\u009c”

(调用 s.o.p 时)

现在我又卡住了.....

----------编辑2------------------ -----

为了尝试了解问题到底出在哪里,我将 HTTP post 请求直接发送到服务器的 servlet。这样做时,我)仍然得到这个:

“种族”:“×\u009c×\u0095×\u009c”,“flockId”:“×\u009c×\u0095×\u009c”

这意味着问题出在服务器的 servlet 中。只是我找不到到底是什么问题
就像我之前写的那样,我在doPost(HttpServletRequest request, HttpServletResponse response) 中调用request.setCharacterEncoding("UTF-8");

有什么想法吗?

【问题讨论】:

  • 这部分正确吗? 'חגע'?
  • 它可能......我实际上不记得我在那里写了什么......我只是在我的编辑中添加了一个例子。非常感谢!

标签: javascript mysql servlets utf-8


【解决方案1】:

有些东西正在转换为“Unicode”,而不是“UTF-8”。我从\u0097(等)看到了这一点。但是,更糟糕的是,这不是一个有效的 Unicode“代码点”。

¢¢ 的 Mojibake

请提供示例希伯来语和相应的乱码。似乎有两件事合谋弄乱了您的文字;如果只完成一次转换,就很难进行逆向工程。

帮助调试情况的另一件事是SELECT HEX(col) ... 以查看存储的内容。

这个Q&A 可能有助于修复它。如果没有,请提供更多信息。

更多

(我正在使用 MySQL 的字符集来执行这项研究。这可能(或可能不)匹配相关文档中使用的编码。)

לול,utf8编码为D79CD795D79C;如果 Mojibaked 变成 לול。所以,我可以看到×9C95。但是如何让一些个字节通过,一些转换成unicode(\u...)是个谜。

如果您正在使用任何转换函数,请将其删除。

cp1250、cp1256、cp1257、latin1、latin2、latin5、latin7 将十六进制 D7 视为“×”。
希伯来语将十六进制 AA 视为 ×
× 的 utf8 编码是十六进制 C397

cp1250、cp1251、cp1256、cp1257、dec8、geostd8、希腊语、希伯来语、latin1、latin5、latin7 将十六进制 BB 视为 »
latin2 将十六进制 BB 视为 ť

\u0095 是“消息等待”。一般来说,\u009x 不应出现在文本中。

线索不匹配,所以我继续困惑于“你是如何从这里到那里的”。

【讨论】:

  • 我又做了一些刺伤。
【解决方案2】:

所以.....

问题解决了!!!!

我不确定问题是什么,但解决它的方法是切换setCharacterEncode("UTF-8");request.getMapParameter(); 的顺序

代替:

Map<String, String[]> map = request.getParameterMap();
request.setCharacterEncoding("UTF-8");  

我现在有:

request.setCharacterEncoding("UTF-8");          
Map<String, String[]> map = request.getParameterMap();

这样就解决了问题...

我真的不知道如何解释,如果有人知道,我会很高兴知道。

另外,javaScript 构造函数中的encodeURIComponent 是不必要的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-08
    • 1970-01-01
    • 2015-01-12
    • 2018-10-22
    • 2017-10-11
    • 2012-12-24
    • 2018-08-27
    相关资源
    最近更新 更多