`
alienj
  • 浏览: 81717 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论
阅读更多

第24章. Web服务


Seam 集成了JBossWS,允许标准JEE web服务充分利用Seam的上下文框架的优势, 包括支持对话web服务。本章通过必要的步骤允许web服务运行在一个Seam 环境。

 

24.1. 配置和打包

为了允许Seam拦截web服务请求,以便于可以为请求创建必要Seam上下文,一个特殊的SOAP(简单对象存取协议)处理器必须被配置; org.jboss.seam.webservice.SOAPRequestHandler是一个 SOAPHandler 实现,管理在一个web服务请求作用域期间的Seam的生命周期。


一个特殊的配置文件, standard-jaxws-endpoint-config.xml应该被放在包含web服务类jar文件的META-INF的目录下。这个文件包含下面的SOAP处理器配置:

 

<jaxws-config xmlns="urn:jboss:jaxws-config:2.0" 

 

              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

 

              xmlns:javaee="http://java.sun.com/xml/ns/javaee"

 

              xsi:schemaLocation="urn:jboss:jaxws-config:2.0 jaxws-config_2_0.xsd">

 

   <endpoint-config>

 

      <config-name>Seam WebService Endpoint</config-name>

 

      <pre-handler-chains>

 

         <javaee:handler-chain>

 

            <javaee:protocol-bindings>##SOAP11_HTTP</javaee:protocol-bindings>

 

            <javaee:handler>

 

               <javaee:handler-name>SOAP Request Handler</javaee:handler-name>

 

               <javaee:handler-class>org.jboss.seam.webservice.SOAPRequestHandler</javaee:handler-class>

 

            </javaee:handler>

 

         </javaee:handler-chain>

 

      </pre-handler-chains>

 

   </endpoint-config>

 

</jaxws-config>

 

24.2. 对话的Web服务


那么对话是如何在web服务请求之间传播呢? Seam 使用一个SOAP头元素表示SOAP请求和响应消息,携带着对话ID在消费者与服务器之间传递。这里是一个包含对话ID的web服务的例子:

 

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 

 

    xmlns:seam="http://seambay.example.seam.jboss.org/">

 

  <soapenv:Header>

 

    <seam:conversationId xmlns:seam='http://www.jboss.org/seam/webservice'>2</seam:conversationId>

 

  </soapenv:Header>

 

  <soapenv:Body>

 

    <seam:confirmAuction/>

 

  </soapenv:Body>

 

</soapenv:Envelope>    

 

正如你在上面SOAP消息中看见的,在SOAP头内有一个conversationId 元素,包含了一个请求的对话ID,在这里是2。不幸的是因为web服务由各种语言编写的各种web服务客户端消费,这由开发者实现对话ID在单一对话作用域内使用的单独web服务之间的传播。


注意,一个重要的事情是conversationId头元素必须合乎http://www.jboss.org/seam/webservice的一个命名空间的条件,否则Seam不能读取请求的对话ID 。这里是一个响应上述请求消息的例子:

 

<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'>

 

  <env:Header>

 

    <seam:conversationId xmlns:seam='http://www.jboss.org/seam/webservice'>2</seam:conversationId>

 

  </env:Header>

 

  <env:Body>

 

    <confirmAuctionResponse xmlns="http://seambay.example.seam.jboss.org/"/>

 

  </env:Body>

 

</env:Envelope>    

 

正如你看见的,响应消息包含与请求一样的conversationId元素。

 

24.2.1. 推荐策略


因为web服务必须由无状态会话bean或POJO实现,所以,对于对话web 服务,推荐web服务作为对话Seam组件的一个正面(facade)。

jboss seam reference 2.1(第24章) - *工* - 要有光,于是就有了光

如果web服务作为无状态会话被编写,那么也可以通过@Name注释使其成为Seam组件。这样做便于Seam双向注入 (或其他)功能用于web服务类自身。


24.3. web服务例子


让我们浏览一个web服务例子。这节的所有代码来自Seam的 /examples 目录下的seamBay例子应用程序, 并遵循前节所述的推荐策略。 首先让我们看一看web服务类和它的一个web服务方法:


@Stateless

 

@WebService(name = "AuctionService", serviceName = "AuctionService")

 

public class AuctionService implements AuctionServiceRemote

 

{

 

   @WebMethod

 

   public boolean login(String username, String password)

 

   {

 

      Identity.instance().setUsername(username);

 

      Identity.instance().setPassword(password);

 

      Identity.instance().login();

 

      return Identity.instance().isLoggedIn();

 

   }

 

……

 

}

正如你看见的,我们的web服务是一个无状态会话bean,并用javax.jws包的JWS注释注释了它,如JSR-181定义一样。 @WebService注释告诉容器该类实现了web服务,在login()方法上的@WebMethod注释指明该方法是一个web服务方法。@WebService 注释的Name和 serviceName属性是可选的。


如规范要求的一样,被暴露来作为web服务方法的每个方法必须在web服务类的远程接口中也被声明(当web服务是一个无状态会话bean时)。在上面的例子中, AuctionServiceRemote接口声明了与用@WebMethod注释一样的login()方法。


如你在上面代码中所见的, web服务实现了一个代理Seam内建的Identity组件的login()方法。按照我们推荐的策略,web服务作为一个简单的正面(facade)被编写,假冒Seam组件的真正工作。这样可以最大程度的重用web服务和客户端之间的业务逻辑。


让我看另外一个例子。这个web服务方法通过委托AuctionAction.createAuction()方法开始了一个新的对话:

 

   @WebMethod

 

   public void createAuction(String title, String description, int categoryId)

 

   {

 

      AuctionAction action = (AuctionAction) Component.getInstance(AuctionAction.class, true);

 

      action.createAuction();

 

      action.setDetails(title, description, categoryId);

 

   }

 

下面是来自AuctionAction的代码:


   @Begin

 

   public void createAuction()

 

   {

 

      auction = new Auction();

 

      auction.setAccount(authenticatedAccount);

 

      auction.setStatus(Auction.STATUS_UNLISTED);        

 

      durationDays = DEFAULT_AUCTION_DURATION;

 

   }

从这里我们可以看见,web服务如何通过作为一个正面(facade)并代理对话Seam组件的真正工作参与到长期运行对话。


24.4. 使用RESTEasy的RESTful HTTP web服务


Seam集成了实现了JAX-RS规范(JSR 311)的RESTEasy。 你可以决定要多么“深”地集成到你的Seam应用程序:

  • 无缝集成RESTEasy引导程序和配置,自动侦测资源和供应商。
  • SeamResourceServlet服务HTTP/REST请求,在web.xml中不需要外部的servlet和配置。
  • 编写资源作为Seam组件, 使用完全的Seam生命周期管理和拦截(双向注入)。

24.4.1. RESTEasy配置和请求服务


首先,得到RESTEasy库和jaxrs-api.jar包,与你的应用程序带的其他库一起部署。 还要部署集成的库jboss-seam-resteasy.jar 。


在启动时,所有注释了@javax.ws.rs.Path的类会被自动发现并注册成HTTP资源。 Seam用它内建的SeamResourceServlet自动访问并服务于HTTP请求。资源的URI(统一资源标识符)象下面这样被构建:

  • URI从SeamResourceServlet在web.xml中映射的模式(pattern开始,例如 /seam/resource,如果你按照常规例子。你可以改变这个设置,在不同的基本路径下暴露你RESTful资源。注意,这是一个全局改变,并且其他的Seam资源(例如 s:graphicImage)也是在这个基本路径下提供服务。
  • 然而,Seam集成的RESTEasy为这个基本路径增加了一个可配置字符串,默认是/rest。因此,举例来说,你的资源的完整路径会是/seam/resource/rest。 我们推荐你在你的应用程序中改变这个字符串,你可以添加一个版本号为准备将来REST API升级服务 (老的客户端会保持老的URI基本路径。) ,例如: /seam/resource/restv1。
  • 最后,实际的资源在定义的@Path下是可用的,如,一个用@Path("/customer")映射的资源在/seam/resource/rest/customer下是可用的。  


举一个例子,下面的资源定义会对使用URI http://your.hostname/seam/resource/rest/customer/123的任何GET请求返回一个纯文本表示:


@Path("/customer")

 

public class MyCustomerResource {

 

 

    @GET

 

    @Path("/{customerId}")

 

    @ProduceMime("text/plain")

 

    public String getCustomer(@PathParam("customerId") int id) {

 

         return ...;

 

    }

 

 }

 

如果这些默认是可以接受的,你不需要另外的配置,不必编辑web.xml 或任何其他设置。 然而,你可以在你的Seam 应用程序中配置RESTEasy 。 首先导入resteasy命名空间到你的XML配置文件头:

 

<components

 

   xmlns="http://jboss.com/products/seam/components"

 

   xmlns:resteasy="http://jboss.com/products/seam/resteasy"

 

   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

 

   xsi:schemaLocation=

 

     http://jboss.com/products/seam/resteasy

 

         http://jboss.com/products/seam/resteasy-2.1.xsd

 

     http://jboss.com/products/seam/components

 

         http://jboss.com/products/seam/components-2.1.xsd">

 

然后,你可以象前面提及的改变/rest前缀:

 

<resteasy:application-config resource-path-prefix="/restv1"/>

 

现在你的资源的完整路径是/seam/resource/restv1/{resource} ——注意 ,你的@Path定义和映射并没有改变。这是一种应用广泛的通用开关,用于HTTP API版本。


如果你喜欢在你的资源内映射完整路径,你可以禁用断裂的基本路径:

 

<resteasy:application-config strip-seam-resource-path="false"/>

 

例如,现在资源的路径利用@Path("/seam/resource/rest/customer")来映射。然而,我们反对禁用这个功能,因为你的资源类映射是捆绑到一个特殊的部署情节。


对任何部署的@javax.ws.rs.Path 资源和任何@javax.ws.rs.ext.Provider类,Seam会扫描你的类路径。你可以禁用扫描,并手动配置这些类:

 

<resteasy:application-config

 

     scan-providers="false"

 

     scan-resources="false"

 

     use-builtin-providers="true">

 

 

 

     <resteasy:resource-class-names>

 

         <value>org.foo.MyCustomerResource</value>

 

         <value>org.foo.MyOrderResource</value>

 

     </resteasy:resource-class-names>

 

 

     <resteasy:provider-class-names>

 

         <value>org.foo.MyFancyProvider</value>

 

     </resteasy:provider-class-names>

 

 

 </resteasy:application-config>

 

use-built-in-providers切换启用(默认)或禁用RESTEasy内建供应商。 我们建设你启用它们,因为它们提供纯文本、JSON和JAXB编组的开箱即用功能。

 

最后,你可以配置媒体类型和语言的URI扩展名:

 

<resteasy:application-config>

 

 

    <resteasy:media-type-mappings>

 

       <key>txt</key><value>text/plain</value>

 

    </resteasy:media-type-mappings>

 

 

    <resteasy:language-mappings>

 

       <key>deutsch</key><value>de-DE</value>

 

    </resteasy:language-mappings>

 

 

</resteasy:application-config>

 

这个定义将对附加的访问和访问语言头的值 text/plain和de-DE映射URI后缀为.txt和.deutsc。


24.4.2. 资源和供应商作为Seam组件


默认时RESTEasy管理任何资源和供应商实例。那意味着RESTEasy会实例化一个资源类并且服务于一个请求,然后摧毁它。这是默认的JAX-RS生命周期。供应商对整个应用程序实例化一次,实际上是单独的并且被假定是无状态的。


你可以编写资源和供应商作为Seam组件,得益于丰富的Seam管理的生命周期、双向注入拦截和安全等等。简单地让你的资源类成为一个Seam组件:

@Name("customerResource")

 

@Path("/customer")

 

public class MyCustomerResource {

 

 

    @In

 

    CustomerDAO customerDAO;

 

 

    @GET

 

    @Path("/{customerId}")

 

    @ProduceMime("text/plain")

 

    public String getCustomer(@PathParam("customerId") int id) {

 

         return customerDAO.find(id).getName();

 

    }

 

}

现在,当一个请求访问服务器时,Seam处理customerResource实例。这是一个事件作用域的Seam JavaBean组件,因此不同于默认的JAX-RS生命周期。然而,你完全得到了Seam注入支持和所有其它Seam组件以及你想用的上下文。目前也支持SESSION、 APPLICATION和STATELESS资源组件。请记住,为正确地处理服务边会话上下文,所有的HTTP 请求必须转换成一个有效会话标识符 (cookie, URI路径参数)。


对话作用域(Conversation-scoped资源组件和对话映射目前还不支持,但不久会实现的。


供应商类也是Seam组件, 它们必须是应用作用域(APPLICATION-scoped)或无状态的。

资源和供应商可以是EJBs或JavaBeans, 象所有其它Seam组件一样。

分享到:
评论

相关推荐

    Flex 3 CookBook中文 简体(带书签)

    Flex CookBook 中文 简体 第一章. ActionScript 语言基础 第二章. 自定义类 第三章....第四章....第五章....第六章....第七章....第八章....第九章....第十章....第十一章....第十二章....第十四章....第二十四章. Socket编程(目录)

    MyEclipse.6.Java.开发中文教程

    第一章 安装配置开发环境 ...第十四章.开发JSF应用 第十五章.开发XFire.Web.Service应用 第十六章.开发.EJB.应用 第十七章.MyEclipse.UML.建模 第十八章.图形界面开发--AWT,Swing,SWT 全部代码.rar

    Sybase ASE 15.7 开发文档:Web 服务用户指南

    第 1 章 了解 Adaptive Server Enterprise Web 服务 .......... 3 概述 .......... 3 Adaptive Server Enterprise Web 服务 .......... 4 ASE Web 服务的优点 .......... 4 存储过程和函数 .......... 4 SQL ..........

    嵌入式WEB服务器及远程测控应用详解.rar

    第四章:CGI介绍及表单提交方式 第五章:简单的 LED 测试 第六章:A/D测量及在网页中的显示 第七章: 基于 ZC301摄像头开源视频服务器代码移植 第八章: IP 自动获得的设置和测试 第九章:复杂 LED测试 第十章...

    网络服务器配置完全手册

    第5 章 Web 网站........................................................................................................................................65 5.1 WWW 服务概述.................................

    ASP.NET 3.5开发大全

    第14章.ASP.NET_XML和Web_Service 第15章.图形图像编程 第16章.ASP.NET_3.5和AJAX ...第24章.广告模块设计 第25章.新闻模块设计 第26章.投票模块设计 第27章.聊天模块设计 第28章.制作一个ASP.NET留言本

    D6 SOAP_WEB SERVICE程序设计.part1.rar

    delphi下soap编程指导 第一章 SOAP和Web Service的概念 第二章 组件模型、Internet/Intranet和SOAP 第三章 开发Web Service 第四章 什么是SOAP 第五章 SOAP和数据封装 ...第十四章 在Internet上使用Web Service

    Lotus.Domino.Web编程

    第1章 Domino Web开发综述 1 1.1 为什么使用Domino 1 1.2 Domino是怎样运行的 1 1.2.1 Domino与传统数据库的区别 1 1.2.2 Domino和Web 2 1.3 开发部件 2 1.4 其他工具 3 1.5 简单的Domino Web软件例子 10 参考信息 ...

    servser 2003完整教程part2

    第四章 管理 Active Directory 组对象和组策略....................................................................89 第一节 本地组...........................................................................

    SharePoint.2010.Web.Parts.实战

    **第二章** 中,作者详细介绍了如何在 SharePoint 2010 中使用和配置 Web Parts。这一部分主要涉及以下几点: - **Web Parts 的基本概念**:解释了 Web Parts 架构的基本组成,包括 Web Part 控件、Web Part 区域、...

    Java Web开发实战经典-基础篇课后习题答案及高级篇源码

    MLDN 李兴华 老师 Java Web基础篇课后习题答案,Java Web高级案例篇全部源码。 此源码从最基本的JSP页面到Model ...第十四章.Ajax开发技术:1,2,3,4题 第十五章.Structs基础开发:1题 第十六章.Structs常用标签:1题

    Java Web开发实战经典》

    套源码从最基本的JSP页面到Model 1到Model 2,文件上传,EL,JSTL,Ajax,Structs,一点一点的修改讲解。...第十四章.Ajax开发技术:1,2,3,4题 第十五章.Structs基础开发:1题 第十六章.Structs常用标签:1题

    server2003完整教程part1

    第四章 管理 Active Directory 组对象和组策略....................................................................89 第一节 本地组...........................................................................

    spring.net中文手册在线版

    第二十四章. 与Visual Studio.NET集成 24.1.XML编辑与验证 24.2.XML Schema的版本 24.3.集成API文档 第六部分. 快速入门程序 第二十五章. IoC快速入门 25.1.简介 25.2.Movie Finder 25.2.1.开始建立MovieFinder应用...

    零基础学Java.Web开发

    7. **第十四章 Spring应用详解**: - Spring框架是Java企业级应用的核心,涵盖依赖注入、AOP、MVC等模块。 - 介绍Spring配置文件、Bean的声明和管理,以及Spring MVC的基本流程。 8. **第十五章 Hibernate应用...

    Web设计原理与编程技术.rar

    第一章 Internet与Web基础知识; 第二章 Web协议; 第三章 简单的Web文档; 第四章 JavaScript; 第五章 Web网站设计准则; 第六章 Java概述;...第十四章 JSP语法; 第十五章 JSP与JavaBean; 第十六章 JSP访问数据库;

    Java/JavaEE 学习笔记

    第十四章 标准I/O流与文件.............84 第十五章 网络编程.89 Tiger学习笔记..................94 第一章 Java5.0新特性.......................94 第二章 基础知识.....96 第三章 泛型...........101 第四章 ...

    Web基础Web基础

    IP地址由32位二进制数表示,通常以点分十进制形式表达。此外,还有IPv4和IPv6两种版本,分别有4个和8组16进制数字。 **7. 其他网络服务协议** 除了HTTP,还有FTP(File Transfer Protocol),用于在Internet上进行...

    J2EE学习笔记(J2ee初学者必备手册)

    第十四章 标准I/O流与文件.............84 第十五章 网络编程.89 Tiger学习笔记..................94 第一章 Java5.0新特性.......................94 第二章 基础知识.....96 第三章 泛型...........101 第四章 ...

Global site tag (gtag.js) - Google Analytics