本篇文章采用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。