http请求功能的封装实现_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > http请求功能的封装实现

http请求功能的封装实现

 2017/12/19 21:56:11  多线程程序员  程序员俱乐部  我要评论(0)
  • 摘要:闲来无事,看下一下项目上,大部分的http请求类,发现。。都是一个方法,最后得到一个String,一般的方法都是,getStringForHttp(url),getJsonForHttp。那么在这样的方法上,我想实现一个getByteForHttp的话,就只能重新复制一份代码,然后再最后的io操作,再另外处理。但。。这叫什么面向对象,所以抽了点时间,写了个http的请求项目,暂时没测试出什么问题。希望有需要的,可以拿过去用,及时反馈bug。1.http请求主流程走向
  • 标签:功能 实现 HTTP请求 HTTP

闲来无事,看下一下项目上,大部分的http请求类,发现。。都是一个方法,最后得到一个String,一般的方法都是,getStringForHttp(url),getJsonForHttp。那么在这样的方法上,我想实现一个getByteForHttp的话,就只能重新复制一份代码,然后再最后的io操作,再另外处理。

?

但。。这叫什么面向对象,所以抽了点时间,写了个http的请求项目,暂时没测试出什么问题。希望有需要的,可以拿过去用,及时反馈bug。

?

1.http请求主流程走向:

?

class="java">/**
 * @author lyen.wu
 * http请求主流程
 */
public interface IYtBaseConnection {

	/**
	 * 设置request的参数
	 * @param connectParam
	 */
	public void setConnectParam(IYtBaseConnectParam connectParam);
	/**设置url,自动生成baseConnectParam*/
	public void setConnectParam(String url);
	/**
	 * 获取返回的结果对象
	 * */
	public IYtBaseConnectResult getConnectResult() ;
	public void post() throws Exception;
	public void get() throws Exception;
	/**
	 * 获取结果对象的简略结果,比如string,比如filePath
	 * */
	public Object getResultObj();
	
}

?2.封装请求参数

?

?

/**
 * @author lyen.wu
 * urlConnect请求的参数
 */
public interface IYtBaseConnectParam {

	/**
	 * 获取url链接
	 * */
	public String getUrl() ;
	/**
	 * 获取property属性
	 * */
	public Map<String, String> getPropertyMap();
	/**
	 * 设置property属性
	 * */
	public void setPropertyMap( Map<String, String> propertyMap);
	/**
	 * 获取请求参数
	 * */
	public String getParam();
	/**获取编码*/
	public String getCharsetCode() ;
	/**设置cookieMap,每次请求完成之后,都会将cookie设置进来*/
	public void setCookieMap(Map<String, String> cookieMap);
	/**获取cookieMap*/
	public Map<String, String> getCookieMap();
	/**302自动跳转*/
	public boolean isAutoRedirect();
	/**
	 * 最终是以byte的方法发送请求参数
	 * */
	public byte[] getParamByte();
}

?

?

3.封装请求的结果

?

/**
 * @author lyen.wu
 * http请求的结果类
 */
public interface IYtBaseConnectResult {
	/**设置状态码*/
	public void setStateCode(int stateCode);
	/**设置inputstream*/
	public void setIn(InputStream in);
	/**获取状态码*/
	public int getStateCode() ;
	/**获取http请求得到的inputstream*/
	public InputStream getIn();
	/**处理inputream的流*/
	public  void dealIn()throws Exception;
	/**处理inputream的流*/
	public  void dealIn(String charset) throws Exception;
}

?

?

至此这个http的骨架已经基本完善,剩下的就是为这个骨架贴肉。

4.首先是主流程的肉

?

package com.yt.tools.http.connection;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;

import com.yt.tools.http.connection.call.AbstractCall;
import com.yt.tools.http.connection.call.SimpleCall;
import com.yt.tools.http.connection.face.IYtBaseConnection;
import com.yt.tools.http.param.YtBaseConnectParam;
import com.yt.tools.http.param.face.IYtBaseConnectParam;
import com.yt.tools.http.result.face.IYtBaseConnectResult;
import com.yt.tools.http.utils.propety.YtHttpProtetyUtils;
import com.yt.tools.log.IYtConnLog;
import com.yt.tools.log.YtConnLogFactory;

/**
 * 基础的网络请求类,封装了总体流程
 * 
 * @author lyen.wu
 * 
 */
public abstract class YtBaseConnection implements IYtBaseConnection {
	private static IYtConnLog log = null;

	protected IYtBaseConnectResult connectResult;
	protected IYtBaseConnectParam connectParam;

	private AbstractCall call;

	public YtBaseConnection() {
		log = YtConnLogFactory.getLogger(this.getClass());
	}

	@Override
	public void setConnectParam(IYtBaseConnectParam connectParam) {
		this.connectParam = connectParam;
	}

	@Override
	public void setConnectParam(String url) {
		setConnectParam(new YtBaseConnectParam(url));
	}


	@Override
	public void post() throws Exception {
		getOrPost(getCall(), "post");
	}

	@Override
	public void get() throws Exception {
		getOrPost(getCall(), "get");
	}

	protected void getOrPost(AbstractCall call, String type) throws Exception {

		connectResult = getConnectResult();
		InputStream in = null;
		try {
			HttpURLConnection conn = getConnByConnectParm();
			// 建立实际的连接
			if (type.equals("get")) {
				call.doGet(conn);
			} else if (type.equals("post")) {
				call.doPost(conn, connectParam.getParamByte());
			}
			// 设置流
			in = conn.getInputStream();
			setResult(conn);
			// 定义BufferedReader输入流来读取URL的响应
			String cookieValue = conn.getHeaderField("Set-Cookie");
			YtHttpProtetyUtils.setCookie(connectParam.getCookieMap(),
					cookieValue);
			conn.disconnect();
		} catch (Exception e) {
			log.error("发送  " + type + " 请求出现异常!" + e);
			throw e;
		}
		// 使用finally块来关闭输入流
		finally {
			try {
				if (in != null) {
					in.close();
				}
				call.finallyAction();
				afterRequest();
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
	}
	/**
	 * 复写该方法,在请求之后的finally释放那里执行
	 */
	protected void afterRequest() {

	}

	public AbstractCall getCall() {
		if (call == null) {
			call = new SimpleCall();
		}
		return call;
	}

	public void setCall(AbstractCall call) {
		this.call = call;
	}

	/**
	 * 设置请求结果
	 * @param result
	 * @param conn
	 * @throws Exception
	 */
	protected void setResult( HttpURLConnection conn) throws Exception {
		// 设置请求结果
		int state = conn.getResponseCode();
		connectResult.setIn(conn.getInputStream());
		connectResult.setStateCode(state);
		// 处理流
		connectResult.dealIn(connectParam.getCharsetCode());
	}

	/**
	 * 设置conn的property属性
	 * @param conn
	 */
	protected void setPropertyMap(HttpURLConnection conn){
		if (connectParam.getPropertyMap() == null
				|| connectParam.getPropertyMap().size() == 0) {
			connectParam.setPropertyMap(YtHttpProtetyUtils
					.getCommonProtety());
		}
		Map<String, String> map = connectParam.getPropertyMap();
		// 设置通用的请求属性
		YtHttpProtetyUtils.setRequestProperty(conn, map);
		// 设置cookie
		YtHttpProtetyUtils.setRequestProperty(conn,
				connectParam.getCookieMap());
	}
	
	/**
	 * 根据connectParam生成HttpURLConnection
	 * @return
	 * @throws Exception
	 */
	public HttpURLConnection getConnByConnectParm() throws Exception{
		URL realUrl = new URL(connectParam.getUrl());

		// 打开和URL之间的连接
		HttpURLConnection conn = (HttpURLConnection) realUrl
				.openConnection();
		// 设置302自动跳转
		conn.setInstanceFollowRedirects(connectParam.isAutoRedirect());
		setPropertyMap(conn);
		return conn;
	}
	
}

?此主流程只是封装了正常的http请求功能,但是并没有处理io流的功能,io流的处理,应该交由子实现类去实现,因为有的功能需要图片,有的功能需要byte,有的功能需要String,这时候,应该暴露适当的流程空间交由外部去实现。

?

5.先补一个param的实现类:

?

/**
 * urlConnect请求的参数
 * 
 * @author lyen.wu
 * 
 */
public class YtBaseConnectParam implements IYtBaseConnectParam{

	//表头参数设置
	private Map<String, String> propertyMap = new HashMap<String, String>();
	//get或者post的参数
	private String param = "";
	//byte数组的请求参数,param会转成paramByte
	private byte[] paramByte = null;
	//请求的链接
	private String url = "";

	// 设置 HttpURLConnection的字符编码
	private String charsetCode = "UTF-8";
	
	//cookie用以共用session
	private Map<String, String> cookieMap = new HashMap<String, String>();

	private boolean autoRedirect = true;

	public YtBaseConnectParam(String url, String param) {
		this(url,null,null,param);
	}
	public YtBaseConnectParam(String url) {
		this(url,"");
	}

	public YtBaseConnectParam(String url, Map<String, String> propertiesMap,
			Map<String, String> headerMap, String param) {
		super();
		this.url = url;
		if(propertiesMap != null){
			this.propertyMap = propertiesMap;
		}
		this.param = param;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	/**
	 * 设置通用的property属性
	 */
	public Map<String, String> setCommonProperty() {
		propertyMap = YtHttpProtetyUtils.getCommonProtety();
		return propertyMap;
	}

	@Override
	public String toString() {
		return "ConnectParam [propertiesMap=" + propertyMap + ", param="
				+ param + ", url=" + url + "]";
	}

	public Map<String, String> getPropertyMap() {
		return propertyMap;
	}

	public void setPropertyMap(Map<String, String> propertiesMap) {
		this.propertyMap = propertiesMap;
	}

	public String getParam() {
		return param;
	}

	public void setParam(String param) {
		this.param = param;
	}

	public String getCharsetCode() {
		return charsetCode;
	}

	public void setCharsetCode(String charsetCode) {
		this.charsetCode = charsetCode;
	}

	public Map<String, String> getCookieMap() {
		return cookieMap;
	}

	public void setCookieMap(Map<String, String> cookieMap) {
		this.cookieMap = cookieMap;
	}
	
	/**
	 * 设置cookie内容,会自动转成map
	 * 第一个属性同时会存入,only-sessionId
	 * @param cookieContent
	 */
	public void setCookie(String cookieContent){
		if(cookieContent == null){
			return ;
		}
		
		String[] cookies = cookieContent.split(";");
		for( int i = 0 ; i < cookies.length ; i ++ ){
			String[] cookie = cookies[i].split("=");
			String key = cookie[0];
			String value = "";
			if(cookie.length > 1){
				value = cookie[1];
			}
			cookieMap.put(key , value);
			if(i == 0){
				cookieMap.put("only-sessionId", value);
			}
		}
		
	}
	public boolean isAutoRedirect() {
		return autoRedirect;
	}
	public void setAutoRedirect(boolean autoRedirect) {
		this.autoRedirect = autoRedirect;
	}
	public byte[] getParamByte() {
		if(paramByte == null){
			try {
				paramByte = param.getBytes(getCharsetCode());
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}
		return paramByte;
	}
	public void setParamByte(byte[] paramByte) {
		this.paramByte = paramByte;
	}
	
	

}

?

?

?

比如常用的获取字符串功能。

YtStringConnection.java

?

package com.yt.tools.http.connection;

import com.yt.tools.http.result.YtBaseConnectResult;
import com.yt.tools.http.result.YtStringConnectResult;

/**
 * 文本网络请求,获取网页的内容或者回包
 * @author lyen.wu
 *
 */
public class YtStringConnection extends YtBaseConnection{

	private YtStringConnectResult stringConnectResult = null ;
	@Override
	public YtBaseConnectResult getConnectResult() {
		if(stringConnectResult == null){
			stringConnectResult =  new YtStringConnectResult();
		}
		return stringConnectResult;
	}
	@Override
	public Object getResultObj() {
		return stringConnectResult.getContent();
	}
	
	
}

?result结果类:

?

?

/**
 * 文本回包
 * @author lyen.wu
 *
 */
public class YtStringConnectResult extends YtBaseConnectResult {

	private String content = "";

	@Override
	public void dealIn(String charsetCode) throws Exception {
		content = YtInputStream2OtherUtils.in2String(in, charsetCode);
	}

	public String getContent(){
		return content;
	}
	
}

?

?

又比如文件获取类:

?

/**
 * 获取文件的网络请求,保存到本地。
 * @author lyen.wu
 *
 */
public class YtFileConnection extends YtBaseConnection{
	
	private YtFileConnectResult fileConnectResult = new YtFileConnectResult();
	public YtFileConnection(String filePath) {
		fileConnectResult.setFilePath(filePath);
	}

	@Override
	public YtBaseConnectResult getConnectResult() {
		return fileConnectResult;
	}
	@Override
	public Object getResultObj() {
		
		return fileConnectResult.getFilePath();
	}
	
	
}

?

/**
 * 转换成file
 * 
 * @author lyen.wu
 * 
 */
public class YtFileConnectResult extends YtBaseConnectResult {

	/** 文件存放路径 */
	private String filePath = "";

	@Override
	public void dealIn(String charset) throws Exception {
		YtInputStream2OtherUtils.in2File(in, filePath);
	}

	public String getFilePath() {
		return filePath;
	}

	public void setFilePath(String filePath) {
		this.filePath = filePath;

	}

}

?

?

流程就已经完成,剩下缺少的类就是一些工具类。

?

public class YtHttpProtetyUtils {
	
	public static String defaultCode = "UTF-8";
	
	/**
	 * 获取通用的requestPropertity设置
	 * 
	 * @return
	 */
	public static Map<String, String> getCommonProtety() {
		Map<String, String> map = new HashMap<String, String>();
		map.put("accept", "*/*");
		map.put("connection", "Keep-Alive");
		map.put("user-agent",
				"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
		map.put("Content-Type",ContentTypeEnum.APP_DEFAULT.getValue());
		return map;
	}

	/**
	 * 设置request属性
	 * 
	 * @param conn
	 * @param map
	 */
	public static void setRequestProperty(HttpURLConnection conn,
			Map<String, String> map) {
		if (map == null) {
			return;
		}
		for (String key : map.keySet()) {
			conn.setRequestProperty(key, map.get(key));
		}
	}
	
	/**
	 * 设置cookie内容,会自动转成map
	 * 第一个属性同时会存入,only-sessionId
	 * @param cookieContent
	 */
	public static void setCookie(Map<String,String> cookieMap, String cookieContent){
		if(cookieContent == null){
			return ;
		}
		
		String[] cookies = cookieContent.split(";");
		for( int i = 0 ; i < cookies.length ; i ++ ){
			String[] cookie = cookies[i].split("=");
			String key = cookie[0];
			String value = "";
			if(cookie.length > 1){
				value = cookie[1];
			}
			cookieMap.put(key , value);
			if(i == 0){
				cookieMap.put("only-sessionId", value);
			}
		}
		
	}

}

?

?

?

/**
 * Content-Type中的常用请求枚举
 * @author lyen.wu
 * email:flash_rui@126.com
 * 2017-12-14
 */
public enum ContentTypeEnum {

	JSON("application/json; charset="+YtHttpProtetyUtils.defaultCode),TEXT_XML("text/xml; charset="+YtHttpProtetyUtils.defaultCode),
	TEXT_HTML("text/html; charset="+YtHttpProtetyUtils.defaultCode),
	APP_DEFAULT("application/x-www-form-urlencoded; charset="+YtHttpProtetyUtils.defaultCode),
	TEXT_PLAIN("text/plain; charset="+YtHttpProtetyUtils.defaultCode);
	
	private String value;
	
	private ContentTypeEnum(String value){
		this.value = value;
	}

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}
	
	
}

?

?

?

/**
 * inputStream流处理方法
 * @author lyen.wu
 * email:flash_rui@126.com
 * 2017-7-17
 */
public class YtInputStream2OtherUtils {

	/**
	 * in流转string
	 * @param in
	 * @param charsetCode
	 * @return
	 * @throws Exception
	 */
	public static String in2String(InputStream in,String charsetCode) throws Exception{
		BufferedReader br = null;
		try{
			String result = "";
			br = new BufferedReader(new InputStreamReader(in,
					charsetCode ));
			String line;
			while ((line = br.readLine()) != null) {
				result += line + "\n";
			}
			return result;
		}catch(Exception e){
			throw e;
		}finally{
			//当br关闭,in也会关闭,不过还是一个个的来
			if(br != null){
				br.close();
			}
			if(in != null){
				in.close();
			}
		}
		
		
	}
	/**
	 * in流转文件,且自动关闭
	 * @param inputStream
	 * @param filePath
	 * @throws Exception
	 */
	public static void in2File(InputStream inputStream , String filePath ) throws Exception{
		in2File(inputStream,filePath,true);
	}
	
	/**
	 * in流转File,参数决定是否关闭in流
	 * @param inputStream
	 * @param filePath
	 * @param autoClose 自动关闭in流
	 * @throws Exception
	 */
	public static void in2File(InputStream inputStream , String filePath , boolean autoClose) throws Exception{
		byte[] data = new byte[1024];
		int len = 0;
		FileOutputStream fileOutputStream = null;
		try {
			fileOutputStream = new FileOutputStream(filePath);
			while ((len = inputStream.read(data)) != -1) {
				fileOutputStream.write(data, 0, len);

			}
		} catch (Exception e) {
			throw e;
		} finally {

			if (autoClose && inputStream != null) {
				try {
					inputStream.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if (fileOutputStream != null) {
				try {
					fileOutputStream.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

		}
	}
	/**
     * 从输入流获取数据
     * @param inputStream
     * @return
     * @throws Exception
     */
    public static byte[] in2Byte(InputStream inputStream) throws Exception{
        byte[] buffer = new byte[1024];
        int len = -1;
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        while((len = inputStream.read(buffer)) != -1){
            outputStream.write(buffer, 0, len);
        }
        outputStream.close();
        inputStream.close();
        return outputStream.toByteArray();
    }
	
}

?

?

Demo 请求样例代码:

@Test
	public void testPost() throws Exception{
		//需要post的参数
		String param = "param=1";
		//创建一个请求参数的param
		YtBaseConnectParam connectParam = new YtBaseConnectParam(
				"http://localhost:8080/test/temp1.json");
		connectParam.setParam(param);
		//创建一个标准的字符串结果请求
		IYtBaseConnection connection = new YtStringConnection();
		//设置请求baseparam
		connection.setConnectParam(connectParam);
		//post
		connection.post();
		//返回结果
		log.info(connection.getResultObj() + "");
	}
	
	@Test
	public void testImgGet() throws Exception {
		//设置http请求的流程且具体实现类是ytFileConnection
		IYtBaseConnection connection = new YtFileConnection("d:\\da.jpg");
		//设置请求地址
		connection.setConnectParam("http://pic.qiantucdn.com/58pic/15/28/06/57458PIC5Zb_1024.jpg!/fw/780/watermark/url/L3dhdGVybWFyay12MS4zLnBuZw==/align/center");
		//get
		connection.get();
		//得到保存的地址
		log.info(connection.getResultObj() + "");
	}
	
	@Test
	public void testStringGet() throws Exception {
		//设置http请求的流程且具体实现类是YtStringConnection
		IYtBaseConnection connection = new YtStringConnection();
		//设置请求地址
		connection.setConnectParam("http://www.baidu.com");
		//get
		connection.get();
		//得到这个网页的源码
		log.info(connection.getResultObj() + "");
	}

	@Test
	public void testJSONPost() throws Exception {
		//json参数
		String param = "{\"order\": \"32221\",\"refoundAmt\":\"9.5\"}";
		YtBaseConnectParam connectParam = new YtBaseConnectParam(
				"http://localhost:8080/pay/refund.json");
		connectParam.setParam(param);
		//此接口需要设置content-type方能解析。
		connectParam.setCommonProperty().put("Content-Type", ContentTypeEnum.JSON.getValue());
		IYtBaseConnection connection = new YtStringConnection();
		connection.setConnectParam(connectParam);
		connection.post();
		log.info(connection.getResultObj() + "");
	}

?

至此http请求功能完成。

git路径:https://github.com/JavaRui/com.yt.tools/tree/master/com.yt.tools.http

?

?

?

?

?

  • com.yt.tools.http.zip (22.4 KB)
  • 下载次数: 0
上一篇: java多用户商城系统架构之第一篇——总的介绍 下一篇: 没有下一篇了!
发表评论
用户名: 匿名