Infor XA ERP的SystemLink响应报文是一段比较复杂的xml,里面记录了操作是否成功的状态以及操作结果或者错误说明。
对SystemLink解析,就是从响应的xml报文里面解析出操作结果状态,如果操作失败,则提取错误消息。因为Infor XA ERP的SystemLink请求分为事务请求、非事务请求,所以解析也有一点点不同,具体细节这里不再说明。直接上代码,看我是如何用java代码解析报文的
解析抽象类:
package cn.markwins.yinfor.utils.xml;import java.util.List;import org.xml.sax.helpers.DefaultHandler;import cn.markwins.yinfor.utils.vo.systemlink.SystemLinkMessage;public abstract class SystemLinkStockDefaultHandler extends DefaultHandler{ /* 返回的消息 */ PRotected SystemLinkMessage systemLinkMessage = null; protected List<String> systemLinkExceptionList = null; public SystemLinkMessage getSystemLinkMessage() { return systemLinkMessage; } protected String preTagName = null;}解析非事务类型的SystemLink报文:package cn.markwins.yinfor.utils.xml;import java.util.ArrayList;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import cn.markwins.yinfor.utils.common.StringTools;import cn.markwins.yinfor.utils.vo.systemlink.SystemLinkMessage;/** * @Description 无事务控制单一的SystemLink响应报文xml解析器 * @author 李yi辉 * @date 2016年7月5日 */public class SystemLinkTransactionNHandler extends SystemLinkStockDefaultHandler { private boolean messageTypeError = false; private boolean responseTag = false; private boolean exceptionTag = false; private boolean messageTag = false; private int errMsgIndex = 0; @Override public void startDocument() throws SAXException { systemLinkMessage = new SystemLinkMessage(); systemLinkExceptionList = new ArrayList<>(); systemLinkMessage.setStatus(true); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if(qName.matches("[A-Za-z0-9]+Response$")){ responseTag = true; if("LoginResponse".equals(qName)){ if("false".equals(attributes.getValue("actionSucceeded"))){ systemLinkMessage.setStatus(false); } } }else{ switch (qName) { case "Exception": exceptionTag = true; errMsgIndex = 0; break; case "Response": if("true".equals(attributes.getValue("hasErrors"))){ systemLinkMessage.setStatus(false); } break; case "Message": messageTag = true; if("error".equals(attributes.getValue("type"))){ messageTypeError = true; ++errMsgIndex; } break; default: break; } } this.preTagName = qName; } @Override public void characters(char[] ch, int start, int length) throws SAXException { //异常信息节点 if(messageTypeError && messageTag && exceptionTag && "Text".equals(this.preTagName)){ String text = null; if(!responseTag){ //还没进入任何Response就出现异常信息,则表示SystemLink服务器异常,处理失败 systemLinkMessage.setStatus(false); } if(!systemLinkMessage.getStatus()){ text = new String(ch, start, length); } if(!StringTools.isNullOrWhiteSpace(text)){// if(systemLinkExceptionList.isEmpty()){ //只取最后一个error类型的消息响应// systemLinkExceptionList.add(text);// }else{// systemLinkExceptionList.set(0, text);// } if(errMsgIndex == 2 && systemLinkExceptionList.size() < 2){ //如果有2个或2个以上的错误,则第一个错误肯定是泛泛总结描述有错误 systemLinkExceptionList.set(0, text); }else{ //其它情况,则是具体的错误信息 systemLinkExceptionList.add(text); } } } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if(qName.matches("[A-Za-z0-9]+Response$")){ responseTag = false; }else{ switch (qName) { case "Message": messageTag = false; messageTypeError = false; break; case "Exception": exceptionTag = false; break; default: break; } } this.preTagName = null; } @Override public void endDocument() throws SAXException { if(!systemLinkMessage.getStatus()){ systemLinkMessage.setSystemLinkExceptionList(systemLinkExceptionList); } }}解析事务类型的SystemLink响应报文:
package cn.markwins.yinfor.utils.xml;import java.util.ArrayList;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import cn.markwins.yinfor.utils.common.StringTools;import cn.markwins.yinfor.utils.vo.systemlink.SystemLinkMessage;/** * @Description 事务控制的SystemLink响应报文xml解析器 * @author 李yi辉 * @date 2016年7月5日 */public class SystemLinkTransactionYHandler extends SystemLinkStockDefaultHandler { private boolean messageTypeError = false; private boolean responseTag = false; private boolean exceptionTag = false; private boolean messageTag = false; private int errMsgIndex = 0; private String responseName = null; private Integer txReqIndex = null; @Override public void startDocument() throws SAXException { systemLinkMessage = new SystemLinkMessage(); systemLinkExceptionList = new ArrayList<>(); systemLinkMessage.setStatus(true); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if(qName.matches("[A-Za-z0-9]+Response$")){ responseTag = true; if("LoginResponse".equals(qName)){ if("false".equals(attributes.getValue("actionSucceeded"))){ systemLinkMessage.setStatus(false); } }else{ responseName = attributes.getValue("name"); if(!StringTools.isNullOrWhiteSpace(responseName)){ int dashIndex = responseName.lastIndexOf('_'); if(dashIndex > 1){ txReqIndex = Integer.valueOf(responseName.substring(dashIndex + 1, responseName.length())); } } } }else{ switch (qName) { case "Exception": exceptionTag = true; errMsgIndex = 0; break; case "Response": if("true".equals(attributes.getValue("hasErrors"))){ systemLinkMessage.setStatus(false); } break; case "Message": messageTag = true; if("error".equals(attributes.getValue("type"))){ messageTypeError = true; ++errMsgIndex; } break; default: break; } } this.preTagName = qName; } @Override public void characters(char[] ch, int start, int length) throws SAXException { //异常信息节点 if(messageTypeError && messageTag && exceptionTag && "Text".equals(this.preTagName)){ String text = null; //还没进入任何Response就出现异常信息,则表示SystemLink服务器异常,处理失败 if(!responseTag){ systemLinkMessage.setStatus(false); } //systemLink响应错误消息 if(!systemLinkMessage.getStatus()){ text = new String(ch, start, length); } if(!StringTools.isNullOrWhiteSpace(text)){ if(errMsgIndex == 2 && systemLinkExceptionList.size() < 2){ //如果有2个或2个以上的错误,则第一个错误肯定是泛泛总结描述有错误 systemLinkExceptionList.set(0, text); }else{ //其它情况,则是具体的错误信息 if(txReqIndex != null && txReqIndex > 0){ text = txReqIndex + ":" + text; } systemLinkExceptionList.add(text); } } } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if(qName.matches("[A-Za-z0-9]+Response$")){ responseTag = false; responseName = null; txReqIndex = null; }else{ switch (qName) { case "Message": messageTag = false; messageTypeError = false; break; case "Exception": exceptionTag = false; break; default: break; } } this.preTagName = null; } @Override public void endDocument() throws SAXException { if(!systemLinkMessage.getStatus()){ systemLinkMessage.setSystemLinkExceptionList(systemLinkExceptionList); } }}最后这个就是通用调用入口的工具类:
package cn.markwins.yinfor.utils.xml;import java.util.ArrayList;import java.util.List;import javax.xml.parsers.SAXParser;import javax.xml.parsers.SAXParserFactory;import org.apache.log4j.Logger;import cn.markwins.yinfor.utils.common.StreamTools;import cn.markwins.yinfor.utils.common.StringTools;import cn.markwins.yinfor.utils.vo.systemlink.SystemLinkMessage;/** * @Description SystemLink响应消息解析器 * @author 李yi辉 * @date 2016年7月6日 */public class SystemLinkRespMessageTools { private static Logger logger = Logger.getLogger(SystemLinkRespMessageTools.class); /** * @Description 解析systemLink消息响应 * @param systemLinkRespXML systemLink的xml响应消息 * @param transactionFlag 解析方式 * true:事务类型systemLink xml响应 * false:非事务类型systemLink xml响应 * @return SystemLinkMessage 解析后的消息封装 */ public static SystemLinkMessage parseStockSystemLinkRespXML(String systemLinkRespXML, boolean transactionFlag) { SystemLinkMessage systemLinkMessage = new SystemLinkMessage(); systemLinkMessage.setStatus(false); List<String> systemLinkExceptionList = new ArrayList<>(); //长时间无响应 if(StringTools.isNullOrWhiteSpace(systemLinkRespXML)){ systemLinkExceptionList.add("XA系统长时间无响应,请于Infor XA系统检查是否已过账,并反馈系统管理员"); systemLinkMessage.setSystemLinkExceptionList(systemLinkExceptionList); logger.error("Infor XA SystemLink 长时间无响应,无响应报文"); return systemLinkMessage; } //响应报文非标准化的xml,sax无法解析,特殊处理 /*1、com.pjx.xsaa.entry.ServerNotFoundException*/ if(systemLinkRespXML.contains("com.pjx.xsaa.entry.ServerNotFoundException")){ systemLinkExceptionList.add("过账失败,Infor XA SystemLink Server未开启,请反馈系统管理员"); systemLinkMessage.setSystemLinkExceptionList(systemLinkExceptionList); return systemLinkMessage; } //解析报文 try { SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); SAXParser saxParser = saxParserFactory.newSAXParser(); SystemLinkStockDefaultHandler handler = null; if(transactionFlag){ handler = new SystemLinkTransactionYHandler(); //开启systemLink事务的解析器 }else{ handler = new SystemLinkTransactionNHandler(); //没启SystemLink事务的解析器 } saxParser.parse(StreamTools.getInputStreamFromString(systemLinkRespXML), handler); SystemLinkMessage systemLinkMessageParsed = handler.getSystemLinkMessage(); if(systemLinkMessageParsed == null || systemLinkMessageParsed.getStatus() == null){ systemLinkExceptionList.add("系统异常,请于XA ERP检查是否已过账,并反馈系统管理员"); systemLinkMessage.setSystemLinkExceptionList(systemLinkExceptionList); logger.error("SystemLink消息解析异常,无法提取解析状态"); return systemLinkMessage; } systemLinkMessage.setStatus(systemLinkMessageParsed.getStatus()); systemLinkMessage.setSystemLinkExceptionList(systemLinkMessageParsed.getSystemLinkExceptionList()); } catch (Exception e) { systemLinkMessage.setStatus(false); systemLinkExceptionList.add("系统异常,请于XA ERP检查是否已过账,并反馈系统管理员"); systemLinkMessage.setSystemLinkExceptionList(systemLinkExceptionList); logger.error("系统异常,请于Infor XA系统检查是否已过账,并反馈系统管理员--SystemLink消息解析异常", e); } return systemLinkMessage; }}http://blog.csdn.net/yihuiworld
新闻热点
疑难解答