有没有一种简单的方法(即不使用代理)可以获取使用JAX-WS参考实现(包含在JDK 1.5及更高版本中)发布的Web服务的原始请求/响应XML?
我需要通过代码来实现这一点。
只需通过 clever logging 配置将其记录到文件中就可以了,但这样做可能不够好。
我知道存在其他更复杂和完整的框架,可以完成此任务,但我想保持尽可能简单,而axis、cxf等都会增加相当大的开销,我希望避免这种情况。
谢谢!
有没有一种简单的方法(即不使用代理)可以获取使用JAX-WS参考实现(包含在JDK 1.5及更高版本中)发布的Web服务的原始请求/响应XML?
我需要通过代码来实现这一点。
只需通过 clever logging 配置将其记录到文件中就可以了,但这样做可能不够好。
我知道存在其他更复杂和完整的框架,可以完成此任务,但我想保持尽可能简单,而axis、cxf等都会增加相当大的开销,我希望避免这种情况。
谢谢!
<logger name="com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe" level="trace" additivity="false">
<appender-ref ref="STDOUT"/>
</logger>
这将记录请求和响应,如下所示(取决于日志输出的配置):
最初的回答:
09:50:23.266 [qtp1068445309-21] DEBUG c.s.x.i.w.t.h.c.HttpTransportPipe - ---[HTTP request - http://xyz:8081/xyz.svc]---
Accept: application/soap+xml, multipart/related
Content-Type: application/soap+xml; charset=utf-8;action="http://xyz.Web.Services/IServiceBase/GetAccessTicket"
User-Agent: JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e
<?xml version="1.0" ?><S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope">[CONTENT REMOVED]</S:Envelope>--------------------
09:50:23.312 [qtp1068445309-21] DEBUG c.s.x.i.w.t.h.c.HttpTransportPipe - ---[HTTP response - http://xyz:8081/xyz.svc - 200]---
null: HTTP/1.1 200 OK
Content-Length: 792
Content-Type: application/soap+xml; charset=utf-8
Date: Tue, 12 Feb 2019 14:50:23 GMT
Server: Microsoft-IIS/10.0
X-Powered-By: ASP.NET
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">[CONTENT REMOVED]</s:Envelope>--------------------
我理解得对吗?你想改变/访问原始的XML消息?
如果是这样的话,你(或者说因为这已经是五年之前的事情了,下一个人)可能需要看一看JAXWS中的Provider接口。客户端的对应部分是使用“Dispatch”类完成的。无论如何,你不必添加处理程序或拦截器。当然,你仍然可以这样做。缺点在于,这种方式下,你完全负责构建SOAPMessage,但它很容易,并且如果这正是你想要的(就像我一样),那么这是完美的。
以下是服务器端的示例(有点笨拙,只是为了实验)-
@WebServiceProvider(portName="Provider1Port",serviceName="Provider1",targetNamespace = "http://localhost:8123/SoapContext/SoapPort1")
@ServiceMode(value=Service.Mode.MESSAGE)
public class Provider1 implements Provider<SOAPMessage>
{
public Provider1()
{
}
public SOAPMessage invoke(SOAPMessage request)
{ try{
File log= new File("/home/aneeshb/practiceinapachecxf/log.txt");//creates file object
FileWriter fw=new FileWriter(log);//creates filewriter and actually creates file on disk
fw.write("Provider has been invoked");
fw.write("This is the request"+request.getSOAPBody().getTextContent());
MessageFactory mf = MessageFactory.newInstance();
SOAPFactory sf = SOAPFactory.newInstance();
SOAPMessage response = mf.createMessage();
SOAPBody respBody = response.getSOAPBody();
Name bodyName = sf.createName("Provider1Insertedmainbody");
respBody.addBodyElement(bodyName);
SOAPElement respContent = respBody.addChildElement("provider1");
respContent.setValue("123.00");
response.saveChanges();
fw.write("This is the response"+response.getSOAPBody().getTextContent());
fw.close();
return response;}catch(Exception e){return request;}
}
}
public class ServerJSFB {
protected ServerJSFB() throws Exception {
System.out.println("Starting Server");
System.out.println("Starting SoapService1");
Object implementor = new Provider1();//create implementor
String address = "http://localhost:8123/SoapContext/SoapPort1";
JaxWsServerFactoryBean svrFactory = new JaxWsServerFactoryBean();//create serverfactorybean
svrFactory.setAddress(address);
svrFactory.setServiceBean(implementor);
svrFactory.create();//create the server. equivalent to publishing the endpoint
System.out.println("Starting SoapService1");
}
public static void main(String args[]) throws Exception {
new ServerJSFB();
System.out.println("Server ready...");
Thread.sleep(10 * 60 * 1000);
System.out.println("Server exiting");
System.exit(0);
}
}
或者您可以使用一个Endpoint类来实现。希望这对您有帮助。
如果您将服务模式更改为PAYLOAD(您只会得到Soap Body),您不需要处理头文件等内容。
com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump = true
public static boolean dump;
ServletFilter
,检查请求和响应进入/返回服务的情况。我已经试了几天找一些框架库来记录web service soap请求和响应。下面的代码为我解决了这个问题:
System.setProperty("com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump", "true");
System.setProperty("com.sun.xml.ws.transport.http.HttpAdapter.dump", "true");
System.setProperty("com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump", "true");
System.setProperty("com.sun.xml.internal.ws.transport.http.HttpAdapter.dump", "true");
这个主题中有几个使用SoapHandlers的答案。你应该知道,如果调用writeTo(out)
,SoapHandlers会修改消息。
调用SOAPMessage的writeTo(out)
方法会自动调用saveChanges()
方法。因此,消息中所有附加的MTOM/XOP二进制数据都会丢失。
我不确定为什么会发生这种情况,但似乎这是一个已记录的特性。
此外,此方法标记了从所有组成AttachmentPart对象的数据被拉入消息的点。
https://docs.oracle.com/javase/7/docs/api/javax/xml/soap/SOAPMessage.html#saveChanges()
实际上,如果您查看HttpClientTransport的源代码,您会注意到它还将消息写入java.util.logging.Logger中。这意味着您也可以在日志中看到这些消息。
例如,如果您正在使用Log4J2,则只需要执行以下操作:
完成这些步骤后,您就可以在日志中看到SOAP消息了。
Glassfish/Payara的解决方案
将以下条目添加到记录器设置中(日志级别为FINER
):
在这里发现此处。
<?xml version="1.0" encoding="UTF-8"?>
<webservices-bnd
xmlns="http://websphere.ibm.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-ws-bnd_1_0.xsd"
version="1.0">
<webservice-endpoint-properties
enableLoggingInOutInterceptor="true" />
</webservices-bnd>