从 J2EE 组件访问 Web 服务:设计详细信息

我们将考虑一个具有 J2EE[TM] 组件的示例应用程序,该组件需要访问不同应用程序的 Web 服务。本文档以 java.netbpcatalog 项目下的面向文档的应用程序为例进行说明。该项使用多个 Web 服务应用程序来说明如何使用不同的策略传递 XML 文档,并且每个应用程序都有一个接收订单的服务端点。所设计的每个端点都有不同的接口和端点实现来处理订单。本示例中,我们将着重介绍如何设计用于访问所部署服务的客户端应用程序。

让我们来看一下客户端应用程序,了解它是如何访问 Web 服务端点的,该端点被设计成将 XML 文档用作结构定义类型。本示例显示了使用 J2EE Web 组件(如 Servlet)的 Web 应用程序访问其他应用程序的 Web 服务的方式。

该应用程序由以下主要实体组成:

下面的 UML 图显示了客户端应用程序的基本结构。

J2EE 客户端

前端控制器

客户端允许用户选择不同的 Web 服务,每种服务分别说明了传递 XML 文档的不同策略。它是 JSP 页的集合,允许用户填写订单表单并提交该表单。所有客户端请求都会通过控制请求流的中央前端控制器。前端控制器会调用请求处理程序。代码示例 1 显示了前端控制器向请求处理程序发出调用,并且在处理请求的过程中出现错误时,将请求转发到错误页。

     resp.setContentType("text/html");
        String responseURL = null;
        String fullURL = req.getRequestURI();
        // get the screen name
        String selectedURL = null;
        int lastPathSeparator = fullURL.lastIndexOf("/") + 1;
        if (lastPathSeparator != -1) {        
            selectedURL = fullURL.substring(lastPathSeparator, fullURL.length());
        }
        responseURL = getResponseURL(selectedURL);   

        if (selectedURL.equals("invokeservice.do")) {
            try {
                handler.handle(req,resp);

            } catch (RequestHandlerException re) {
                req.setAttribute("error_message", re.getMessage());
                responseURL = getResponseURL("error.do");
            }
        }
        getServletConfig().getServletContext()
                .getRequestDispatcher(responseURL).forward(req, resp);

代码示例 1:FrontController.java 中的代码片段

请求处理程序

请求处理程序会处理传入的请求,并调用相应的业务委托以访问 Web 服务端点。请求处理程序还提供相应的响应。请求处理程序通过为请求设置属性以供客户端 JSP 页使用来设置响应消息。在用户可以采取更正操作并从错误状态恢复正常时,请求处理程序会抛出 RequestHandlerException。代码示例 2 显示请求处理程序调用相应的业务委托以处理请求。请注意,请求处理程序从请求参数创建订单对象。
  
          if(request.getParameter("type").equals("String")){
                ret = stringPOService.submitPO(po);
            } else if(request.getParameter("type").equals("Object")){
                ret = schemaPOService.submitPO(po);
            } else if(request.getParameter("type").equals("AnyType")){
                ret = anyTypePOService.submitPO(po);
            } else if(request.getParameter("type").equals("Any")){
                ret = anyPOService.submitPO(po);
            } else if(request.getParameter("type").equals("Attachment")){
                ret = attachmentPOService.submitPO(po);
            }           
            request.setAttribute("result", ret);   

代码示例 2:RequestHandler.java 中的代码片段

业务委托

业务委托向接收结构定义类型的文档的端点发出 JAX-RPC 调用。代码示例 3 显示了调用 Web 服务端点的业务委托。请注意,SchemaPOServiceBD 使用服务定位器模式,该模式在将服务定位器更新为支持 Web 服务的目录项中进行了说明。

  SchemaDefinedPurchaseOrderServiceSEI port = (SchemaDefinedPurchaseOrderServiceSEI)         
   serviceLocator.getServicePort(JNDINames.SCHEMA_SERVICE_REF, SchemaDefinedPurchaseOrderServiceSEI.class);
  ...
  String ret = port.submitPO(order);
代码示例 3:SchemaPOServiceBD.java 中的代码片段

部署描述符

客户端必须在其 web.xml 文件中指定服务引用。下面是 web.xml 中的代码片段:

<service-ref>
    <description>Schema defined Purchase Order Service Client</description>
    <service-ref-name>service/SchemaDefinedPurchaseOrderService</service-ref-name>
    <service-interface>
        com.sun.j2ee.blueprints.docoriented.client.objectposervice.SchemaDefinedPurchaseOrderService
    </service-interface>
    <wsdl-file>WEB-INF/wsdl/SchemaDefinedPurchaseOrderService.wsdl</wsdl-file>
    <jaxrpc-mapping-file>WEB-INF/schemadefinedpurchaseorderservice-mapping.xml</jaxrpc-mapping-file>
    <service-qname      
      xmlns:servicens="urn:SchemaDefinedPurchaseOrderService">servicens:SchemaDefinedPurchaseOrderService
    </service-qname>
</service-ref>
代码示例 4:web.xml 中的代码片段

客户端应用程序访问的 Web 服务应用程序

上述客户端应用程序可以访问五个 Web 服务应用程序。每个应用程序都具有一个服务接口和一个接收订单 XML 文档的服务端点。这些应用程序都很类似,只是在 XML 文档的传递策略上有所不同。这些主题的目录项详细地论述了这些应用程序。

这些服务应用程序均已部署,可以在下表引用的相关 WSDL 文件中查看其接口。

字符串形式的文档
用于 StringPurchaseOrderService 的 WSDL
结构定义的类型形式的文档
用于 SchemaDefinedPurchaseOrderService 的 WSDL
xsd:anyType 形式的文档
用于 AnyTypePurchaseOrderService 的 WSDL
xsd:any 形式的文档
用于 AnyPurchaseOrderService 的 WSDL
附件形式的文档
用于 AttachmentPurchaseOrderService 的 WSDL


© Sun Microsystems 2005。Java BluePrints Solutions Catalog 中的所有内容受版权保护,未经 Sun Microsystems 的明确书面许可,不得在其他产品中发布。