http转发实现之一:转发代码的实现
4145 点击·0 回帖
![]() | ![]() | |
![]() | 最近公司实现一个银行网关系统,主要目的是接收银行的结果通知,并转发到后台的支付处理集群,在同时对银行的结果通知进行存储。如果银行网关系统通知处理集群失败。则在未来一段时间内对这些数据实施重发补偿。简而言之,这样做的好处是减少掉单率,在集群遇到重大问题宕机时,也能在很大程度上挽回损失,因为存储了银行通知,有补偿机制。我负责系统的主要编码工作。废话从简,把这个系统的核心代码贴上再说。 1 接收转发类 [java] 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; } // 返回处理结果 www.atcpu.com 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 转发实施类 [html] 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; } } 作者 Willon_tom | |
![]() | ![]() |