与Web服务器交互:
如果手机要想与 web 容器交互的话,那么就必须依靠 Http 协议完成。
一、通过地址重新访问动态 Web
首先我们需要建立一个 Web 程序,现在为了说明问题,我们简单见一个 Servlet ,然后返回 true or false 即可
服务器端: AndroidServlet.java
package com.iflytek.demo; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class AndroidServlet */ public class AndroidServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * Default constructor. */ public AndroidServlet() { // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse * response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub //http://IP:8080/09AndroidWeb/AndroidServlet?name=xdwang&password=1111 String name = request.getParameter("name"); String password = request.getParameter("password"); if ("xdwang".equals(name) && "1111".equals(password)) { response.getWriter().println("true"); } else { response.getWriter().println("false"); } } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse * response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub } }
客户端:
Web01_Activity.java
package com.iflytek.demo; import java.net.HttpURLConnection; import java.net.URL; import android.app.Activity; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.widget.TextView; public class Web01_Activity extends Activity { private TextView infoTxt; public Handler handler = new Handler() { @Override public void handleMessage(android.os.Message msg) { super.handleMessage(msg); switch (msg.what) { case 1: infoTxt.setText(msg.obj.toString()); break; default: break; } } }; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); infoTxt = (TextView) super.findViewById(R.id.info); this.HttpHelper(); } private void HttpHelper() { final AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() { @Override protected void onPostExecute(String result) { final String temp = result; Thread thread = new Thread(new Runnable() { @Override public void run() { Message msg = new Message(); msg.what = 1; msg.obj = temp; handler.sendMessage(msg); } }); thread.start(); } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected String doInBackground(Void... arg0) { boolean flag = false; // 成功与否的标记 try { URL url = new URL("http", "IP", 8080, "/09AndroidWeb/AndroidServlet?name=xdwang&password=1111"); HttpURLConnection conn = (HttpURLConnection) url .openConnection(); byte data[] = new byte[512];// 开辟一个空间 int len = conn.getInputStream().read(data); // 输入流读取 if (len > 0) { // 已经读取到内容 String temp = new String(data, 0, len).trim(); flag = Boolean.parseBoolean(temp); // 取出里面的boolean型数据 } conn.getInputStream().close(); } catch (Exception e) { return "WEB服务器连接失败!"; } if (flag) { return "用户登录成功!"; } else { return "用户登录失败!"; } } }; task.execute(); } }
AndroidManifest.xml需要添加网络访问权限
<uses-permission android:name="android.permission.INTERNET" />
总结,这种方式是地址重写的方式完成,但是我们知道地址重写是 Get 请求方式,从上面的 Servlet 类的处理也可以看出是 Get 请求,但是这种方式会收到地址传输的限制,所以这时候我们也可以使用 post 请求方式提交。
二、 POST 请求
Get 请求与 Post 请求最大的区别在于一个地址显示,一个不显示,具体可以看我写的 GET 与 POST 请求 。 可是如何在 Android 中实现 post 请求呢?严格来说,之前的程序并不标准,地址重写问题较多。
使用 POST 提交访问动态 WEB 所需要的操作类:
由于 WEB 连接采用的是 HTTP 操作协议进行的,所以用户想要发送请求( POST 、 GET )则可以使用 org.apache.http.client.methods.HttpPost 类或者是 org.apache.http.client.methods.HttpGet 类进行。
当用户成功的向 Web Server 端发送请求后,所有返回的数据将使用 org.apache.http.HttpResponse 接口保存。
当用户使用 HttpResponse 的 getEntity() 方法接受所有返回数据之后,可以使用 EntityUtils 类进行处理,而且由于 HttpResponse 是一个接口,所以要想实例化此接口,就要使用 org.apache.http.impl.client.DefaultHttpClient 类完成。
由于在 Web Server 上所提供的方法需要参数的传递,所以所有的参数都要使用 org.apache.http.message.BasicName.ValuePair 类进行封装。
除了处理好参数之外,还需要处理请求时的所需要的编码,通用的编码为 UTF-8 ,而要想指定此编码则必须使用 org.apache.http.client.entry.UrlEncodedFormEntity 类完成。
此时把服务器端的 doPost 中再去调用 doGet 方法:
客户端 Web02_Activity.java
package com.iflytek.demo; import java.util.ArrayList; import java.util.List; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; 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.app.Activity; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.widget.TextView; public class Web02_Activity extends Activity { private TextView infoTxt = null; private static final String URL = "http://IP:8080/09AndroidWeb/AndroidServlet"; // 请求地址 public Handler handler = new Handler() { @Override public void handleMessage(android.os.Message msg) { super.handleMessage(msg); switch (msg.what) { case 1: infoTxt.setText(msg.obj.toString()); break; default: break; } } }; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); this.infoTxt = (TextView) super.findViewById(R.id.info); this.HttpHelper(); } private void HttpHelper() { final AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() { @Override protected void onPostExecute(String result) { final String temp = result; Thread thread = new Thread(new Runnable() { @Override public void run() { Message msg = new Message(); msg.what = 1; msg.obj = temp; handler.sendMessage(msg); } }); thread.start(); } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected String doInBackground(Void... arg0) { boolean flag = false; // 成功与否的标记 try { HttpPost request = new HttpPost(URL); List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("name", "xdwang")); params.add(new BasicNameValuePair("password", "1111")); request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8)); HttpResponse response = new DefaultHttpClient() .execute(request); if (response.getStatusLine().getStatusCode() != 404) { // 现在已经发现了数据了 flag = Boolean.parseBoolean(EntityUtils.toString( response.getEntity()).trim()); } } catch (Exception e) { return "WEB服务器连接失败!"; } if (flag) { return "用户登录成功!"; } else { return "用户登录失败!"; } } }; task.execute(); } }
三、网络读取图片
服务器端:
先设计一个返回图片流的工具类
ImageUtil.java
package com.iflytek.util; import java.awt.image.BufferedImage; import java.io.FileInputStream; import java.io.IOException; import java.text.MessageFormat; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; public class ImageUtil { /** * @descrption * @author xdwang * @create 2012-11-16下午8:35:36 * @param response * @param path * 文件路径 * @param type * 图片类型 */ public static void showImage(HttpServletResponse response, String path, String type) { try { ServletOutputStream outStream = response.getOutputStream();// 得到向客户端输出二进制数据的对象 FileInputStream fis = new FileInputStream(path); // 以byte流的方式打开文件 // 读数据 byte data[] = new byte[1000]; while (fis.read(data) > 0) { outStream.write(data); } fis.close(); response.setContentType(MessageFormat.format("image/{0}", type)); // 设置返回的文件类型 outStream.write(data); // 输出数据 outStream.close(); } catch (IOException e) { e.printStackTrace(); } } /** * @descrption * @author xdwang * @create 2012-11-16下午8:35:48 * @param response * @param data * byte数组 * @param type * 图片类型 */ public static void showImage(HttpServletResponse response, byte[] data, String type) { try { ServletOutputStream outStream = response.getOutputStream();// 得到向客户端输出二进制数据的对象 // 读数据 outStream.write(data); response.setContentType(MessageFormat.format("image/{0}", type)); // 设置返回的文件类型 outStream.write(data); // 输出数据 outStream.close(); } catch (IOException e) { e.printStackTrace(); } } }
AndroidServlet.java
package com.iflytek.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.iflytek.util.ImageUtil; /** * Servlet implementation class AndroidServlet */ public class AndroidServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * Default constructor. */ public AndroidServlet() { // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse * response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse * response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub ImageUtil.showImage(response, getServletContext().getRealPath("Java.jpg"), "jpeg"); } }
Android客户端:
Web03_Activity.java
package com.iflytek.demo; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.widget.ImageView; public class Web03_Activity extends Activity { private ImageView iamgeView = null; private static final String PATH = "http://IP:8080/09AndroidWeb/Java.jpg"; // 请求地址 private Bitmap bitmap; public Handler handler = new Handler() { @Override public void handleMessage(android.os.Message msg) { super.handleMessage(msg); switch (msg.what) { case 1: try { iamgeView.setImageBitmap(bitmap); } catch (Exception e) { } break; default: break; } } }; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); this.iamgeView = (ImageView) super.findViewById(R.id.img); this.HttpHelper(); } private void HttpHelper() { final AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() { @Override protected void onPostExecute(String result) { Thread thread = new Thread(new Runnable() { @Override public void run() { Message msg = new Message(); msg.what = 1; handler.sendMessage(msg); } }); thread.start(); } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected String doInBackground(Void... arg0) { ByteArrayOutputStream bos = null; // 内存操作流完成 try { URL url = new URL(PATH); HttpURLConnection conn = (HttpURLConnection) url .openConnection(); conn.connect(); InputStream input = conn.getInputStream(); bitmap = BitmapFactory.decodeStream(input); // bos = new ByteArrayOutputStream(); // byte data[] = new byte[1024]; // int len = 0; // while ((len = input.read(data)) != -1) { // bos.write(data, 0, len); // } // byte resultData[] = bos.toByteArray(); // bitmap = BitmapFactory.decodeByteArray(resultData, 0, // resultData.length); // 把二进制变为图片 } catch (Exception e) { } finally { if (bos != null) { try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; } }; task.execute(); } }