在某些场景中AXIS提供很强大的功能,包括添加消息头,提供NTLM等多种认证方式,进行ACK发送的功能,具体参考SAP 的AXIS FQA。
本文档主要讲述PI的AXIS部署以及自定handler,涉及2个handler,一个用于外围系统异步发送系统的时候发生ACK给外围系统,另一个是PI采用Handler实现NTLM V2安全认证。 PI7.31 SP15 ,PI7.4 SP10之后SAP推出了针对Apache HTTP Client library的补丁,参考note 2062567 - Integration of Apache HttpClient library in the PI Axis adapter可以实现NTLM V2。而对于这2个补丁之前的版本SAP不支持 NTLM V2协议。本例的方法是根据SAP的SP包中的相关类进行反编译后的源代码封装成自己的handler类。
首先PI要支持AXIS,则需要部署com.sap.aii.af.axisproviderlib.sda
部署情况可以通过网址http://
commons-codec-1.9. jar(开始使用1.3版本,发现有bug: java.lang.RuntimeException: java.lang.NoSuchMethodError: org.apache.commons.codec.binary.Base64.(I)V;) commons-discovery-0.2.jar commons-httpclient-3.0.jar commons-logging-1.0.4.jar commons-net-1.0.0-dev.jar
httpclient-4.5.1.jar (NTLM V2 用到此包,下面的2个包也一样) httpcore-4.4.4.jar log4j-1.2.91.jar Sandesha-1.0.jar wsdl4j-1.5.1.jar wss4j-1.5.7.jar xalan-2.7.1.jar xmlsec-1.4.2.jar
用工具sdaMakerTool进行压缩。如果是自己开发的handler类没有用到其他PI标准类的话也可以独立部署到这个包中,如果用到了其他类,其他的jar类也一并压缩到这个包中,并要进行加载,另外一种方式是把自定的handler类在SAP 的axis sample adapter中实现,参考AXIS的FQA.
本文档中的两个类都是独立的类,用到的SAP标准的jar文件也压缩到其中。
ACK handler类实现,网上有这个blog,照着blog实现。代码如下。
package com.sap.aii.axis.sample.handlers; import java.io.ByteArrayInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter;
import java.io.StringReader; import java.io.StringWriter; import java.nio.charset.Charset; import java.sql.Timestamp;
import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.Random; import java.util.TimeZone;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.soap.MessageFactory; import javax.xml.soap.MimeHeaders; import javax.xml.soap.SOAPElement; import javax.xml.soap.SOAPException; import javax.xml.soap.SOAPMessage; import javax.xml.transform.OutputKeys; import javax.xml.transform.Source; import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import org.apache.axis.AxisFault; import org.apache.axis.Message;
import org.apache.axis.MessageContext;
import org.apache.axis.components.logger.LogFactory; import org.apache.axis.handlers.BasicHandler; import org.apache.axis.message.SOAPBodyElement; import org.apache.axis.message.SOAPEnvelope; import org.apache.axis.utils.XMLUtils; import org.apache.commons.logging.Log; import org.w3c.dom.Document; import org.w3c.dom.Element;
import org.w3c.dom.ls.DOMImplementationLS; import org.w3c.dom.ls.LSSerializer;
public class ZResponseHandler extends BasicHandler { protected static Log log =
LogFactory.getLog(ZResponseHandler.class.getName());
public void invoke(MessageContext msgContext) throws AxisFault {
/** Response handler to write custom Ariba response */ try {
String Msg_id = msgContext.getStrProp(\); log.info(\+Msg_id); if (Msg_id.equals(\)) Msg_id = \;
String respTxt = createResponseText(Msg_id); /**
* Getting response soap message envelop and add * response message to soap body */
//MessageFactory messageFactory = MessageFactory.newInstance();
MessageFactory messageFactory = new org.apache.axis.soap.MessageFactoryImpl();
// SOAPMessage curMsg = messageFactory.createMessage(new MimeHeaders(),
//getSoapMessageFromString(respTxt);
//setValue(respTxt);
// SOAPMessage curMsg = messageFactory.createMessage();
SOAPMessage msg = messageFactory.createMessage(new MimeHeaders(), new
ByteArrayInputStream(respTxt.getBytes(Charset.forName(\))));
//curMsg.getSOAPPart().getEnvelope().setTextContent(respTxt); msgContext.setMessage(msg);
} catch (Exception e) {
throw AxisFault.makeFault(e); } }
private String createResponseText(String msgid) {
String payloadID = \;
// new
ByteArrayInputStream(respTxt.getBytes(Charset.forName(\