本文通过对Android手机访问Web服务器的API的分析和实践,提出了一种解决手机终端和Web服务器交互提取各种类型数据的清晰有效方法,扩展了Android平台在访问Web服务器进行交互时的解析数据能力,给移动商务软件开发人员在开发数据交互实践过程提供了参考。
1 手机客户端向Web应用服务器发送请求信息
下面以者实际开的Android手机终端登录功能为案例来介绍如何利用Sun公司提供的java数据流和过滤流结合Android提供的API来提取来自Web服务器端不同类型的数据。
1)首先引用所需要的各种API
在Android手机终端开发应用程序时,首先需要利用Google和Sun公司提供的必要类包(API),包括Http通信协议下的类org.apache.http.*;手机端端类org.apache.http.client.*;消息类org.apache.http.message.*; 数据流类java.io.*;交互界面类java.util.*; android.app.Activity;操作描述类android.content.*;键值处理类android.os.Bundle;日志类android.util.Log;显示组件类android.view.*;和界面类android.widget.*等。
2)定义访问网站的URL
public class UriAPI {
public static final String TTPCustomer
="http://192.168.157.100:8028/JSHWDemo/servlet/CustomerServlet";}
3)创建Android程序界面类
下面创建一个手机界面,需要继承Android提供的Activity类,在该类中创建提交给Web服务器的数据的HttpPost对象,覆盖Activity类的方法onCreate(Bundle b),创建事件监听器OnClickListener对象,在其中实现onClick(View v)方法,再把该事件监听器注册到相应的事件源loginButton上。主要代码如下
public class LoginActivity extends Activity {
private static final int REQUEST_CODE = 2;
HttpPost httpRequest=new HttpPost(UriAPI.HTTPCustomer);
Button loginButton;
Button cancael;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
loginButton=(Button) findViewById(R.id.login);
//注册监听器对象
loginButton.setOnClickListener(new OnClickListener(){
CharSequence username="";
CharSequence password="";
public void onClick(View v)
{
//下面准备需要提交的数据,从手机界面抓取下来
EditText ev_username=(EditText)findViewById(R.id.username);
username=ev_username.getText();
EditText ev_password=(EditText)findViewById(R.id.p_w);
password=ev_password.getText();
4)创建HttpPost对象
HttpPost对象的主要作用是将Android手机端的数据提交给Web应用服务器,为此Android提供了很好的API,我们就利用Android和Sun公司提供的这些类把需要提交给服务器的数据(NameValuePair对象)保存到一个List对象中,主要代码如下
if(!username.equals("")&&!password.equals("")){
//创建HttpPost对象
HttpPost httpRequest=new HttpPost(UriAPI.HTTPCustomer);
List<NameValuePair> params=new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("username", username.toString()));
params.add(new BasicNameValuePair("password", password.toString()));
params.add(new BasicNameValuePair("flag", "0"));
5)设置数据编码方式
Android手机在将准备好的数据发送到Web服务器之前,需要对数据的编码进行规定,这样服务器在接收到这些数据后,就会根据发送过去的文字编码处理和显示,代码如下
try{
httpRequest.setEntity(new UrlEncodedFormEntity(params,HTTP.UTF_8));
6)提交HttpPost对象和获取服务器HttpResponse响应数据
完成前面的工作,就该将数据提交给Web应用服务器了,在应用服务接收Android手机提交的数据后,经过处理,将要返回(响应)给Android手机的数据打包到一个HttpResponse对象中,发回给手机,代码如下
HttpResponse httpResponse=new DefaultHttpClient().execute(httpRequest);
}
}catch(ClientProtocolException e){e.printStackTrace();}
catch (UnsupportedEncodingException e) {e.printStackTrace();}
catch (IOException e) {e.printStackTrace();}
到此,Android平台的通信任务已完成,即将Web服务器相应过来的数据交给了httpResponse对象,剩下来的工作就是如何将Web服务器响应过来的数据从httpResponse对象中取出来。
2 手机终端提取服务器端的响应数据
1)获取响应服务器的数据
从Web服务器响应到手机终端的数据一般打包在一个字节数组中,关键是这个字节数组中可能包含了各种不同的数据类型,为此,需要采取Java数据流和过滤流的方法从字节数据中取出各种类型的数据,这是本文的介绍的关键技术,代码如下
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);
将字节数组中的数据还原成原来的各种数据类型 ,代码如下
user=new String(dis.readUTF());
到此手机终端从Web服务器获取了所有类型的数据,剩下的任务就是将这些数据进一步交给Android手机终端View组件[3],在手机界面上显示给用户,这方面的内容不再赘述。
3 服务器端接收和响应Android手机终端请求
在Android手机终端发送请求后,接收请求的Web服务器端会根据请求的数据信息进行运算,然后把运算结果响应给手机客户端。下面介绍Web服务器如何实现这一过程的。
3.1采用http的Post方法接收数据
1)引用所需API
在Web端开发应用程序时,首先需要利用Sun公司提供的必要类包(API),包括数据流类java.io.*;交互界面类java.util.*;数据通信端口类javax.servlet.*;通信协议类javax.servlet.http.*;用Spring架构通过XML文件注入数据对象类org.springframework.web.context.*; org.springframework.web.context.support.*; service.CustomerService;等。
2)创建Servlet类数据端口
创建Servlet对象就是创建了Web应用服务器和连接互联网上所用客户端通信设备的数据接收和发送端口,主要代码如下
public class CustomerServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String username=request.getParameter("username");
String password=request.getParameter("password");
response.setContentType(CONTENT_TYPE );
3)访问持久层检索数据
这里应用已经完善的Spring管理事务的对象方法来获取持久层的数据,主要代码如下
try{
customer=cusDao.login(username,password);
if(customer!=null){//登录成功
output.writeUTF(customer.getUsername());
}
else {//登录失败
output.writeUTF("No");
}
}catch(Exception e){e.printStackTrace();}
4)创建输出流数据流对象
这里创建的输出流对象主要是把响应的数据发送到手机端,由于可能是不同类型的数据,所以采用DataOutputStream对象来处理,用输出过滤流对象[4]将不同类型的数据返回手机终端,主要代码如下
DataOutputStream output = new DataOutputStream( response.getOutputStream() );
output.writeUTF("服务器端数据:用户名:"+username);
output.writeUTF("服务器端数据:密 码:"+password);
output.writeInt(1);
output.close();
}
3.2 配置服务器端组件集成文件(XML)
Web应用服务器端用到的是SSH架构[5]技术,服务器的业务逻辑已经成熟,我们只需要将Spring的业务通过前述的Servlet进行封装,就可以将所有的Spring管理的事物也业务通过Servlet和Android手机进行交互,方法是在Spring的ApplicationContext.xml文件中增加下面的配置即可
ApplicationContext.xml文件主要配置如下
<beans>
<!-- 下面是手机终端通过Spring访问网站的必配内容 -->
<bean id="CustomerServlet" class="com.bai.android.servlet.CustomerServlet">
<property name="cusDao">
<!—将Spring业务交给Servlet对象—>
<ref bean="customerServiceTarget"/>
</property>
</bean>
</beans>
这样服务器响应给手机终端的数据处理部分完毕,一次交互过程完成。
Android提供的API仅仅把从Web服务器中的数据响应到手机终端的HttpResponse对象中,接着将该对象中的数据转化成字节数组,由于响应过来的数据可能是各种不同的类型,都包含在该字节数组中,我们要将自己数组中的数据还原成服务器端原有的数据类型,就要采用别的方法,于是我们采用了sun公司提供的ByteArrayInputStream[6]过滤流和DataInputStream流绑定的方法,利用DataInputStream提供的各种readXxx()方法,就可以把Web服务器端发过来的不同数据类型Xxx数据提取出来,然后交给Android提供View[7]对象在界面上进行处理。这样就为Android手机访问Web服务器提取不同类型的数据提供了技术构架,为Android和其他种类的手机开发人员提供了参考。