package com.steven.junit.project2; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.lang.reflect.Method; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.xml.parsers.SAXParserFactory; import junit.framework.TestCase; import mpi.client.common.MPIConstants; import mpi.client.common.msg.Base64Coder; import mpi.client.common.msg.DeflacterProc; import mpi.client.common.msg.InflaterProc; import mpi.client.exception.PayException; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class TestCoreJava2 extends TestCase { OrderData orderData = new OrderData(); // 正规的Xml都是要一个开始元素和结束元素的。 所以<Doc>...</Doc> 不能少 String xml = "<Doc><SeqId>111</SeqId><InsName>222</InsName><Amount>333</Amount><Date>444</Date></Doc>"; @Override protected void setUp() throws Exception { orderData.setSeqId("700000000000001"); orderData.setInsName("222"); orderData.setAmount("333323"); orderData.setDate("20120808"); } /** * 将Bean转换成XML * @throws PayException */ public void testParseBean2XML() throws PayException{ StringBuffer sb = new StringBuffer(); parseBean2XML(sb, orderData); System.out.println(sb.toString()); } //加签,加密太复杂. 放弃 /** * 压缩编码 * @throws PayException * @throws UnsupportedEncodingException */ public void testDefalteEncode() throws UnsupportedEncodingException, PayException{ System.out.println(new String(deflateEncode(xml.getBytes("UTF-8")))); //eJyzCU4t9EyxMzQ0tNGHMG0884r9EnNT7YyMjGz0YRwbx9z80rwSO2NjYxt9KNvGJbEkFSICZgEAkTgXzg== } /** * 解码解压 * @throws Exception */ public void testDecodeInflate() throws Exception{ System.out.println(new String(decodeInflate(deflateEncode(xml.getBytes("UTF-8"))))); } /** * 将xml转成Bean. 使用JDK另一个jar包 rt.jar 的DefaultHandler来处理 * @throws Exception */ public void testParseXML2Bean() throws Exception{ String xml2 = "<Doc><SeqId>111</SeqId><InsName>222</InsName><Amount>333</Amount><Date>444</Date></Doc>"; OrderData bean = parseXML2Bean(xml2.getBytes("UTF-8")); assertEquals("111", bean.getSeqId()); assertEquals("222", bean.getInsName()); assertEquals("444", bean.getDate()); } /** * 用正则表达式来验证bean中的字段 * ^\\d{3}$ */ public void testMsgCheck(){ assertEquals("success", msgCheck(orderData)[0]); orderData.setDate("abcdefgh"); assertEquals("fail", msgCheck(orderData)[0]); orderData.setDate("20120808"); orderData.setInsName("心有灵犀的"); assertEquals("success", msgCheck(orderData)[0]); } /** * 通用MPI报文域检查 */ private String[] msgCheck(OrderData vo) { // 返回校验结果,第一位 :应答码,第二位 :错误信息,成功是信息为"" String[] result = new String[2]; // 默认返回校验失败 result[0] = "fail"; // 正则校验 Pattern pattern; Matcher matcher; // 存放获取到的报文域的值 Object o; try { // 获取交易码对应交易的报文校验规则 String[][] configs = MPIReqCheckConfig.getConfig("1010"); if (null != configs) { for (String[] config : configs) { // 反射获取get方法 Method m = vo.getClass().getMethod("get" + config[0]); if (null != m) { m.setAccessible(true); // 取消 Java 语言访问检查 o = m.invoke(vo); // 用get方法取值 if (null == o || o.toString().trim().isEmpty()) {// 空指针或全空格都认为是空 if ("M".equals(config[2])) {// 必填项为空 result[1] = config[0] + "为空"; return result; } } else {// 根据配置的正则校验报文域 pattern = Pattern.compile(config[1]); matcher = pattern.matcher(o.toString().trim()); if (!matcher.matches()) {// 格式校验失败 result[1] = config[0] + "格式有误"; return result; } } } else {// 在报文VO中没有找到对应的get方法 result[1] = config[0] + "域不存在"; return result; } } } } catch (Exception e) {// 未知错误 result[0] = "系统错误"; result[1] = "系统错误"; return result; } result[0] = "success"; result[1] = ""; // 返回结果 return result; } /** * 根据送入的XML报文解析生成MPIReq对象 * * @param inByte * @return * @throws IOException * @throws SAXException */ private OrderData parseXML2Bean(byte[] inByte) { InputStream inStream = new ByteArrayInputStream(inByte); try { OrderDataHandler handler = new OrderDataHandler(); SAXParserFactory.newInstance().newSAXParser().parse(inStream, handler); return handler.getOrderData(); } catch (Exception e) { e.printStackTrace(); return null; } finally { try { inStream.close(); } catch (IOException ioex) { inStream = null; } } } /** * 解码解压缩 * * @param inputByte * @return * @throws IOException */ private static byte[] decodeInflate(byte[] inputByte) throws IOException { try { if (inputByte == null || inputByte.length == 0) { throw new IOException("解码解压缩异常:输入不能为空!"); } byte[] tmpByte = base64Coder.decode(inputByte); return inflater.inflater(tmpByte); } catch (IOException ioex) { return null; } } private byte[] deflateEncode(byte[] inputByte) throws PayException { try { if (inputByte == null || inputByte.length == 0) { throw new PayException("压缩输入不能为空"); } byte[] tmpByte = deflacter.deflater(inputByte); //System.out.println(new String(tmpByte)); //输出结果: x湷 N-鬖�4囱�<髪�sS韺寣l鬭擒�;ccc}(燮%�$"f return base64Coder.encode(tmpByte); } catch (Exception e) { throw new PayException("压缩编码失败", e); } } private class OrderData{ private String seqId; private String insName; private String amount; private String date; public String getSeqId() { return seqId; } public void setSeqId(String seqId) { this.seqId = seqId; } public String getInsName() { return insName; } public void setInsName(String insName) { this.insName = insName; } public String getAmount() { return amount; } public void setAmount(String amount) { this.amount = amount; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } } /** * Description: MPIReq XML报文处理类 * * (C) Copyright of China UnionPay Co., Ltd. 2010. * * @author Tiffany.deng * @version 1.0.0 */ private class OrderDataHandler extends DefaultHandler { private String currQname = ""; private OrderData OrderData = null; public OrderDataHandler() { this.OrderData = new OrderData();; } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { currQname = qName; } @Override public void endElement(String uri, String localName, String qName) throws SAXException { } @Override public void characters(char[] ch, int start, int length) throws SAXException { String val = new String(ch, start, length); setPropVal(currQname, val, this.OrderData); } private void setPropVal(String qName, String val, OrderData vo) { Method m = null; try { m = vo.getClass().getMethod("set" + qName, String.class); m.setAccessible(true); // 取消 Java 语言访问检查 m.invoke(vo, val); } catch (Exception ex) { ex.printStackTrace(); return; } } public OrderData getOrderData() { return OrderData; } public void setOrderData(OrderData OrderData) { this.OrderData = OrderData; } } private void parseBean2XML(StringBuffer sb, Object o) throws PayException { try { Method[] ms = o.getClass().getDeclaredMethods(); for (int i = 0; i < ms.length; i++) { Method m = ms[i]; m.setAccessible(true); // 取消 Java 语言访问检查 String paramNm = null; String paramVal = null; if (m.getName().startsWith("get")) { // 通过去掉get前缀的方式获取字段名 paramNm = m.getName().substring(3); // 获取字段值 try { if (null != m.invoke(o, new Object[]{})) { paramVal = m.invoke(o, new Object[]{}).toString(); } } catch (Exception ex) { System.out.println("转换MPIRes异常,字段名=[" + paramNm + "],将该字段值设置为空字符串\n"); } sb.append(tNodeHeadStart); sb.append(paramNm); sb.append(tNodeEnd); if (null != paramVal && !"".equals(paramVal.trim())) { sb.append(paramVal); } sb.append(tNodeFootStart); sb.append(paramNm); sb.append(tNodeEnd); } } } catch (Exception e) { throw new PayException("转换MPIRes异常", e); } } /** * 压缩处理器 */ private static final DeflacterProc deflacter = new DeflacterProc(); /** * 解压缩处理器 */ private static final InflaterProc inflater = new InflaterProc(); /** * BASE64编解码器 */ private static final Base64Coder base64Coder = new Base64Coder(); private static final String tNodeHeadStart = "<"; private static final String tNodeEnd = ">"; private static final String tNodeFootStart = "</"; }