为什么UTF-8编码在简单的Java项目中工作而在Android中不工作?

时间:2014-12-29 13:19:23

标签: java android encoding utf-8

我遇到UTF-8字符编码问题。从mysql数据库通过服务器加载内容的我的android应用程序没有正确显示像(é,í,ü,ö,ä等)这样的特殊字符。

我尝试了以下内容:

  1. 我查看了我的数据库,看起来都不错。 (utf8_unicode_ci)
  2. 我创建了一个简单的Java项目,使用我自己的数据库框架直接在我的数据库上工作。一切看起来都不错!
  3. 我创建了一个简单的Java项目,使用相同的代码(AsyncTask除外)通过我的服务器从数据库中请求数据。一切看起来都不错!
  4. 我查看了服务器日志文件,即发送的响应 回到客户端看起来不错!
  5. 我看了一下传入的数据,字符串看起来很破!之后转换它,例如通过`new String(line.getBytes(),“utf-8”)'无效。
  6. 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");
    

    问题解决了: 该问题是由Webserver标头中缺少编码引起的。 我已将编码添加到标题中,现在它正常工作。 HttpServletResponse.setContentType( “text / html的”); HttpServletResponse.setCharacterEncoding( “UTF-8”);

    谢谢,伙计们。

2 个答案:

答案 0 :(得分:1)

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

String responseBody = EntityUtils.toString(entity);

它将正确地自动检测HTTP响应中使用的并在标头中指定的编码。

答案 1 :(得分:-1)

您可能需要更改

InputStreamReader isr = new InputStreamReader(instream);

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

虽然UTF-8已经是Android的默认字符集。