码迷,mamicode.com
首页 > 移动开发 > 详细

Android(java)学习笔记212:中文乱码的问题处理(qq登录案例)

时间:2015-09-06 12:56:25      阅读:309      评论:0      收藏:0      [点我收藏+]

标签:

1.我们在之前的笔记中LoginServlet.java中,我们Tomcat服务器回复给客户端的数据是英文的"Login Success","Login Failed".

现在我们改成如下的汉字:

 1 package com.himi.web;
 2 
 3 import java.io.IOException;
 4 import javax.servlet.ServletException;
 5 import javax.servlet.annotation.WebServlet;
 6 import javax.servlet.http.HttpServlet;
 7 import javax.servlet.http.HttpServletRequest;
 8 import javax.servlet.http.HttpServletResponse;
 9 
10 /**
11  * Servlet implementation class LoginServlet
12  */
13 @WebServlet("/LoginServlet")
14 public class LoginServlet extends HttpServlet {
15     private static final long serialVersionUID = 1L;
16 
17     /**
18      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
19      */
20     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
21          String qq = request.getParameter("qq");
22          String password = request.getParameter("password");
23          System.out.println("qq:"+qq);
24          System.out.println("password:"+password);
25          
26          //模拟服务器操作,查询数据库,看qq和密码是否正确. response.getOutputStream()获得一个输出流,向浏览器写入数据(提示数据)
27          if("10086".equals(qq) && "123456".equals(password)) {
28              response.getOutputStream().write("登录成功".getBytes());
29          }else {
30              response.getOutputStream().write("登录失败".getBytes());
31          }
32          
33     }
34 
35 }

这时候,我们布署之前的Android手机端http程序到模拟器上,运行产生如下效果

技术分享

 

2.常见的乱码处理

(1)菱形里面有问号 : gbk的中文数据用utf-8表示的

 

Tomcat默认的编码是iso-8859-1的码表,没有中文,如果遇到了不认识的字符串就使用本地默认编码gbk;当我们把这些gbk编码数据通过http协议传递给手机Android客户端的时候,Android客户端的默认编码是utf-8.所以会出现这样的问题。

这个乱码解决问题的方式:在客户端或者服务器端任意一端(不能同时修改两端).比如服务器端把回复数据编码改成utf-8,要么就是客户端把接收到数据指定以gb2312

 

(2)中文用户名输入出现乱码

• 手机客户端

还是之前的qq登录的案例,这里输入中文:

技术分享

点击登录之后,服务器端接收到数据,显示乱码,效果如下:出现?乱码

技术分享

 

 • PC端浏览器

这里也是输入中文用户名,如下:

技术分享

 

结果出现乱码如下:出现的?乱码

技术分享

 

 

(3)PC端到服务器端的乱码问题解决:

     PC端到服务器端的乱码是由于之前客户端是以utf-8流的方式把中文用户名,传递给服务器端服务端默认编码是ios-8859-1,它是不能识别中文的。所以服务器端以ios-8859-1的方式显示数据,就会上面的问号乱码

解决办法:修改服务器端代码,如下:

技术分享

qq.getBytes("iso-8859-1"),这里必须指定iso-8859-1的方式,不然会默认是系统本地编码gb2312;

此时再次在浏览器提交数据,服务器端就不会出现乱码,如下:

技术分享

 

(4)GET客户端到服务器端的乱码问题解决:

上面只是解决PC端到服务器端的乱码出现的问题,但是客户端到服务器端的乱码还是没有解决,如下:

技术分享

 

这里我们知道get方式是组拼url路径的,提交的数据包含在这个路径下,提交的数据要是包含中文或者其他不合法字符就会转化,就如下:

技术分享

解决方法:拼接url的路径时候,对中文进行转化:

技术分享

 

 

(5)POST客户端到服务器端的乱码问题解决:

之前POST方式编写的QQ登录案例,直接布署程序到模拟器上会出现如下错误:

技术分享

 

解决办法:

  1 package com.himi.post;
  2 
  3 import java.io.BufferedReader;
  4 import java.io.File;
  5 import java.io.FileInputStream;
  6 import java.io.FileOutputStream;
  7 import java.io.InputStream;
  8 import java.io.InputStreamReader;
  9 import java.net.HttpURLConnection;
 10 import java.net.MalformedURLException;
 11 import java.net.URL;
 12 
 13 import android.app.Activity;
 14 import android.os.Bundle;
 15 import android.text.TextUtils;
 16 import android.util.Log;
 17 import android.view.View;
 18 import android.widget.CheckBox;
 19 import android.widget.EditText;
 20 import android.widget.Toast;
 21 
 22 public class MainActivity extends Activity {
 23     private static final String Tag = "MainActivity";
 24     private EditText et_qq;
 25     private EditText et_pwd;
 26     private CheckBox cb_remember;
 27 
 28     @Override
 29     protected void onCreate(Bundle savedInstanceState) {
 30         super.onCreate(savedInstanceState);
 31         setContentView(R.layout.activity_main);
 32         //查询关心的控件
 33         et_qq = (EditText) findViewById(R.id.et_qq);
 34         et_pwd = (EditText) findViewById(R.id.et_pwd);
 35         cb_remember = (CheckBox) findViewById(R.id.cb_remember);
 36         Log.i(Tag,"oncreate 被调用");
 37         //完成数据的回显。
 38         readSavedData();
 39     }
 40     //读取保存的数据
 41     private void readSavedData() {
 42         // getFilesDir() == /data/data/包名/files/  获取文件的路径 一般系统是不会清理的。 用户手工清理,系统会有提示。
 43         // getCacheDir()==  /data/data/包名/cache/ 缓存文件的路径 当系统内存严重不足的时候 系统会自动的清除缓存 用户手工清理系统没有提示
 44         File file = new File(getFilesDir(),"info.txt");
 45         if(file.exists()&&file.length()>0){
 46             try {
 47                 //FileInputStream fis = new FileInputStream(file);
 48                 FileInputStream fis =this.openFileInput("info.txt");
 49                 BufferedReader br = new BufferedReader(new InputStreamReader(fis));
 50                 //214342###abcdef
 51                 String info = br.readLine();
 52                 String qq = info.split("###")[0];
 53                 String pwd = info.split("###")[1];
 54                 et_qq.setText(qq);
 55                 et_pwd.setText(pwd);
 56                 fis.close();
 57             } catch (Exception e) {
 58                 e.printStackTrace();
 59             }
 60         }
 61     }
 62     /**
 63      * 登陆按钮的点击事件,在点击事件里面获取数据
 64      * @param view
 65      */
 66     public void login(View view){
 67         final String qq = et_qq.getText().toString().trim();
 68         final String pwd = et_pwd.getText().toString().trim();
 69         if(TextUtils.isEmpty(qq)||TextUtils.isEmpty(pwd)){
 70             Toast.makeText(this, "qq号码或者密码不能为空", 0).show();
 71             return;
 72         }
 73         //判断用户是否勾选记住密码。
 74         if(cb_remember.isChecked()){
 75             //保存密码
 76             Log.i(Tag,"保存密码");
 77             try {
 78 //                File file = new File(getFilesDir(),"info.txt");
 79 //                FileOutputStream fos = new FileOutputStream(file);
 80                 FileOutputStream fos = this.openFileOutput("info.txt", 0);
 81                 //214342###abcdef
 82                 fos.write((qq+"###"+pwd).getBytes());
 83                 fos.close();
 84                 Toast.makeText(this, "保存成功", 0).show();
 85             } catch (Exception e) {
 86                 e.printStackTrace();
 87                 Toast.makeText(this, "保存失败", 0).show();
 88             }
 89         }else{
 90             //无需保存密码
 91             Log.i(Tag,"无需保存密码");
 92         }
 93         
 94         //登录的操作,网络的请求
 95         new Thread() {
 96             public void run() {
 97                 //post请求提交数据
 98                 //String path = "http://localhost:8080/web/LoginServlet";这里不能写成localhost
 99                 try {
100                     String path = getString(R.string.serverip);
101                     URL url = new URL(path);
102                     HttpURLConnection conn = (HttpURLConnection) url.openConnection();
103                     //重要,记得设置请求方式post
104                     conn.setRequestMethod("POST");
105                     //重要,记得设置数据的类型
106                     conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
107                     String data = "qq="+URLEncoder.encode(qq,"utf-8")+"&password="+URLEncoder.encode(pwd,"utf-8");
108                     //重要,记得设置数据的长度
109                     conn.setRequestProperty("Content-Length", String.valueOf(data.length()));
110                     
111                     //重要,记得给服务器写数据
112                     conn.setDoOutput(true);//声明要给服务器写数据
113                     //重要,把数据写给服务器
114                     conn.getOutputStream().write(data.getBytes());
115                     
116                     int code = conn.getResponseCode();
117                     if(code == 200) {
118                         InputStream is = conn.getInputStream();
119                         String result = StreamTools.readStream(is);
120                         showToastInAnyThread(result);
121                     }else {
122                         showToastInAnyThread("请求失败");
123                     }
124                 } catch (Exception e) {
125                     e.printStackTrace();
126                     showToastInAnyThread("请求失败");
127                 }
128             };
129         }.start();
130         
131     }
132     
133     /**
134      * 显示土司 在主线程更新UI
135      * @param text
136      */
137     public void showToastInAnyThread(final String text) {
138         runOnUiThread(new Runnable() {
139             
140             public void run() {
141                 Toast.makeText(MainActivity.this, text, 0).show();
142                 
143             }
144         });
145     }
146 }

这时候我们输入提交数据给服务器就不会出现乱码,如下:

技术分享

 

 

 

(6)HttpClient-Get客户端到服务器端的乱码问题解决:

1 package com.himi.post;
  2 import java.io.BufferedReader;
  3 import java.io.File;
  4 import java.io.FileInputStream;
  5 import java.io.FileOutputStream;
  6 import java.io.InputStream;
  7 import java.io.InputStreamReader;
  8 import org.apache.http.HttpResponse;
  9 import org.apache.http.client.HttpClient;
 10 import org.apache.http.client.methods.HttpGet;
 11 import org.apache.http.impl.client.DefaultHttpClient;
 12 import android.app.Activity;
 13 import android.os.Bundle;
 14 import android.text.TextUtils;
 15 import android.util.Log;
 16 import android.view.View;
 17 import android.widget.CheckBox;
 18 import android.widget.EditText;
 19 import android.widget.Toast;
 20 public class MainActivity extends Activity {
 21     private static final String Tag = "MainActivity";
 22     private EditText et_qq;
 23     private EditText et_pwd;
 24     private CheckBox cb_remember;
 25     @Override
 26     protected void onCreate(Bundle savedInstanceState) {
 27         super.onCreate(savedInstanceState);
 28         setContentView(R.layout.activity_main);
 29         //查询关心的控件
 30         et_qq = (EditText) findViewById(R.id.et_qq);
 31         et_pwd = (EditText) findViewById(R.id.et_pwd);
 32         cb_remember = (CheckBox) findViewById(R.id.cb_remember);
 33         Log.i(Tag,"oncreate 被调用");
 34         //完成数据的回显。
 35         readSavedData();
 36     }
 37     //读取保存的数据
 38     private void readSavedData() {
 39         // getFilesDir() == /data/data/包名/files/  获取文件的路径 一般系统是不会清理的。 用户手工清理,系统会有提示。
 40         // getCacheDir()==  /data/data/包名/cache/ 缓存文件的路径 当系统内存严重不足的时候 系统会自动的清除缓存 用户手工清理系统没有提示
 41         File file = new File(getFilesDir(),"info.txt");
 42         if(file.exists()&&file.length()>0){
 43             try {
 44                 //FileInputStream fis = new FileInputStream(file);
 45                 FileInputStream fis =this.openFileInput("info.txt");
 46                 BufferedReader br = new BufferedReader(new InputStreamReader(fis));
 47                 //214342###abcdef
 48                 String info = br.readLine();
 49                 String qq = info.split("###")[0];
 50                 String pwd = info.split("###")[1];
 51                 et_qq.setText(qq);
 52                 et_pwd.setText(pwd);
 53                 fis.close();
 54             } catch (Exception e) {
 55                 e.printStackTrace();
 56             }
 57         }
 58     }
 59     /**
 60      * 登陆按钮的点击事件,在点击事件里面获取数据
 61      * @param view
 62      */
 63     public void login(View view){
 64         final String qq = et_qq.getText().toString().trim();
 65         final String pwd = et_pwd.getText().toString().trim();
 66         if(TextUtils.isEmpty(qq)||TextUtils.isEmpty(pwd)){
 67             Toast.makeText(this, "qq号码或者密码不能为空", 0).show();
 68             return;
 69         }
 70         //判断用户是否勾选记住密码。
 71         if(cb_remember.isChecked()){
 72             //保存密码
 73             Log.i(Tag,"保存密码");
 74             try {
 75 //                File file = new File(getFilesDir(),"info.txt");
 76 //                FileOutputStream fos = new FileOutputStream(file);
 77                 FileOutputStream fos = this.openFileOutput("info.txt", 0);
 78                 //214342###abcdef
 79                 fos.write((qq+"###"+pwd).getBytes());
 80                 fos.close();
 81                 Toast.makeText(this, "保存成功", 0).show();
 82             } catch (Exception e) {
 83                 e.printStackTrace();
 84                 Toast.makeText(this, "保存失败", 0).show();
 85             }
 86         }else{
 87             //无需保存密码
 88             Log.i(Tag,"无需保存密码");
 89         }
 90         
 91         //登录的操作,网络的请求
 92         new Thread() {
 93             public void run() {
 94                 //String path = "http://localhost:8080/web/LoginServlet";这里不能写成localhost
 95                 try {
 96                     //httpclient get请求提交数据
 97                     String path = getString(R.string.serverip)+"?qq="+URLEncoder.encode(qq)+"&password="+URLEncoder.encoder(pwd);
 98                     //1.打开浏览器
 99                     HttpClient client = new DefaultHttpClient();
100                     //2.输入地址
101                     HttpGet httpGet = new HttpGet(path);
102                     //3.敲回车
103                     HttpResponse response = client.execute(httpGet);
104                     int code = response.getStatusLine().getStatusCode();
105                     if(code == 200) {
106                         InputStream is = response.getEntity().getContent();
107                         String result = StreamTools.readStream(is);
108                         showToastInAnyThread(result);
109                     }else {
110                         showToastInAnyThread("请求失败,返回码是:"+code);
111                     }
112                     
113                     
114                 } catch (Exception e) {
115                     e.printStackTrace();
116                     showToastInAnyThread("请求失败");
117                 }
118             };
119         }.start();
120         
121     }
122     
123     /**
124      * 显示土司 在主线程更新UI
125      * @param text
126      */
127     public void showToastInAnyThread(final String text) {
128         runOnUiThread(new Runnable() {
129             
130             public void run() {
131                 Toast.makeText(MainActivity.this, text, 0).show();
132                 
133             }
134         });
135     }
136 }

(7)HttpClient-Post客户端到服务器端的乱码问题解决:

1 package com.himi.post;
  2 import java.io.BufferedReader;
  3 import java.io.File;
  4 import java.io.FileInputStream;
  5 import java.io.FileOutputStream;
  6 import java.io.InputStream;
  7 import java.io.InputStreamReader;
  8 import java.util.ArrayList;
  9 import java.util.List;
 10 import org.apache.http.HttpResponse;
 11 import org.apache.http.NameValuePair;
 12 import org.apache.http.client.HttpClient;
 13 import org.apache.http.client.entity.UrlEncodedFormEntity;
 14 import org.apache.http.client.methods.HttpPost;
 15 import org.apache.http.impl.client.DefaultHttpClient;
 16 import org.apache.http.message.BasicNameValuePair;
 17 import android.app.Activity;
 18 import android.os.Bundle;
 19 import android.text.TextUtils;
 20 import android.util.Log;
 21 import android.view.View;
 22 import android.widget.CheckBox;
 23 import android.widget.EditText;
 24 import android.widget.Toast;
 25 public class MainActivity extends Activity {
 26     private static final String Tag = "MainActivity";
 27     private EditText et_qq;
 28     private EditText et_pwd;
 29     private CheckBox cb_remember;
 30     @Override
 31     protected void onCreate(Bundle savedInstanceState) {
 32         super.onCreate(savedInstanceState);
 33         setContentView(R.layout.activity_main);
 34         //查询关心的控件
 35         et_qq = (EditText) findViewById(R.id.et_qq);
 36         et_pwd = (EditText) findViewById(R.id.et_pwd);
 37         cb_remember = (CheckBox) findViewById(R.id.cb_remember);
 38         Log.i(Tag,"oncreate 被调用");
 39         //完成数据的回显。
 40         readSavedData();
 41     }
 42     //读取保存的数据
 43     private void readSavedData() {
 44         // getFilesDir() == /data/data/包名/files/  获取文件的路径 一般系统是不会清理的。 用户手工清理,系统会有提示。
 45         // getCacheDir()==  /data/data/包名/cache/ 缓存文件的路径 当系统内存严重不足的时候 系统会自动的清除缓存 用户手工清理系统没有提示
 46         File file = new File(getFilesDir(),"info.txt");
 47         if(file.exists()&&file.length()>0){
 48             try {
 49                 //FileInputStream fis = new FileInputStream(file);
 50                 FileInputStream fis =this.openFileInput("info.txt");
 51                 BufferedReader br = new BufferedReader(new InputStreamReader(fis));
 52                 //214342###abcdef
 53                 String info = br.readLine();
 54                 String qq = info.split("###")[0];
 55                 String pwd = info.split("###")[1];
 56                 et_qq.setText(qq);
 57                 et_pwd.setText(pwd);
 58                 fis.close();
 59             } catch (Exception e) {
 60                 e.printStackTrace();
 61             }
 62         }
 63     }
 64     /**
 65      * 登陆按钮的点击事件,在点击事件里面获取数据
 66      * @param view
 67      */
 68     public void login(View view){
 69         final String qq = et_qq.getText().toString().trim();
 70         final String pwd = et_pwd.getText().toString().trim();
 71         if(TextUtils.isEmpty(qq)||TextUtils.isEmpty(pwd)){
 72             Toast.makeText(this, "qq号码或者密码不能为空", 0).show();
 73             return;
 74         }
 75         //判断用户是否勾选记住密码。
 76         if(cb_remember.isChecked()){
 77             //保存密码
 78             Log.i(Tag,"保存密码");
 79             try {
 80 //                File file = new File(getFilesDir(),"info.txt");
 81 //                FileOutputStream fos = new FileOutputStream(file);
 82                 FileOutputStream fos = this.openFileOutput("info.txt", 0);
 83                 //214342###abcdef
 84                 fos.write((qq+"###"+pwd).getBytes());
 85                 fos.close();
 86                 Toast.makeText(this, "保存成功", 0).show();
 87             } catch (Exception e) {
 88                 e.printStackTrace();
 89                 Toast.makeText(this, "保存失败", 0).show();
 90             }
 91         }else{
 92             //无需保存密码
 93             Log.i(Tag,"无需保存密码");
 94         }
 95         
 96         //登录的操作,网络的请求
 97         new Thread() {
 98             public void run() {
 99                 //post请求提交数据
100                 //String path = "http://localhost:8080/web/LoginServlet";这里不能写成localhost
101                 try {
102                     String path = getString(R.string.serverip);
103                     //1.打开浏览器
104                     HttpClient client = new DefaultHttpClient();
105                     //2.输入地址
106                     HttpPost httpPost = new HttpPost(path);
107                     //设置一个url的表单的数据
108                     List<NameValuePair> paramters = new ArrayList<NameValuePair>();
109                     paramters.add(new BasicNameValuePair("qq", qq));
110                     paramters.add(new BasicNameValuePair("password", pwd));
111                     httpPost.setEntity(new UrlEncodedFormEntity(paramters,"utf-8"));
112                     //3.敲回车
113                     HttpResponse response = client.execute(httpPost);
114                     int code = response.getStatusLine().getStatusCode();
115                     if(code == 200) {
116                         InputStream is = response.getEntity().getContent();
117                         String result = StreamTools.readStream(is);
118                         showToastInAnyThread(result);
119                     }else {
120                         showToastInAnyThread("请求失败,返回码是:"+code);
121                     }
122                     
123                 } catch (Exception e) {
124                     e.printStackTrace();
125                     showToastInAnyThread("请求失败");
126                 }
127             };
128         }.start();
129         
130     }
131     
132     /**
133      * 显示土司 在主线程更新UI
134      * @param text
135      */
136     public void showToastInAnyThread(final String text) {
137         runOnUiThread(new Runnable() {
138             
139             public void run() {
140                 Toast.makeText(MainActivity.this, text, 0).show();
141                 
142             }
143         });
144     }
145 }

 

Android(java)学习笔记212:中文乱码的问题处理(qq登录案例)

标签:

原文地址:http://www.cnblogs.com/hebao0514/p/4784685.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!