【问题标题】:Architecture for building XML requests?构建 XML 请求的架构?
【发布时间】:2014-01-21 21:27:44
【问题描述】:

我正在编写一个使用soap xml webservices 的客户端工具(使用CXF 从提供的wsdl 中自动生成类)。我想知道哪种设计最适合构建我想要发送到 Web 服务的 xml 请求。我的问题是要发送的请求必须由许多不同的部分/对象组成。我正在寻找一种简洁的方式来构建这些部分的创建,最终形成完整的请求。

请求可能会增长到 200-500 个 XML 行,因此在一个类中创建所有这些可能是个坏主意。

为了说明我的目标,假设一个请求需要一个 Person 对象,并且必须在该对象上设置一些参数,例如姓名、生日、地址等。我可以想到以下设计:

1) 返回构造的 xml 部分的静态实用程序

class XMLUtil {
    public static PersonType createPerson(String name, String birthday, Address Address) {
        //the xml person to send within the request
        PersonType p = new PersonType();
        p.setName(name);
        p.setBirthday(birthday);
        p.setAddress(address);
        //assume some more params, but the concept is clear I hope
        return p;
    }
}

2) 将构造的 xml 部分添加到 xml 请求的静态实用程序

class XMLUtil {
    public static void addPerson(WebserviceReq req, String name, String birthday, Address Address) {
        //create person as above
        req.addPerson(p);
    }
}

3) 非静态服务

class XMLService {
    private WebserviceReq req;

    public XMLService(WebserviceReq req) {
        this.req = req;
    }

    public void createPerson(String name, String birthday, Address Address) {
        //create person as above
        req.addPerson(p);
    }

    public WebserviceReq getWebserviceReq() {
        return req;
    }
}

用法:

1)

WebserviceReq req = new WebserviceReq();
req.addPerson(XMLUtil.createPerson("test", "2014-01-01", address));
req.send();

2)

WebserviceReq req = new WebserviceReq();
XMLUtil.addPerson(req, "test", "2014-01-01", address);
req.send();

3)

WebserviceReq req = new WebserviceReq();
XMLService service = new XMLService(req);
service.createPerson("test", "2014-01-01", address);
service.getWebserviceReq();
req.send();

如果不仅要为 xml 请求构建一个 person 对象,而且还有很多你试图以某种方式封装的部分,那么你会更喜欢哪种方法?

【问题讨论】:

    标签: java xml web-services soap


    【解决方案1】:

    我已经做过并使用了很多次效果很好的是以下......

    为 XML 中的每个元素类型创建一组类 - 这包括以下...

    Node - 所有元素的基类。支持属性的设置和获取。 Leaf - 任何包含值的元素的基类(简单元素) 分支 - 叶元素的集合。通过索引访问子级。 实体 - 允许对其子项进行密钥访问的分支。

    与您现在的做法相反,您有一个名为 Person 的 bean,它具有私有变量并且需要代码来设置和获取每个值,例如,您将使用 Entity 实例并向其添加叶实例。 ..

    Entity person = new Entity("Person");
    person.add(new Leaf<String>("FirstName", "Rodney"));
    person.add(new Leaf<String>("LastName", "Barbati"));
    

    这里的强大之处在于增加了基类将自己写成 XML 的能力。这使您能够快速创建新类型,而无需编写代码将它们转换为 XML。

    您还可以通过从 Entity 派生 person 类并在其构造函数中添加子元素来使其完全透明。我还建议您添加一个验证方法来检查每个所需子项的存在和正确格式。

    Java 中提供了一些用于处理 XML 元素的类,但它们有些繁琐且不易使用。您可以考虑包装它们或从它们派生以使它们更易于使用。

    以上内容使您无需样板代码即可轻松输出 XML - 如果您将其与可以为给定元素构造给定类的自定义 SAX 解析器结合使用,您就有了高速、流式 XML 服务的完整基础几乎可以立即用很少的代码行支持新的数据类型 - 通常根本不需要。

    如果您发现自己编写自定义代码来输出任何 XML 结构,请理解您不必这样做 - 有更好的解决方案。

    顺便说一句:上面的类非常适合在 Spring 中定义数据结构。

    祝你好运,

    罗德尼·巴巴蒂

    【讨论】:

    • 一般来说是个好主意,但是:我有根据 web 服务提供的 wsdl 自动生成的 web 服务类。使用你的方法,我必须进一步为我想要使用的生成类创建一个包装类......
    • 是的,确实如此——无论如何,您还必须编写一个新类以提供任何功能,因为您生成的类实际上并没有任何功能。在这些类中,您必须显式引用生成的类的所有数据成员。
    猜你喜欢
    • 2013-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-18
    • 1970-01-01
    • 1970-01-01
    • 2019-04-14
    相关资源
    最近更新 更多