繁体   English   中英

CXF:记录请求和响应

[英]CXF: Logging request and response

我有一个soap Web服务,我想将响应和请求记录为xml字符串。 我知道拦截器,但由于某种原因,这无所谓,我不能使用它们。 如何从xml消息被解组到的对象构造xml请求(和响应)? 如何将对象重新编组为xml字符串?

谢谢您的帮助。

为了Marshal / 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>

我将创建一个带有单个属性的'tests'类 - 一个'lib-data'类的ArrayList。

在每个lib-data类中,我将创建一个名为library的String字段,一个名为count的int字段和一个'test-data'类的ArrayList。

对于每个测试数据类,我将创建String title和book属性以及int count属性。

从那里,只需添加正确的@XmlRootElement(在每个类之前)和@XmlElement(在每个属性之前)注释。 在那之后,您可以使用Jaxb进行实际的编组和解组。

编辑:

对不起,你的问题非常开放,所以我不确定你创造了多少。

XML注释非常简单,对于'tests'类,它看起来像这样:

@XmlRootElement
public class Tests {

    @XmlElement(name="lib-data")
    ArrayList<LibData> libData;

    public Tests()
    {
        this.libData = new ArrayList<LibData>()
    }


    public ArrayList<LibData> getLibData() {
        return this.libData;
    }

    public void setLibData(ArrayList<LibData> libData) {
        this.libData = libData;
    }
}

我还会创建一个'MarshalHandler'类,它隐藏了编组和解组的实现细节:

public class MarshalHandler {

    private JAXBContext jc;
    private Unmarshaller unmarshaller;
    private Marshaller marshaler;

    public MarshalHandler(){
        jc = JAXBContext.newInstance(Tests.class);
        unmarshaller = jc.createUnmarshaller();
        marshaler = jc.createMarshaller();
    }


    public Test unmarshall(File f){
        return (Tests) unmarshaller.unmarshal(f);
    }

    public void marshal(Tests t, String fileLoc){
        OutputStream os = new FileOutputStream(fileLoc);
        marshaler.marshal(t, os);
        os.flush();
        os.close();
    }
}

(我没有编译或测试过该代码。它可能包含一两个错误,但绝对不会考虑异常)

现在,您如何处理MarshalHandler的细节完全取决于您,并将受到您的程序整体设计的影响。 例如,您可能希望您的marshal方法返回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是线程安全的。 而且我完全省略了异常处理......

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>

参考: http//cxf.apache.org/docs/configuration.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM