Java CXF:记录请求和响应
我有一个soapweb服务,我想将响应和请求记录为xml字符串。 我知道拦截器,但出于某种原因,这无关紧要,我不能使用它们。 如何从xml消息被解组的对象构造xml请求(和响应)?如何将对象重新命名为xml字符串Java CXF:记录请求和响应,java,xml,soap,cxf,marshalling,Java,Xml,Soap,Cxf,Marshalling,我有一个soapweb服务,我想将响应和请求记录为xml字符串。 我知道拦截器,但出于某种原因,这无关紧要,我不能使用它们。 如何从xml消息被解组的对象构造xml请求(和响应)?如何将对象重新命名为xml字符串 感谢您的帮助。为了封送/取消封送,您需要创建一个与XML文档相同的类“层次结构”。例如: <tests> <lib-data> <library>Library</library> <
感谢您的帮助。为了封送/取消封送,您需要创建一个与XML文档相同的类“层次结构”。例如:
<tests>
<lib-data>
<library>Library</library>
<count>64018</count>
<test-data>
<title>Book title1</title>
<book>Book Name1</book>
<count>5</count>
</test-data>
<test-data>
<title>Book title2</title>
<book>Book Name3</book>
<count>5</count>
</test-data>
<test-data>
<title>Book title3</title>
<book>Book Name3</book>
<count>4</count>
</test-data>
</lib-data>
</tests>
(我还没有编译或测试该代码。它可能包含一两个错误,并且肯定不会考虑异常)
现在,如何处理MarshalHandler的细节完全取决于您,并且将受到程序总体设计的影响。例如,您可能希望封送处理方法返回StreamResult,而不是保存到预定的fileLoc。也许您正在获取这个SOAP响应并将其保存为字节数组,在这种情况下,最好能够将该数组直接传递给您的unmarshall方法。但是,没有更多细节很难说。为了封送/解封送,您需要创建一个与XML文档相同的类“层次结构”。例如:
<tests>
<lib-data>
<library>Library</library>
<count>64018</count>
<test-data>
<title>Book title1</title>
<book>Book Name1</book>
<count>5</count>
</test-data>
<test-data>
<title>Book title2</title>
<book>Book Name3</book>
<count>5</count>
</test-data>
<test-data>
<title>Book title3</title>
<book>Book Name3</book>
<count>4</count>
</test-data>
</lib-data>
</tests>
(我还没有编译或测试该代码。它可能包含一两个错误,并且肯定不会考虑异常)
现在,如何处理MarshalHandler的细节完全取决于您,并且将受到程序总体设计的影响。例如,您可能希望封送处理方法返回StreamResult,而不是保存到预定的fileLoc。也许您正在获取这个SOAP响应并将其保存为字节数组,在这种情况下,最好能够将该数组直接传递给您的unmarshall方法。但是,没有更多的细节很难说。你知道使用拦截器是目前为止最简单的方法吗?日志拦截器正是为了实现这一点 这就是说,如果你不能用简单的方法做事,那么你必须尝试其他方法。例如,您可以拥有自己的
JAXBContext
,并使用它将值写入日志;虽然不会完全一样,但会非常接近
// I assume you've already JAXB-annotated these classes anyway.
JAXBContext c = JAXBContext.newInstance(YourInputPOJO.class, YourOutputPOJO.class);
public YourOutputPOJO theMethod(YourInputPOJO input) {
logMessage("in", "theMethod", input);
YourOutputPOJO output = ...;
logMessage("out", "theMethod", output);
return output;
}
private void logMessage(String dir, String method, Object message) {
Marshaller m = c.createMarshaller();
Writer out = new StringWriter();
m.marshal(message, out);
log.info("message " + dir + ":" + method + "(" + out + ")");
}
不要在每次调用时都使用
JAXBContext
,这相当昂贵,但是使用Marshaller
也不太糟糕。不要在线程之间共享Marshaller
,但是在创建JAXBContext
之后,它是线程安全的。我完全忽略了异常处理…您知道使用拦截器是目前为止最简单的方法吗?日志拦截器正是为了实现这一点
这就是说,如果你不能用简单的方法做事,那么你必须尝试其他方法。例如,您可以拥有自己的JAXBContext
,并使用它将值写入日志;虽然不会完全一样,但会非常接近
// I assume you've already JAXB-annotated these classes anyway.
JAXBContext c = JAXBContext.newInstance(YourInputPOJO.class, YourOutputPOJO.class);
public YourOutputPOJO theMethod(YourInputPOJO input) {
logMessage("in", "theMethod", input);
YourOutputPOJO output = ...;
logMessage("out", "theMethod", output);
return output;
}
private void logMessage(String dir, String method, Object message) {
Marshaller m = c.createMarshaller();
Writer out = new StringWriter();
m.marshal(message, out);
log.info("message " + dir + ":" + method + "(" + out + ")");
}
不要在每次调用时都使用
JAXBContext
,这相当昂贵,但是使用Marshaller
也不太糟糕。不要在线程之间共享Marshaller
,但是在创建JAXBContext
之后,它是线程安全的。我完全忽略了异常处理…CXF内置了日志功能,它只需要一个xml条目
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<cxf:bus>
<cxf:features>
<cxf:logging/>
</cxf:features>
</cxf:bus>
</beans>
Ref:CXF具有内置的日志功能,它只需要一个xml条目
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<cxf:bus>
<cxf:features>
<cxf:logging/>
</cxf:features>
</cxf:bus>
</beans>
Ref:我已经按照你的建议做了。我想问的是“从那里开始”的部分我已经按照你的建议做了。我想问的是“从那里开始”这是使用默认拦截器我想,我说我不能使用拦截器。这是使用默认拦截器我想,我说我不能使用拦截器。这也解决了我的需要,但我只能选择一个答案。所以就投了赞成票。非常感谢你。事实上,这是一条艰难的道路,但没有办法。@alkis我仍然对为什么不能使用拦截器感兴趣。是的,默认的可能不正确,但是使用您自己的应该是可能的,然后它们将能够插入您想要的任何机制。(唉,CXF文档比以前要不清楚了……)Donal说实话,我不知道我是否有权讨论这件事。我不想因为不小心泄露了项目中我不应该透露的方面而惹上麻烦。我完全理解你对拦截器的看法。我一整天都在读关于他们的书。我们可以这么说,对于这个特殊的任务,拦截器带来了很多麻烦,但没有什么价值。这也解决了我的需要,但我只能选择一个答案。所以就投了赞成票。非常感谢你。事实上,这是一条艰难的道路,但没有办法。@alkis我仍然对为什么不能使用拦截器感兴趣。是的,默认的可能不正确,但是使用您自己的应该是可能的,然后它们将能够插入您想要的任何机制。(唉,CXF文档比以前要不清楚了……)Donal说实话,我不知道我是否有权讨论这件事。我不想因为不小心泄露了项目中我不应该透露的方面而惹上麻烦。我完全理解你对拦截器的看法。我一整天都在读关于他们的书。我们可以这么说,对于这个特殊的任务,拦截器带来了很多麻烦,但却没有什么价值。为什么你不能使用拦截器呢?这已经是2年前的事了。我甚至不记得为什么会这样。为什么你不能使用拦截器?这已经两年了。我甚至不记得为什么会这样。