本篇文章采用apatche httpclient与远程服务器建立连接
服务端:
处理用户的Servelet只是前段控制器,它的作用主要有三个:
1.获取请求参数
2.调用业务逻辑组件的方法来处理用户请求
3.根据处理结果进行输出
由于Servelet都需要获取Spring容器中的业务逻辑组件,因此提供一个公共的基类,定义一个一个方法获取web应用中的spring容器。
package org.crazyit.auction.servlet.base;
import javax.servlet.*;
import javax.servlet.http.*;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.context.ApplicationContext;
public class BaseServlet extends HttpServlet
{
private ApplicationContext ctx;
public void init(ServletConfig config)
throws ServletException
{
super.init(config);
// 获取Web应用中的ApplicationContext实例
ctx = WebApplicationContextUtils
.getWebApplicationContext(getServletContext());
}
// 返回Web应用中的Spring容器
public ApplicationContext getCtx()
{
return this.ctx;
}
}
该Servelet基类中定义了一个getCtx()方法,通过该方法可以获得spring容器,服务器端的servelet只要继承这个基类就可以通过该方法获取spring容器
示例:处理登录的Servelet
package org.crazyit.auction.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import org.crazyit.auction.servlet.base.BaseServlet;
import org.crazyit.auction.service.AuctionManager;
import java.io.*;
import org.json.*;
@WebServlet(urlPatterns="/android/login.jsp")
public class LoginServlet extends BaseServlet
{
public void service(HttpServletRequest request ,
HttpServletResponse response)
throws IOException , ServletException
{
String user = request.getParameter("user");
String pass = request.getParameter("pass");
// 获取系统的业务逻辑组件
AuctionManager auctionManager = (AuctionManager)getCtx().getBean("mgr");
// 验证用户登录
int userId = auctionManager.validLogin(user , pass);
response.setContentType("text/html; charset=GBK");
// 登录成功
if (userId > 0)
{
request.getSession(true).setAttribute("userId" , userId);
}
try
{
// 把验证的userId封装成JSONObject
JSONObject jsonObj = new JSONObject()
.put("userId" , userId);
// 输出响应
response.getWriter().println(jsonObj.toString());
}
catch (JSONException ex)
{
ex.printStackTrace();
}
}
}
示例中@WebServelet指定了Servelet的url为
/android/login.jsp
<span style="white-space:pre"> </span>validLogin()方法用来处理用户登录。如果登录成功,程序将用户ID放入http session中,方便程序跟踪用户的状态。
客服端:
<span style="font-size:18px;">采用Apatche HttpClient与远程服务器通信,定义一个工具类对HttpClient进行封装,定义如下两个方法</span>
<span style="white-space:pre"> </span>GetRequest()发送get请求
<span style="white-space:pre"> </span>PostRequest()发送post请求
package org.crazyit.auction.client.util;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
public class HttpUtil
{
// 创建HttpClient对象
public static HttpClient httpClient = new DefaultHttpClient();
public static final String BASE_URL =
"http://192.168.1.88:8888/auction/android/";
/**
*
* @param url 发送请求的URL
* @return 服务器响应字符串
* @throws Exception
*/
public static String getRequest(final String url)
throws Exception
{
FutureTask<String> task = new FutureTask<String>(
new Callable<String>()
{
@Override
public String call() throws Exception
{
// 创建HttpGet对象。
HttpGet get = new HttpGet(url);
// 发送GET请求
HttpResponse httpResponse = httpClient.execute(get);
// 如果服务器成功地返回响应
if (httpResponse.getStatusLine()
.getStatusCode() == 200)
{
// 获取服务器响应字符串
String result = EntityUtils
.toString(httpResponse.getEntity());
return result;
}
return null;
}
});
new Thread(task).start();
return task.get();
}
/**
* @param url 发送请求的URL
* @param params 请求参数
* @return 服务器响应字符串
* @throws Exception
*/
public static String postRequest(final String url
, final Map<String ,String> rawParams)throws Exception
{
FutureTask<String> task = new FutureTask<String>(
new Callable<String>()
{
@Override
public String call() throws Exception
{
// 创建HttpPost对象。
HttpPost post = new HttpPost(url);
// 如果传递参数个数比较多的话可以对传递的参数进行封装
List<NameValuePair> params =
new ArrayList<NameValuePair>();
for(String key : rawParams.keySet())
{
//封装请求参数
params.add(new BasicNameValuePair(key
, rawParams.get(key)));
}
// 设置请求参数
post.setEntity(new UrlEncodedFormEntity(
params, "gbk"));
// 发送POST请求
HttpResponse httpResponse = httpClient.execute(post);
// 如果服务器成功地返回响应
if (httpResponse.getStatusLine()
.getStatusCode() == 200)
{
// 获取服务器响应字符串
String result = EntityUtils
.toString(httpResponse.getEntity());
return result;
}
return null;
}
});
new Thread(task).start();
return task.get();
}
}<strong style="font-size:18px;">
</strong>
用户登录客户端:
<span style="font-size:14px;">package org.crazyit.auction.client;
import java.util.HashMap;
import java.util.Map;
import org.crazyit.auction.client.util.DialogUtil;
import org.crazyit.auction.client.util.HttpUtil;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class Login extends Activity
{
// 定义界面中两个文本框
EditText etName, etPass;
// 定义界面中两个按钮
Button bnLogin, bnCancel;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
// 获取界面中两个编辑框
etName = (EditText) findViewById(R.id.userEditText);
etPass = (EditText) findViewById(R.id.pwdEditText);
// 获取界面中的两个按钮
bnLogin = (Button) findViewById(R.id.bnLogin);
bnCancel = (Button) findViewById(R.id.bnCancel);
// 为bnCancal按钮的单击事件绑定事件监听器
bnCancel.setOnClickListener(new HomeListener(this));
bnLogin.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
// 执行输入校验
if (validate()) //①
{
// 如果登录成功
if (loginPro()) //②
{
// 启动Main Activity
Intent intent = new Intent(Login.this
, AuctionClientActivity.class);
startActivity(intent);
// 结束该Activity
finish();
}
else
{
DialogUtil.showDialog(Login.this
, "用户名称或者密码错误,请重新输入!", false);
}
}
}
});
}
private boolean loginPro()
{
// 获取用户输入的用户名、密码
String username = etName.getText().toString();
String pwd = etPass.getText().toString();
JSONObject jsonObj;
try
{
jsonObj = query(username, pwd);
// 如果userId 大于0
if (jsonObj.getInt("userId") > 0)
{
return true;
}
}
catch (Exception e)
{
DialogUtil.showDialog(this
, "服务器响应异常,请稍后再试!", false);
e.printStackTrace();
}
return false;
}
// 对用户输入的用户名、密码进行校验
private boolean validate()
{
String username = etName.getText().toString().trim();
if (username.equals(""))
{
DialogUtil.showDialog(this, "用户账户是必填项!", false);
return false;
}
String pwd = etPass.getText().toString().trim();
if (pwd.equals(""))
{
DialogUtil.showDialog(this, "用户口令是必填项!", false);
return false;
}
return true;
}
// 定义发送请求的方法
private JSONObject query(String username, String password)
throws Exception
{
// 使用Map封装请求参数
Map<String, String> map = new HashMap<String, String>();
map.put("user", username);
map.put("pass", password);
// 定义发送请求的URL
String url = HttpUtil.BASE_URL + "login.jsp";
// 发送请求
return new JSONObject(HttpUtil.postRequest(url, map));
}
}</span>
上面activity的query()方法中两行粗体字代码用于向指定URL发送请求,并将服务器响应封装成JSONObject。