http转发实现之一:转发代码的实现

        最近公司实现一个银行网关系统,主要目的是接收银行的结果通知,并转发到后台的支付处理集群,在同时对银行的结果通知进行存储。如果银行网关系统通知处理集群失败。则在未来一段时间内对这些数据实施重发补偿。简而言之,这样做的好处是减少掉单率,在集群遇到重大问题宕机时,也能在很大程度上挽回损失,因为存储了银行通知,有补偿机制。我负责系统的主要编码工作。废话从简,把这个系统的核心代码贴上再说。

1  接收转发类

package com.vness.httpforward.handler;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.vness.common.logger.writeLog;
import com.vness.httpforward.connector.VnHttpConnector;

/*
 * author:v.tone
 * time:2012.05 
 */

public class VnHttpForwardHanlder {
	private HttpServletRequest request; // 原有请求串
	private HttpServletResponse response;
	private String targetAddr; // 转发目标地址
	private Map<String, Object> returnData;

	private int _maxDataSize = 1024;

	private int timelimit = 10;

	public HttpServletRequest getRequest() {
		return request;
	}

	public void setRequest(HttpServletRequest request) {
		this.request = request;
	}

	public HttpServletResponse getResponse() {
		return response;
	}

	public void setResponse(HttpServletResponse response) {
		this.response = response;
	}

	public String getTargetAddr() {
		return targetAddr;
	}

	public void setTargetAddr(String targetAddr) {
		this.targetAddr = targetAddr;
	}

	public Map<?, ?> getReturnData() {
		return returnData;
	}

	@SuppressWarnings("unchecked")
	public void setReturnData(Map<?, ?> returnData) {
		this.returnData = ((Map<String, Object>) returnData);
	}

	public int getTimelimit() {
		return timelimit;
	}

	public void setTimelimit(int timelimit) {
		this.timelimit = timelimit;
	}

	public VnHttpForwardHanlder(HttpServletResponse rsp,
			HttpServletRequest req, String addr) {
		this.request = req;
		this.targetAddr = addr;
		this.response = rsp;
	}

	public VnHttpForwardHanlder() {
	}

	// 转发前检查
	protected boolean preCheck() {
		if (this.targetAddr == null || this.targetAddr.equals("")) {
			writeLog.write("dispatch_", "dispatcher address is null.");
			returnData.put("ERR_CD", "0001");
			return false;
		}
		// 请求串为空
		if (this.request == null || this.request.equals("")) {
			writeLog.write("dispatch_", "Entry request string:" + this.request);
			returnData.put("ERR_CD", "0002");
			return false;
		}
		return true;
	}

	protected byte[] receiveData() throws Exception {
		byte[] data = new byte[0];
		if (request.getMethod() == "GET") {
			String queryStr = request.getQueryString();
			if (null != queryStr) {
				data = queryStr.getBytes();
			}
		} else {
			int msgLen = request.getContentLength();
			if (msgLen <= 0) {
				msgLen = request.getInputStream().available();
			}

			// dataSize check
			if (-1 != _maxDataSize) {
				if (msgLen > _maxDataSize) {
					returnData.put("ERR_CD", "0003");
					throw new Exception("post data is too large, size="
							+ msgLen);
				}
			}
			data = new byte[msgLen];
			data = InputStreamToByte(request.getInputStream());
		}
		// ByteBuffer buff = ByteBuffer.wrap(data);
		return data;
	}

	private byte[] InputStreamToByte(InputStream iStrm) throws IOException {
		ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
		int ch;
		while ((ch = iStrm.read()) != -1) {
			bytestream.write(ch);
		}
		byte imgdata[] = bytestream.toByteArray();
		bytestream.close();
		return imgdata;
	}

	@SuppressWarnings("unchecked")
	public void request() {

		if (!preCheck()) {
			writeLog.write("dispatch_", "dispatch check error.");
			return;
		}
		InputStream in = null;
		OutputStream out = null;
		try {
			in = request.getInputStream();
			out = response.getOutputStream();

			byte[] data = receiveData();
			writeLog.write("dispatch_", "dispatch datas [ " + data.toString()
					+ " ]");
			returnData = (Map<String, Object>) VnHttpConnector.request(
					targetAddr, data, request.getMethod(), timelimit);
			setResponseHeader();
			String err = (String) returnData.get("ERR_CD");
			if (!"0000".equalsIgnoreCase(err)) {
				response.sendError(500);
				return;
			}
			// 返回处理结果
			out.write((byte[]) returnData.get(VnHttpConnector.RET_MESSAGE));
			out.flush();
		} catch (Exception e) {
			e.printStackTrace();

		} finally {
			if (null != in) {
				try {
					in.close();
				} catch (Exception e) {
				}
			}
			if (null != out) {
				try {
					out.close();
				} catch (Exception e) {
				}
			}
		}
		return;
	}

	private void setResponseHeader() {
		if (null != returnData) {
			returnData.put("ERR_CD", "0004");
			return;
		}
		// 设置header
		Map<?, ?> resHeaders = (Map<?, ?>) returnData
				.get(VnHttpConnector.RET_HEAD);
		if (null != resHeaders) {
			// RESPONSE HEADER
			Iterator<?> i = resHeaders.keySet().iterator();
			String key = null;
			String value = null;
			while (i.hasNext()) {
				key = (String) i.next();
				value = (String) resHeaders.get(key);
				response.setHeader(key, value);
			}
		}
		// 设置状态
		response.setStatus((Integer) returnData.get(VnHttpConnector.RET_STATUS));
	}

}
2 转发实施类

package com.vness.httpforward.connector;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import net.sf.json.JSONObject;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;

import com.vness.common.logger.writeLog;
 
/*
 * author:v.tone
 * time:2012.05 
 */

public class VnHttpConnector {

    public static final String METHOD_TYPE_GET = "GET";
    public static final String METHOD_TYPE_POST = "POST";

    public static final String RET_HEAD = "HEAD";
    public static final String RET_STATUS = "STATUS";
    public static final String RET_MESSAGE = "MESSAGE";

    public static Map<String, Object> request(String url, byte[] data, String methodType,
            int timeout, JSONObject header) throws HttpException, IOException {

        timeout = timeout * 1000;
        Map<String, Object> response = new HashMap<String, Object>();

        HttpClient client = new HttpClient();
        client.getParams().setSoTimeout(timeout);
        client.getHttpConnectionManager().getParams().setConnectionTimeout(
                timeout);
        writeLog.write("dispatch_","request mothed type:"+methodType);
        HttpMethod method = null;
        try {
            if (METHOD_TYPE_GET.equals(methodType)) {
                // GET 
                GetMethod get = new GetMethod(url);
                if (null != data && data.length > 0) {
                    get.setQueryString(new String(data));
                } 
                method = get;
            } else {
                // DEFAULT POST
                PostMethod post = new PostMethod(url);
                if (null != data && data.length > 0) {
                    ByteArrayRequestEntity entity = new ByteArrayRequestEntity(
                            data);
                    post.setRequestEntity(entity);
                }
                method = post;
            }
            writeLog.write("dispatch_","request data."+ new String(data));
            method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
                    new DefaultHttpMethodRetryHandler(0, false));

            if (null != header) {
                // HTTP HEADER
                Iterator<?> i = header.keySet().iterator();
                String key = null;
                String value = null;
                while (i.hasNext()) {
                    key = (String) i.next();
                    value = (String) header.get(key);
                    method.setRequestHeader(key, value);
                }
            }
            writeLog.write("dispatch_","will execute send.");
            int status = client.executeMethod(method);
            writeLog.write("dispatch_","dispatcher return code:"+status);
            response.put(RET_STATUS, status);
            response.put(RET_MESSAGE, method.getResponseBody());
            response.put(RET_HEAD, header2Map(method.getResponseHeaders()));
        } finally {
            if (null != method) {
                method.releaseConnection();
            }
            client = null;
        }

        return response;

    }

    public static Map<?, ?> request(String url, byte[] data, String methodType,
            int timeout, String jsonFmtHeaders) throws HttpException,
            IOException {

        return request(url, data, methodType, timeout, JSONObject
                .fromObject(jsonFmtHeaders));
    }

    public static Map<?, ?> request(String url, byte[] data, String methodType,
            int timeout) throws HttpException, IOException {
    	writeLog.write("dispatch_","Connector request().");
        return request(url, data, methodType, timeout, (JSONObject) null);
    }

    private static Map<String, String> header2Map(Header[] headers) {
        Map<String, String> tmp = null;
        if (null != headers) {
            tmp = new HashMap<String, String>();
            for (Header header : headers) {
                tmp.put(header.getName(), header.getValue());
            }
        }
        return tmp;
    } 
}


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值