问题:
安卓程序,通过servlet连接MySQL数据库,并实现查询和插入(修改,删除类似)。
其中遇到的最大的问题是:汉字乱码问题(查询条件有汉字乱码、servlet的汉字到数据乱码、安卓通过servlet方法数据库汉字乱码)
当所有的编码(客户端,服务端,数据库)都为UTF-8时,但是插入汉字依然为乱码。
1、安卓客户端中的汉字到servlet中为乱码。
当插入到数据库的汉字为乱码(而不是问号)时。
解决方法:
在安卓客户端将String中的汉字由UTF-8转码为ISO8859-1.
username = new String(((String) username).getBytes("UTF-8"),"iso8859-1");
在servlet服务端将String中的汉字由ISO8859-1转码为UTF-8.
username = new String(username.getBytes("iso8859-1"),"UTF-8");
至此,servlet中收到的汉字即为正确的汉字而不是乱码。
如果,此时插入到数据库中的汉字由乱码改成了问号,那么请看2.
2、servlet到数据库中为问号。
判断此种情况,可在servlet中的SQL语句直接赋值,而不是再获取。如果数据库中显示为问号时。
解决方法:
jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8
其中必须有 ?useUnicode=true&characterEncoding=utf8 而且不能有其他。
具体例子:
安卓客户端代码:
package com.linfeng;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List; import org.apache.http.HttpClientConnection;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils; import android.R.string;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
// private static final int REQUEST_CODE = 2;
HttpPost httpRequest = new HttpPost(UriAPI.HTTPCustomer);
EditText et_name;
EditText et_xuenian;
EditText et_xueqi;
TextView show_login;
Button btn_login;
Button btn_cancle;
ProgressDialog progressDialog;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 初始化登陆界面
btn_login = (Button) findViewById(R.id.btn_login);
btn_cancle = (Button) findViewById(R.id.btn_cancle);
et_name = (EditText) findViewById(R.id.et_name);
et_xuenian = (EditText) findViewById(R.id.xuenian);
et_xueqi = (EditText) findViewById(R.id.xueqi);
show_login = (TextView) findViewById(R.id.show_login);
progressDialog = new ProgressDialog(this);
btn_login.setOnClickListener(new OnClickListener() {
@SuppressWarnings("unchecked")
@Override
public void onClick(View v) {
// 通过AsyncTask类提交数据 异步显示
new AT().execute("20133079", "2016");
}
});
}
public class UriAPI {
/** 定义一个Uri **/
public static final String HTTPCustomer = "http://10.0.2.2:8080/JSONDemo/servlet/Insertdomo";
}
@SuppressWarnings("rawtypes")
class AT extends AsyncTask {
String result = "success";
private HttpURLConnection conn;
@Override
protected void onPreExecute() {
// 加载progressDialog
progressDialog.show();
}
@Override
protected Object doInBackground(Object... params_obj) {
CharSequence username ="20133078";
CharSequence suggest = "铁大jjk"; suggest = et_name.getText(); suggest=suggest.toString(); try {
username = new String(((String) username).getBytes("UTF-8"),"iso8859-1");
suggest = new String(((String) suggest).getBytes("UTF-8"),"iso8859-1");
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} if (!username.equals("") && !suggest.equals("")) {
// 请求数据
HttpPost httpRequest = new HttpPost(UriAPI.HTTPCustomer);
// 创建参数
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("username", username
.toString()));
params.add(new BasicNameValuePair("suggest", suggest.toString()
));
System.out.println(params);
// params.add(new BasicNameValuePair("flag","0"));
try {
// 对提交数据进行编码
httpRequest.setEntity(new UrlEncodedFormEntity(params,
HTTP.ISO_8859_1));
System.out.println(params);
System.out.println(httpRequest);
HttpResponse httpResponse = new DefaultHttpClient()
.execute(httpRequest);
// 获取响应服务器的数据
if (httpResponse.getStatusLine().getStatusCode() == 200) {
// 利用字节数组流和包装的绑定数据
byte[] data = new byte[2048];
// 先把从服务端来的数据转化成字节数组
data = EntityUtils
.toByteArray((HttpEntity) httpResponse
.getEntity());
// 再创建字节数组输入流对象
ByteArrayInputStream bais = new ByteArrayInputStream(
data);
// 绑定字节流和数据包装流
DataInputStream dis = new DataInputStream(bais);
// 将字节数组中的数据还原成原来的各种数据类型,代码如下:
result = new String(dis.readUTF());
Log.i("服务器返回信息:", result);
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
@Override
protected void onPostExecute(Object result) {
// 获得服务器返回信息成功后
System.out.print(result);
show_login.setText(result.toString()); //显示 success
// 取消进度条
progressDialog.cancel(); if(result.toString()=="success")
{
setContentView(R.layout.classlistselect);
}
}
}
}
服务端Servlet代码:
1、连接数据库db:
package db; import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; import exception.DbException;
public class DbUtils {
private final static String DRIVER="com.mysql.jdbc.Driver";
private final static String URL="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8";
private final static String NAME="root";
private final static String PWD="123456";
private static Connection conn=null;
public static Connection getConenction(){
try {
Class.forName(DRIVER);
conn=DriverManager.getConnection(URL, NAME, PWD);
} catch (ClassNotFoundException e) {
throw new DbException("");
} catch (SQLException e) {
throw new DbException("");
}catch (Exception e){
throw new DbException(e); }
return conn;
}
public static void freeDb(Connection conn,PreparedStatement pmst,ResultSet rs){
try {
if (rs!=null) {
rs.close(); }
} catch (Exception e) {
throw new DbException("");
}
try {
if (pmst!=null) {
pmst.close(); }
} catch (Exception e) {
throw new DbException("");
}
try {
if (conn!=null) {
conn.close(); }
} catch (Exception e) {
throw new DbException("");
} } }
2、servlet代码:
package servlet; import java.io.DataOutputStream;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import dao.Insertdom;
public class Insertdomo extends HttpServlet {
private static final long serialVersionUID = 314719472293387358L; @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String re="";
String username = req.getParameter("username");
String suggest = req.getParameter("suggest");
username = new String(username.getBytes("iso8859-1"),"UTF-8");
suggest = new String(suggest.getBytes("iso8859-1"),"UTF-8");
boolean flag = Insertdom.Add(username,suggest);
// try {
// resp.setCharacterEncoding("UTF-8");
// DataOutputStream output=new DataOutputStream(resp.getOutputStream());
// if ("20133079".equals(username) && "天上".equals(suggest)) {
// re = "suggest";
// }else{
// re = suggest;
// }
try {
resp.setCharacterEncoding("UTF-8");
DataOutputStream output=new DataOutputStream(resp.getOutputStream());
if (flag) {
re = "成功";
}else{
re = "失败";
}
output.writeUTF(re);
output.writeInt(1);
output.close();
System.out.print(re);
} catch (Exception e) {
e.printStackTrace();
} }
}
3、插入具体实现函数:
package dao; import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException; import db.DbUtils;
import exception.DbException; public class Insertdom {
static Connection conn = null;
/** */
static {
conn=DbUtils.getConenction(); }
private final static String SQL="insert into suggest(username,suggest) values (?,?)";
/**
* @throws UnsupportedEncodingException */
public static boolean Add(String username,String suggest) throws UnsupportedEncodingException{
PreparedStatement pmst = null;
int rs = 0;
boolean flag = true;
try {
pmst = conn.prepareStatement(SQL);
pmst.setString(1, username);
pmst.setString(2, suggest);
rs=pmst.executeUpdate();
} catch (SQLException e) { throw new DbException("查询无", e);
}
if (rs == 0) {
flag = false;
System.out.println("新增失败");
} else {
flag = true;
System.out.println("新增成功");
}
return flag;
}
}
这只是安卓通过servlet访问数据库的一种方法,还有更多的方法值得我们去学习。