java - 为什么 UTF-8 编码在简单的 Java 项目中可以工作,但在 Android 中却不起作用?

标签 java android encoding utf-8

我在使用 UTF-8 字符编码时遇到问题。我的 Android 应用程序通过服务器从 mysql 数据库加载内容,但未正确显示特殊字符,例如(é、í、ü、ö、ä 等)。

我尝试过以下方法:

  1. 我查看了我的数据库,一切看起来都很好。 (utf8_unicode_ci)
  2. 我创建了一个简单的 Java 项目,使用我自己的数据库框架直接在我的数据库上工作。一切看起来都不错!
  3. 我创建了一个简单的 Java 项目,使用相同的代码(AsyncTask 除外)通过我的服务器从数据库请求数据。一切看起来都不错!
  4. 我查看了服务器日志文件以及发送的响应 返回给客户看起来不错!
  5. 我看了一下传入的数据,字符串看起来断了!!!之后进行转换,例如通过 `new String(line.getBytes(), "utf-8")' 不起作用。

Number 5 对于普通的 java 项目来说看起来不错,但我的 Android 应用程序遇到了麻烦。 为此,我使用以下代码:

public class Sender extends AsyncTask<Object, String, Object> {

    private static final String LOG_CLASS = Sender.class.getSimpleName();

    private static final String host = "xxx";
    private static final String port = "8080";
    private static final String serverUrl = "http://" + host + ":" + port + "/WebService/HomeServlet";


    @Override
    protected Object doInBackground(Object ... request) {

        final HttpClient httpclient = new DefaultHttpClient();
        final HttpPost httppost = new HttpPost(serverUrl);

        final List<NameValuePair> params = new ArrayList<NameValuePair>(2);
        params.add(new BasicNameValuePair("SOAP", WsUtils.parseObjectToSoap(request[0])));

        try {
            httppost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
            HttpResponse response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();

            if (entity != null) {
                InputStream instream = entity.getContent();
                try {
                    Log.i(LOG_CLASS, "Calling Server: " + serverUrl);

                    InputStreamReader isr = new InputStreamReader(instream, "UTF-8");
                    BufferedReader reader = new BufferedReader(isr);

                    final StringBuilder soapMessage = new StringBuilder();

                    String line;
                    while ((line = reader.readLine()) != null) {
                        Log.i(LOG_CLASS, "xxxxxxxx: " + new String(line.getBytes(), "utf-8"));
                        soapMessage.append(line);
                    }

                    final String fullQualifiedClassName = WsUtils.identifySoapMessage(soapMessage.toString());
                    final Object parsedSoapCall = WsUtils.parseSoapToObject(fullQualifiedClassName, soapMessage.toString());

                    return parsedSoapCall;

                } finally {
                    instream.close();
                }
            }
        } catch (UnsupportedEncodingException e) {
            Log.e(LOG_CLASS, "Encoding is not supported: " + e.getStackTrace());
        } catch (ClientProtocolException e) {
            Log.e(LOG_CLASS, "ClientProtocolException: " + e.getStackTrace());
        } catch (IOException e) {
            Log.e(LOG_CLASS, "IOException: " + e.getStackTrace());
        }


        Log.e(LOG_CLASS, "Error while loading data from Server");
        return null;
    }

}

服务器的这一部分正在发送响应。日志消息显示没有编码问题。

public class HomeServlet extends HttpServlet {

    private static final long serialVersionUID = 7376640150158278177L;

    public static final Logger LOG = Logger.getLogger(HomeServlet.class);
    private Processing processing = new Processing();

        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

            final String soapMessage = req.getParameter("SOAP");

            /* do some work */

            /* Process request (Database processing etc.) */
            final String response = processing.process(parsedSoapCall);
            LOG.info("Incoming request processed, back to client: " + response);

            /* Sending response back to client */
            if (null != response) {
                final PrintWriter writer = resp.getWriter();
                writer.println(response);
            }

        }

    }

DataBase 类的连接字符串:

con = DriverManager.getConnection("jdbc:mysql://" + dbHost + ":" + dbPort + "/" + dbName + "?user=" + dbUserName + "&password=" + dbPassword + "&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&autoReconnect=true");

问题已解决: 该问题是由于 Web 服务器 header 中缺少编码引起的。 我已将编码添加到 header 中,现在工作正常。 HttpServletResponse.setContentType("text/html"); HttpServletResponse.setCharacterEncoding("UTF-8");

谢谢大家。

最佳答案

不要使用 InputStreamInputStreamReader 逐行从实体中获取 String,而是尝试使用:

String responseBody = EntityUtils.toString(entity);

它将正确自动检测 HTTP 响应中使用的编码以及 header 中指定的编码。

关于java - 为什么 UTF-8 编码在简单的 Java 项目中可以工作,但在 Android 中却不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27689691/

相关文章:

Java:JFileChooser 获取国际文件名

android - 错误: package androidx.生命周期在flutter中不存在

android - 从 org.apache.http.HttpResponse 获取建议的文件名

Perl:从文件导入包含 ÅäÖ 的文本

encoding - JSTL 可以转换以 UTF-8 编码的 XML 吗?

java - selectOneRadio 的 JSF 转换错误

java - 生成唯一 ID

java - 需要有关未经检查的操作java的帮助

java - 在 Android (Java) 中使用硬件组件

Ruby C 扩展异常消息编码