web开发下的HTTP编程及接口回调的使用

JDK使用GET方式访问HTTP

得到访问地址 java.net.URL(有参数提供参数)
得到网络访问对象java.net.HttpURLConnection,设置请求参数(过期时间,输入、输出流、访问方式),以流的形式进行连接  
得到返回值 responseCode
如果返回值正常,数据在网络中是以流的形式得到服务端返回的数据

JDK使用POST方式访问HTTP
得到访问地址 java.net.URL
得到网络访问对象,设置请求参数(过期时间,输入、输出流、访问方式,请求属性Content-Type:application/x-www-form-urlencoded),进行连接  java.net.HttpURLConnection
输出流写入参数到请求中
得到返回值 responseCode
如果返回值正常,网络是以流的形式得到返回的数据

示例代码:
package com.qianfeng.httpurlconnect;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class HttpUtils {

	public static void saveImage(String path){
		try {
			//根据地址创建URL对象
			URL url = new URL(path);
			//URLConnection代表程序与URL之间的通信链接
			//创建链接
			HttpURLConnection urlConn = (HttpURLConnection)url.openConnection();
			//
			urlConn.setDoInput(true);
			//设置请求的方法,GET
			urlConn.setRequestMethod("GET");
			
			//打开链接
			urlConn.connect();
			//返回响应的代码
			int code = urlConn.getResponseCode();
			
			if(code == 200){
				//获得输入流
				InputStream is = urlConn.getInputStream();
				//获得输出流
				File f = new File("c:/houzi.gif");
				int  i =0;
				while(f.exists()){
					f = new File("c:/houzi("+i+").gif");
					i++;
				}
				FileOutputStream out = new FileOutputStream(f);
				//将读取的数据放入Byte数组中,之后一次性写入
				ByteArrayOutputStream baos = new ByteArrayOutputStream();
				byte [] a = new byte[1024*8];
				//读
				int n = 0;
				//写入本地的磁盘
				while((n=is.read(a))!=-1){
					baos.write(a,0,n);
					baos.flush();
				}
				//将内存流中的数据一次性写入
				out.write(baos.toByteArray());
				is.close();
				out.close();
			}else if(code==404){
				System.out.println("未找到资源文件");
			}else if(code==500){
				System.out.println("未找到服务器");
			}
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}


下载图片是将下载这种耗时的操作放在子线程中进行,将主线程解放出来做一些其他事情,怎样将子线程读取到的数据再返回到主线程呢
这就用到了著名的接口回调的操作
现在我们看一下怎么实现这种操作:
先建立一个接口
DownloadCallback
package com.qianfeng.httpurlconnect;

public interface DownloadCallback {
	public void downCallback(byte [] data);

}
接下来定义一个工具类
HttpUtils
package com.qianfeng.httpurlconnect;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class HttpUtils {

	
	public static void getContent(final String path,final DownloadCallback callback){
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				try {
					//根据地址创建URL对象
					URL url = new URL(path);
					//URLConnection代表程序与URL之间的通信链接
					//创建链接
					HttpURLConnection urlConn = (HttpURLConnection)url.openConnection();
					//
					urlConn.setDoInput(true);
					//设置请求的方法,GET
					urlConn.setRequestMethod("GET");
					
					//打开链接
					urlConn.connect();
					//返回响应的代码
					int code = urlConn.getResponseCode();
					
					if(code == 200){
						//获得输入流
						InputStream is = urlConn.getInputStream();					
						//将读取的数据放入Byte数组中,之后一次性写入
						ByteArrayOutputStream baos = new ByteArrayOutputStream();
						byte [] a = new byte[1024*8];
						//读
						int n = 0;
						//写入本地的磁盘
						while((n=is.read(a))!=-1){
							baos.write(a,0,n);
							baos.flush();
						}
						//再次调用接口中的方法,并将子线程的数据传进去,方便在主线程重写方法时获得该数据
						callback.downCallback(baos.toByteArray());
						is.close();
					}else if(code==404){
						System.out.println("未找到资源文件");
					}else if(code==500){
						System.out.println("未找到服务器");
					}
				} catch (MalformedURLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
		}).start();
	}
}

创建一个执行操作的主线程
package com.qianfeng.httpurlconnect;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class HttpURLConnection01 {
	public static void main(String[] args) {
		//图片地址
		String path="http://192.168.125.117:8080/day27/img/27125326.jpg";
	
		HttpUtils.getContent(path,new DownloadCallback() {
			//在主线程中重写该方法,使得在主线程可以操作子线程的数据,这就是接口回调
			@Override
			public void downCallback(byte[] data) {
				// TODO Auto-generated method stub
				//获得输出流
				File f = new File("c:/houzi.gif");
				int  i =0;
				while(f.exists()){
					f = new File("c:/houzi("+i+").gif");
					i++;
				}
				try {
					FileOutputStream out = new FileOutputStream(f);
					out.write(data);
					out.close();
					
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
		});
	}
	
}
这样一个接口回调就解决了耗时事务在主线程操作,阻塞主线程的其他操作的执行,增强了用户体验,这个回调的意思就是子线程里面调用的方法的具体实现实际是在主线程里
可以想象在主线程下面还有好多的事情要做,主线程做完了DownloadCallback的内部类就往下走了,然后子线程执行到调用DownloadCallback接口时,就会到main中找两不耽误

你可能感兴趣的:(java,URL,HTTP,接口回调)