今天要学的例子是通过android 手机客户端登陆到服务器。验证是否登陆成功。
首先:我们在myEclipse 中新建一个web项目提供手机客户端的登陆请求,并做出响应,我们使用struts2.1.8。做一个简单的示例。
这个web服务可以接收post |get 的请求。代码如下:
package com.hkrt.action;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.Action;
public class LoginCheckAction implements Action{
private String userName;
private String password;
public String execute() throws Exception {
HttpServletRequest request = ServletActionContext.getRequest();
InputStream is = request.getInputStream();
byte [] result = readIS(is);
if(result.length>0){
Map<String,String> resuestMap = getRequestParams(new String(result));
if(!resuestMap.isEmpty()){
userName = resuestMap.get("userName");
password = resuestMap.get("password");
}
}else{
userName = request.getParameter("userName");
password = request.getParameter("password");
}
System.out.println("userName:"+userName+"\tpassword:"+password);
HttpServletResponse response = ServletActionContext.getResponse();
OutputStream os = response.getOutputStream();
if(!"zs".equals(userName) || !"123".equals(password)){
os.write(new String("-1").getBytes());
} else {
os.write(new String("1").getBytes());
}
response.setStatus(HttpServletResponse.SC_OK);
System.out.println("数据访问");
return null;
}
public static byte[] readIS(InputStream is) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buff = new byte[1024];
int length = 0;
while ((length = is.read(buff)) != -1) {
bos.write(buff, 0, length);
}
return bos.toByteArray();
}
// 以Post 请求时,返回请求一个map的请求参数
private Map<String,String> getRequestParams(String requestStr){
Map<String,String> maps = new HashMap<String, String>();
String [] strs = requestStr.split("&");
List<String> list = new ArrayList<String>();
for(String st:strs){
list.add(st);
}
for(String lis:list){
maps.put(lis.split("=")[0],lis.split("=")[1]);
}
return maps;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
配置strus.xml 文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="default" namespace="/actions" extends="struts-default">
<!-- 登陆 action -->
<action name="LoginCheckAction" class="com.hkrt.action.LoginCheckAction"/>
</package>
</struts>
现在服务器代码就写完了,没有与数据库进行交互。
以下。我们实现android 客户端登陆的代码:
页面如下:很难看...
代码实现的功能:记录用户名和密码,以get或post 方式请求服务。线程之间的数据交互,对UI进行绘制。
package com.hkrt.activity;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLEncoder;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Toast;
import com.hkrt.R;
public class LoginUserActivity extends Activity {
private static final String TAG_POST = "post 请求";
private EditText userNameEdit,passwordEdit;
private CheckBox checkPwd;//记录密码
private ImageButton login;//登陆按钮
private SharedPreferences sharedPreferences ;//保存用户名和密码的文件
private Editor editor;//编辑
private ProgressDialog proDialog; //进度条
private Handler loginHandler;//信息处理机
private String userName;
private String password;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login_user_activity);
initView();
remberMe();
login.setOnClickListener(submitListener);
loginHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
Bundle bundle = msg.getData();
boolean loginResult = (Boolean)bundle.get("isNetError");//只获取登陆失败
if(proDialog != null){
proDialog.dismiss();
}
boolean isNet = isNetWorkAvailable(LoginUserActivity.this);
if(!isNet){
Toast.makeText(LoginUserActivity.this, "当前网络不可用", Toast.LENGTH_SHORT).show();
}
if(!loginResult) {
Toast.makeText(LoginUserActivity.this, "错误的用户名或密码", Toast.LENGTH_SHORT).show();
}
super.handleMessage(msg);
}
};
}
//查测网络是否连接 需要添加连网权限 返回true 表示联网 返回false 表示没有联网 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
public static boolean isNetWorkAvailable(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
return info != null && info.isConnected();
}
//初始化UI组件
private void initView(){
userNameEdit = (EditText)this.findViewById(R.id.username_edit);
passwordEdit = (EditText)this.findViewById(R.id.password_edit);
checkPwd = (CheckBox)this.findViewById(R.id.checkPwd);
login = (ImageButton)this.findViewById(R.id.login);
}
//记录密码
private void remberMe(){
sharedPreferences= getSharedPreferences("login",Context.MODE_PRIVATE);
editor = sharedPreferences.edit();//获取编辑器
String userName = sharedPreferences.getString("name","");
String pwd = sharedPreferences.getString("pwd","");
userNameEdit.setText(userName);
passwordEdit.setText(pwd);
if(userName!=null && !userName.equals("")){
checkPwd.setChecked(true);
}
}
//登陆事件
private OnClickListener submitListener = new OnClickListener() {
public void onClick(View v) {
userName = userNameEdit.getText().toString();
password=passwordEdit.getText().toString();
if(checkPwd.isChecked()){
// 编辑配置
editor.putString("name",userName);
editor.putString("pwd",password);
editor.commit();//提交修改
}else{
editor.putString("name",null);
editor.putString("pwd", null);
editor.commit();//提交修改
}
proDialog = ProgressDialog.show(LoginUserActivity.this,"请稍候","正在登陆...", true, true);
Thread loginThread = new Thread(new LoginFailureHandler());
loginThread.start();
}
};
// 验证是否登陆成功
private class LoginFailureHandler implements Runnable{
@Override
public void run() {
boolean loginState = loginActionMethodPost(userName,password);
if(loginState){
Intent intent = new Intent(LoginUserActivity.this,LoginUserSuccessActivity.class);
Bundle bun = new Bundle();
bun.putString("userName",userName);
bun.putString("password",password);
intent.putExtras(bun);
startActivity(intent);
proDialog.dismiss();
}else{
Message message = new Message();
Bundle bundle = new Bundle();
bundle.putBoolean("isNetError",loginState);
message.setData(bundle);
loginHandler.sendMessage(message);
}
}
}
//请求登陆 get 方式
private boolean loginActionMethodGet(String name,String pwd){
BufferedInputStream bufIn = null;
boolean login =false;
String validateURL="http://10.0.2.2:8080/androidService/actions/LoginCheckAction?userName=" + name + "&password=" +pwd;
try {
URL url = new URL(validateURL);
HttpURLConnection httpConn = (HttpURLConnection)url.openConnection();
httpConn.setConnectTimeout(5000);
httpConn.setRequestMethod("GET");
httpConn.connect();
bufIn = new BufferedInputStream(httpConn.getInputStream());
if(httpConn.getResponseCode()==HttpURLConnection.HTTP_OK){
byte [] body = new byte [1];
bufIn.read(body);
String loginState = new String(body);
if(loginState.equals("1")){ //返回1登陆成功 -1登陆失败
login =true;
}else{
login =false;
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(bufIn!=null){
try {
bufIn.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return login;
}
// 登陆的 post 方式
private boolean loginActionMethodPost(String name, String pwd) {
boolean login = false;
// Post方式请求
String validateURL = "http://10.0.2.2:8080/androidService/actions/LoginCheckAction";
// 请求的参数转换为byte数组
String params;
try {
params = "userName=" + URLEncoder.encode(name, "UTF-8") + "&password=" + URLEncoder.encode(pwd,"UTF-8");
byte[] postData = params.getBytes();
// 新建一个URL对象
URL url = new URL(validateURL);
// 打开一个HttpURLConnection连接
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
// 设置连接超时时间
urlConn.setConnectTimeout(5 * 1000);
// Post请求必须设置允许输出
urlConn.setDoOutput(true);
// Post请求不能使用缓存
urlConn.setUseCaches(false);
// 设置为Post请求
urlConn.setRequestMethod("POST");
urlConn.setInstanceFollowRedirects(true);
// 配置请求Content-Type
urlConn.setRequestProperty("Content-Type","application/x-www-form-urlencode");
// 开始连接
urlConn.connect();
// 发送请求参数
DataOutputStream dos = new DataOutputStream(urlConn.getOutputStream());
dos.write(postData);
dos.flush();
dos.close();
// 判断请求是否成功
if (urlConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
// 获取返回的数据
byte[] data = readIS(urlConn.getInputStream());
if(data.length>0){
String loginState = new String(data);
if (loginState.equals("1")) {
login = true;
}
Log.i(TAG_POST, "Post请求方式成功,返回数据如下:");
Log.i(TAG_POST, new String(data, "UTF-8"));
}
} else {
Log.i(TAG_POST, "Post方式请求失败");
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
}
return login;
}
//读取服务器返回的记录
public static byte[] readIS(InputStream is) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buff = new byte[1024];
int length = 0;
while ((length = is.read(buff)) != -1) {
bos.write(buff, 0, length);
}
bos.flush();
bos.close();
return bos.toByteArray();
}
}
注:服务器的请求路径,由127.0.01 改成10.0.2.2
以上android 客户端登陆代码可以使用apache 公司的HttpClient.代码格式如下:
// 使用Apache 提供的httpClient 发送get 请求
private boolean loginActionMethodHttpGet(String name,String pwd){
BufferedInputStream bufIn = null;
boolean login =false;
String validateURL="http://10.0.2.2:8080/androidService/actions/LoginCheckAction?userName=" + name + "&password=" +pwd;
HttpGet get = new HttpGet(validateURL);
HttpClient httpClient = new DefaultHttpClient();
try {
HttpResponse httpResponse = httpClient.execute(get);
HttpEntity entity = httpResponse.getEntity();
if(entity!=null){
bufIn = new BufferedInputStream(entity.getContent());
byte [] body = new byte [1];
bufIn.read(body);
String loginState = new String(body);
if(loginState.equals("1")){ //返回1登陆成功 -1登陆失败
login =true;
}else{
login =false;
}
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return login;
}
// 使用Apache 提供的httpClient 发送 post 请求
private boolean loginActionMethodHttpPost(String name,String pwd){
boolean login =false;
String validateURL = "http://10.0.2.2:8080/androidService/actions/LoginCheckAction";
HttpPost httpPost = new HttpPost(validateURL);
List<NameValuePair> params = new ArrayList<NameValuePair>();
HttpClient httpClient = new DefaultHttpClient();
try {
params.add(new BasicNameValuePair("userName", name));
params.add(new BasicNameValuePair("password", pwd));
httpPost.setEntity(new UrlEncodedFormEntity(params,HTTP.UTF_8));
HttpResponse httpResponse = httpClient.execute(httpPost);
if(httpResponse.getStatusLine().getStatusCode()==200){
String loginState = EntityUtils.toString(httpResponse.getEntity());
System.out.println("apache post:"+loginState);
if(loginState.equals("1")){ //返回1登陆成功 -1登陆失败
login =true;
}else{
login =false;
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return login;
}