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
新聞熱點
疑難解答