1. 程式人生 > >servlet獲取並解析post請求傳送過來的xml字串

servlet獲取並解析post請求傳送過來的xml字串

客戶端程式碼:

@Action(value = "/sendxmlTest", results = { 
			@Result(name = SUCCESS, location = "condo/accountOpenApplly.jsp"),
			@Result(name = INPUT, location = "base/error.jsp") })
	public String sendxmlTest(){
		String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
						"<request>\n" + 
						"  <head>\n" + 
						"    <transType>0101</transType>\n" + 
						"    <terminalVer>1.0.0</terminalVer>\n" + 
						"    <dateTime>20170407103000</dateTime>\n" + 
						"  </head>\n" + 
						"  <body>\n" + 
						"    <contactNo>Test00001</contactNo>\n" + 
						"  </body>\n" + 
						"<mac>902de37505fce863f4489a87c7e3fa6c</mac>"+
						"</request>";

		String url = "http://127.0.0.1:8080/zxemm/contactServlet.htm";
		try {
			String resultXml = SubmitUtils.buildRequest(url, xml);
		} catch (Exception e) {
			e.printStackTrace();
		}
	return SUCCESS;
		
	}

服務端程式碼:
package com.jiuyi.net.servlet;

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

import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import com.jiuyi.jyplat.entity.condo.ContactInfo;
import com.jiuyi.jyplat.service.SpringContextUtil;
import com.jiuyi.jyplat.service.condo.IContactInfoService;
import com.jiuyi.jyplat.util.ConfigManager;
import com.jiuyi.jyplat.util.DateUtils;
import com.jiuyi.jyplat.util.Utils;
import com.jiuyi.net.message.httpClient.XMLUtil;
import com.jiuyi.net.message.pos.contact.QurContactRsp;
import com.jiuyi.net.message.pos.contact.QurContactRspMsg;
import com.jiuyi.net.message.pos.contact.RequestHead;
import com.jiuyi.net.utils.PosMacUtils;

/**
 * 
 * <p><b>Title: </b>ContactServlet.java
 * <p><b>Description: </b>合同資訊查詢servlet
 * @author 
 * @version V1.0
 * <p>
 * 2017-4-6  建立類  <br>
 *
 */
public class ContactServlet extends HttpServlet{

	private static final long serialVersionUID = 1L;
	
	Logger log = Logger.getLogger(ContactServlet.class);
	
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		this.doPost(request, response);
	}
	
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		log.info("收到查詢合同資訊的請求...");
		QurContactRspMsg rspMsg = new QurContactRspMsg();
		QurContactRsp rsp = new QurContactRsp();
		RequestHead head = new RequestHead();
		head.setTransType("0101");
		head.setTerminalVer("V1.0");
		head.setDateTime(DateUtils.getToday(DateUtils.TIME_STR_FORMAT));
		PrintWriter out = response.getWriter();
		ServletInputStream sis = null;  
		String xmlData="";
		Map<String,String> macMap = new HashMap<String,String>();
		String posKey = (String) ConfigManager.getInstance().getConfigItem("pos_key", ""); //獲取配置檔案中的加密key
		try {
			//編碼格式改成UTF-8
			response.setCharacterEncoding("UTF-8");
			request.setCharacterEncoding("UTF-8");
			response.setContentType("textml; charset=UTF-8");
			response.setHeader("Content-type", "text/html;charset=UTF-8");
			
			sis=request.getInputStream();
			// 取HTTP請求流長度  
            int size = request.getContentLength();  
            // 用於快取每次讀取的資料  
            byte[] buffer = new byte[size];  
            // 用於存放結果的陣列  
            byte[] xmldataByte = new byte[size];  
            int count = 0;  
            int rbyte = 0;  
            // 迴圈讀取  
            while (count < size) {   
                // 每次實際讀取長度存於rbyte中  
                rbyte = sis.read(buffer);   
                for(int i=0;i<rbyte;i++) {  
                    xmldataByte[count + i] = buffer[i];  
                }  
                count += rbyte;  
            }  
              
            xmlData = new String(xmldataByte, "UTF-8");  
            log.info("查詢合同資訊介面接收的xmlData為:"+xmlData);
            
            //將傳入的xml字串轉換為map集合
			Map<String,String> params = new HashMap<String,String>();
            params = this.parseXmlToMap(xmlData);

            //驗籤
			String posSign = genMac(xmlData); //得到請求報文的密文
			String mySign = PosMacUtils.buildRequestMysign(params,posKey);
			if(Utils.isNullData(posSign,mySign) || !posSign.equals(mySign)){
				log.error("呼叫儲存pos機交易流水介面驗籤失敗!");
				head.setResponseCode("0001");
				head.setResponseDesc("驗籤失敗");
				rspMsg.setHead(head);
				String xmlRsp = XMLUtil.objToxml(rspMsg);
				xmlRsp = XMLUtil.formatXml(xmlRsp);
				
				macMap = this.parseXmlToMap(xmlRsp); //將xml報文轉換成map集合用於生成密文
				String mac = PosMacUtils.buildRequestMysign(macMap, posKey);
				rspMsg.setMac(mac);
				String resultXml = XMLUtil.objToxml(rspMsg);
				resultXml = XMLUtil.formatXml(resultXml);
				log.info("呼叫儲存pos機交易流水介面返回報文為:"+resultXml);
				out.print(resultXml);
				out.flush();
				out.close();
				return;
			}
			
			
			
			//獲取請求引數中的合同號
			String contactNo = params.get("contactNo");
			String transType = params.get("transType");
			if(Utils.isNullData(contactNo,transType)){
				log.error("呼叫查詢合同資訊介面請求引數不完整,請檢查!");
				head.setResponseCode("0011");
				head.setResponseDesc("請求引數不完整");
				rspMsg.setHead(head);
				String xmlRsp = XMLUtil.objToxml(rspMsg);
				xmlRsp = XMLUtil.formatXml(xmlRsp);
				
				macMap = this.parseXmlToMap(xmlRsp); //將xml報文轉換成map集合用於生成密文
				String mac = PosMacUtils.buildRequestMysign(macMap, posKey);
				rspMsg.setMac(mac);
				String resultXml = XMLUtil.objToxml(rspMsg);
				resultXml = XMLUtil.formatXml(resultXml);
				log.info("呼叫儲存pos機交易流水介面返回報文為:"+resultXml);
				out.print(resultXml);
				out.flush();
				out.close();
				return;
			}
			IContactInfoService contactInfoService = (IContactInfoService)SpringContextUtil.getBean("contactInfoService");
			ContactInfo c = contactInfoService.findByContactNo(contactNo);
			if(null==c){
				head.setResponseCode("0001");
				head.setResponseDesc("查詢合同資訊不存在");
				rspMsg.setHead(head);
				String xmlRsp = XMLUtil.objToxml(rspMsg);
				xmlRsp = XMLUtil.formatXml(xmlRsp);
				
				macMap = this.parseXmlToMap(xmlRsp); //將xml報文轉換成map集合用於生成密文
				String mac = PosMacUtils.buildRequestMysign(macMap, posKey);
				rspMsg.setMac(mac);
				String resultXml = XMLUtil.objToxml(rspMsg);
				resultXml = XMLUtil.formatXml(resultXml);
				log.info("呼叫儲存pos機交易流水介面返回報文為:"+resultXml);
				out.print(resultXml);
				out.flush();
				out.close();
				return;
			}
			if(null!=c && "1111".equals(c.getStatus())){//合同已撤銷
				head.setResponseCode("0004");
				head.setResponseDesc("退款中(合同已撤銷)");
				rspMsg.setHead(head);
				String xmlRsp = XMLUtil.objToxml(rspMsg);
				xmlRsp = XMLUtil.formatXml(xmlRsp);
				
				macMap = this.parseXmlToMap(xmlRsp); //將xml報文轉換成map集合用於生成密文
				String mac = PosMacUtils.buildRequestMysign(macMap, posKey);
				rspMsg.setMac(mac);
				String resultXml = XMLUtil.objToxml(rspMsg);
				resultXml = XMLUtil.formatXml(resultXml);
				log.info("呼叫儲存pos機交易流水介面返回報文為:"+resultXml);
				out.print(resultXml);
				out.flush();
				out.close();
				return;
			}
			if(null!=c && "2222".equals(c.getStatus())){//無效合同
				head.setResponseCode("0010");
				head.setResponseDesc("無效合同");
				rspMsg.setHead(head);
				String xmlRsp = XMLUtil.objToxml(rspMsg);
				xmlRsp = XMLUtil.formatXml(xmlRsp);
				
				macMap = this.parseXmlToMap(xmlRsp); //將xml報文轉換成map集合用於生成密文
				String mac = PosMacUtils.buildRequestMysign(macMap, posKey);
				rspMsg.setMac(mac);
				String resultXml = XMLUtil.objToxml(rspMsg);
				resultXml = XMLUtil.formatXml(resultXml);
				log.info("呼叫儲存pos機交易流水介面返回報文為:"+resultXml);
				out.print(resultXml);
				out.flush();
				out.close();
				return;
			}
			rsp.setBackCardName(c.getBackCardName());
			rsp.setBankCode(c.getBackCardNo());
			rsp.setCompanyName(c.getCompanyName());
			rsp.setContactAmt(null==c.getContactAmt()?0.0:Double.parseDouble(c.getContactAmt()));
			rsp.setContactNo(c.getContactNo());
			rsp.setCreateDate(c.getCreateDate());
			rsp.setHouseAddr(c.getHouseAddr());
			rsp.setHouseArea(null==c.getHouseArea()?0.0:Double.parseDouble(c.getHouseArea()));
			rsp.setHouseNo(c.getHouseNo());
			rsp.setOperNo(c.getOperNo());
			rsp.setPayCont(null==c.getPayCont()?0.0:Double.parseDouble(c.getPayCont()));
			rsp.setPaymentCode(c.getPaymentCode());
			rsp.setProjectName(c.getProjectName());
			rsp.setProjectNo(c.getProjectNo());
			rsp.setRoomNo(c.getRoomNo());
			rsp.setSuperviseAmt(null==c.getSuperviseAmt()?0.0:Double.parseDouble(c.getSuperviseAmt()));
			rsp.setUnitNo(c.getUnitNo());
			head.setResponseCode("0000");
			head.setResponseDesc("交易成功");
			rspMsg.setHead(head);
			rspMsg.setBody(rsp);
			String xmlRsp = XMLUtil.objToxml(rspMsg);
			xmlRsp = XMLUtil.formatXml(xmlRsp);
			
			macMap = this.parseXmlToMap(xmlRsp); //將xml報文轉換成map集合用於生成密文
			String mac = PosMacUtils.buildRequestMysign(macMap, posKey);
			rspMsg.setMac(mac);
			String resultXml = XMLUtil.objToxml(rspMsg);
			resultXml = XMLUtil.formatXml(resultXml);
			log.info("呼叫儲存pos機交易流水介面返回報文為:"+resultXml);
			out.print(resultXml);
			out.flush();
			out.close();
			return;
			
		} catch (Exception e) {
			log.error("呼叫儲存pos機交易流水接口出現異常!"+e.toString(), e);
			String returnXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
			returnXml+="<response><head><dateTime>"+DateUtils.getToday(DateUtils.TIME_STR_FORMAT)+"</dateTime>";
			returnXml+=" <responseCode>9999</responseCode><responseDesc>系統異常</responseDesc><terminalVer>V1.0</terminalVer><transType>0101</transType></head></response>";
			macMap = this.parseXmlToMap(returnXml); //將xml報文轉換成map集合用於生成密文
			String mac = PosMacUtils.buildRequestMysign(macMap, posKey);
			String resultXml ="<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
			resultXml += "<response><head><dateTime>"+DateUtils.getToday(DateUtils.TIME_STR_FORMAT)+"</dateTime>";
			resultXml+=" <responseCode>9999</responseCode><responseDesc>系統異常</responseDesc><terminalVer>V1.0</terminalVer><transType>0101</transType></head><mac>"+mac+"</mac></response>";
			log.info("呼叫儲存pos機交易流水介面返回報文為:"+resultXml);
			out.print(resultXml);
			out.flush();
			out.close();
			return;
		}
		
	}
	
	
	/**
	 * 
	 * <p><b>Description: </b>得到傳送過來的密文
	 * <p>2017-4-7 下午12:34:45
	 * @author 
	 * @param xml
	 * @return
	 */
	public static String genMac(String xml){
		try {
			Document doc = null;  
			// 將字串轉為XML  
			doc = DocumentHelper.parseText(xml);   
			// 獲取根節點  
			Element rootElt = doc.getRootElement();   
      
			String mac =  rootElt.elementTextTrim("mac");
			return mac;
		} catch (DocumentException e) {
			e.printStackTrace();
		}   
		return null;
	}
	
	/**
	 * 
	 * <p><b>Description: </b>解析查詢合同資訊介面的請求報文
	 * <p>2017-4-7 上午10:27:02
	 * @author 
	 * @param xml
	 * @return
	 */
	public static Map parseXmlToMap(String xml) {  
	      Map map = new HashMap();  
	      Document doc = null;  
	      try {  
	          // 將字串轉為XML  
	          doc = DocumentHelper.parseText(xml);   
	          // 獲取根節點  
	          Element rootElt = doc.getRootElement();   
	          // 獲取根節點下的子節點head  
	          Iterator iter = rootElt.elementIterator("head");   
	          // 遍歷head節點  
	          while (iter.hasNext()) {  
	  
	              Element recordEle = (Element) iter.next();  
	              // 拿到head節點下的子節點transType值  
	              String transType = recordEle.elementTextTrim("transType");   
	              map.put("transType", transType);  
	              // 拿到head節點下的子節點terminalVer值  
	              String terminalVer = recordEle.elementTextTrim("terminalVer");   
	              map.put("terminalVer", terminalVer);  
	              // 拿到head節點下的子節點dateTime值  
	              String dateTime = recordEle.elementTextTrim("dateTime");   
	              map.put("dateTime", dateTime);  
	              
	              // 拿到head節點下的子節點responseCode值  
	              String responseCode = recordEle.elementTextTrim("responseCode");   
	              map.put("responseCode", responseCode);  
	              // 拿到head節點下的子節點responseDesc值  
	              String responseDesc = recordEle.elementTextTrim("responseDesc");   
	              map.put("responseDesc", responseDesc);  
	          }  
	  
	          //獲取根節點下的子節點body  
	          Iterator iterss = rootElt.elementIterator("body");   
	          // 遍歷body節點  
	          while (iterss.hasNext()) {  
	              Element recordEless = (Element) iterss.next();  
	              // 拿到body節點下的子節點contactNo值  
	              String contactNo = recordEless.elementTextTrim("contactNo");   
	              map.put("contactNo", contactNo); 
	              
	              String contactAmt = recordEless.elementTextTrim("contactAmt");   
	              map.put("contactAmt", contactAmt); 
	              
	              String superviseAmt = recordEless.elementTextTrim("superviseAmt");   
	              map.put("superviseAmt", superviseAmt); 
	              
	              String houseNo = recordEless.elementTextTrim("houseNo");   
	              map.put("houseNo", houseNo); 
	              
	              String houseArea = recordEless.elementTextTrim("houseArea");   
	              map.put("houseArea", houseArea); 
	              
	              String houseAddr = recordEless.elementTextTrim("houseAddr");   
	              map.put("houseAddr", houseAddr); 
	              
	              String backCardName = recordEless.elementTextTrim("backCardName");   
	              map.put("backCardName", backCardName); 
	              
	              String roomNo = recordEless.elementTextTrim("roomNo");   
	              map.put("roomNo", roomNo); 
	              
	              String bankCode = recordEless.elementTextTrim("bankCode");   
	              map.put("bankCode", bankCode); 
	              
	              String unitNo = recordEless.elementTextTrim("unitNo");   
	              map.put("unitNo", unitNo); 
	              
	              String projectName = recordEless.elementTextTrim("projectName");   
	              map.put("projectName", projectName); 
	              
	              String projectNo = recordEless.elementTextTrim("projectNo");   
	              map.put("projectNo", projectNo); 
	              
	              String companyName = recordEless.elementTextTrim("companyName");   
	              map.put("companyName", companyName); 
	              
	              String createDate = recordEless.elementTextTrim("createDate");   
	              map.put("createDate", createDate); 
	              
	              String paymentCode = recordEless.elementTextTrim("paymentCode");   
	              map.put("paymentCode", paymentCode); 
	              
	              String payCont = recordEless.elementTextTrim("payCont");   
	              map.put("payCont", payCont); 
	              
	              String operNo = recordEless.elementTextTrim("operNo");   
	              map.put("operNo", operNo); 
	              
	          }  
	      } catch (DocumentException e) {  
	          e.printStackTrace();  
	      } catch (Exception e) {  
	          e.printStackTrace();  
	      }  
	      return map;  
	  }  
}
傳送xml格式字串請求報文的程式碼
package com.jiuyi.net.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;


public class SubmitUtils {
	
	/**
     * 建立請求,以模擬遠端HTTP的POST請求
     * @param urlStr 請求地址
     * @param xmlInfo 請求的xml內容
     * @return 返回請求內容 xml字串
     * @throws Exception
     */
    public static String buildRequest(String urlStr,String xmlInfo) throws Exception {
    	String strResult = "";
    	HttpURLConnection httpConn = null;
    	BufferedReader bufReader = null;
    	InputStreamReader input = null;
    	
		try {
			URL url = new URL(urlStr);
			httpConn = (HttpURLConnection) url.openConnection();
			httpConn.setFollowRedirects(true);
			httpConn.setDoOutput(true); // 需要向伺服器寫資料
			httpConn.setDoInput(true); //
			httpConn.setUseCaches(false); // 獲得伺服器最新的資訊
			httpConn.setAllowUserInteraction(false);
			httpConn.setRequestMethod("POST");
			httpConn.addRequestProperty("accept", "text/xml;text/html");
			httpConn.addRequestProperty("Content-Type",  "text/xml;charset=utf-8");
			httpConn.addRequestProperty("Accept","image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/x-silverlight, */*");
			httpConn.setRequestProperty("Referer","http://passport.examda.com/?login&tpl=mn&u=http%3A//www.examda.com/");
			httpConn.setRequestProperty("Accept-Language", "zh-cn");
			httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
			httpConn.setRequestProperty("Accept-Encoding","gzip, deflate");
			httpConn.setRequestProperty("User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Foxy/1; .NET CLR 2.0.50727;MEGAUPLOAD 1.0)");
			httpConn.setRequestProperty("Host", "passport.examda.com");
			httpConn.setRequestProperty("Content-Length", xmlInfo.length()+ "");
			
			OutputStream out = httpConn.getOutputStream();
			out.write(xmlInfo.getBytes("UTF-8"));
			out.flush();
			out.close();
			
			input = new InputStreamReader(httpConn.getInputStream(), "UTF-8");
			bufReader = new BufferedReader(input);
			String line = "";
			StringBuilder contentBuf = new StringBuilder();
			
			while ((line = bufReader.readLine()) != null) { 
				contentBuf.append(line);
			}
			strResult = contentBuf.toString();
			
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally{
			if (bufReader!=null){
				bufReader.close();
			}
			if (input != null) {
				input.close();
			}
			if (httpConn != null) {
				httpConn.disconnect();
			}
		}
		return strResult;
    }


}