`
xiangxingchina
  • 浏览: 520100 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Spring Web Services 框架入门研究--发布服务

阅读更多

关于Spring Web Services框架
Spring web services(以下简称:Spring WS)框架是springframework东家SpringSource公司旗下的一个子项目。目前的版本是1.5M1,最新版本可以从spirngframework网站下载,项目地址是:http://www.springframework.org/node/567
由于怀着对spring框架的热爱,于是打算学习下这个框架。

 

Spring Web Services框架的特点

  • Spring框架的支持,你可以重用Spring的所有特性。
  • Spring WS使用Contract First(自顶向下)的设计方式。Spring WS不支持Contract Last(自底向上)
  • 支持几乎所有的XML API,处理传入XML消息的时候就不限于JAX-P,可以是任意的XML API,选择你所擅长的。
  • 灵活的XML Marshalling,Object/XML mapping产品的支持,包括JAX-B1,2,XMLBean以及Castor等等
  • Security支持,集成了Acegi.实现web services 认证。

Spring Web Services框架的分析

 

     1.为什么使用Contract First.

 

   最佳实践认为:使用自顶向下的设计方式也就是采用XML/XSD to JAVA可以获得更多的益处,包括以下几点.

  • 重 用性,web services或者SOA的很大优势在于对业务的快速响应,那么设计与开发web services的时候如果能够在服务的重用上做足,做强,无疑在以后业务的响应上会带来莫大的好处,使用Contract First,使用XML/XSD定义服务,你可以获得重用,而java则很难做到这一点。
  • 性能,web servers的性能一直是众多人士关注的,采用Contract Last经常会由于java的引用造成内存中存在众多的reference,假设一个java 对象引用了5个以上的其他对上,再把这些对象转换成XML,可想而知。必然加大内存的开销,(XML里面表述起来就像有5个字节点一样,那么更多呢?)采 用Contract First,你很明白的所想要的服务,你通过撰写XSD来描述你的服务,你很清楚你的引用。
  • 版本,使用 Contract Last的时候,快速响应的服务是会经常修改来适应新的业务要求,你发布服务通过java类来开始,那么新的服务在java中意味着新的接口以及新的实 现,那么怎么办?废弃原来的?也许原来的还在使用,那么你得保持两个服务。采用Contract Last,由于Contract的松散耦合,它允许你存在两套服务的同时,并且只有一个实现。

这样造成了Contract Last的问题:自底向上生成经常会得到无法重用的类型定义以及多个定义为表示语义等效信息的类型。相比而言: XML 模式规范定义范围比 Java 更广的用于描述消息结构的构造。其中包括各个选择、限制的派生、Annotation 及其他。因此,与采用其他方式相比,使用 WSDL 和 XSD 定义接口并生成框架 Java 代码的方式更好

 

比较二者,其实最大优劣的莫过于服务的变化性,Contract Last会让服务难于修改和快速变更,难于重用,用java开始设计,那么你最好保证你的服务是永久不改变的,或者事先你得反复审查你的服务接口。使其尽量保持不变性。

 

     2.例子引入

 

Spring Web Servers提供了丰富的例子可供学习,下载其完整包可以在samples下面找到。这里也引用其中一个Echo sample介绍其开发过程。该例子实现web services client调用服务传送名字到服务器。然后服务提供者接收该名字,并附加信息返回给调用者。

  • 一切开始于XML.

定义你的XML

Xml代码
  1. < sch:EchoRequest   xmlns:sch = "http://www.upyaya.org/echo/schemas" >   
  2.   < sch:Echo >   
  3.     < sch:Name > string </ sch:Name >   
  4.   </ sch:Echo >   
  5. </ sch:EchoRequest >   
<sch:EchoRequest xmlns:sch="http://www.upyaya.org/echo/schemas">
  <sch:Echo>
    <sch:Name>string</sch:Name>
  </sch:Echo>
</sch:EchoRequest>

使用XML Buddy转换成XSD.

 

Xml代码
  1. <? xml   version = "1.0"   encoding = "UTF-8" ?>   
  2. <!-- Generated from echo.xml by XMLBuddy -->   
  3. < xs:schema   xmlns:xs = "http://www.w3.org/2001/XMLSchema"   
  4.            targetNamespace = "http://www.upyaya.org/echo/schemas"   
  5.            xmlns = "http://www.upyaya.org/echo/schemas"   
  6.            elementFormDefault = "qualified" >   
  7.     < xs:element   name = "Echo" >   
  8.         < xs:complexType >   
  9.             < xs:sequence >   
  10.                 < xs:element   ref = "Name" />   
  11.             </ xs:sequence >   
  12.         </ xs:complexType >   
  13.     </ xs:element >   
  14.     < xs:element   name = "EchoRequest" >   
  15.         < xs:complexType >   
  16.             < xs:sequence >   
  17.                 < xs:element   ref = "Echo" />   
  18.             </ xs:sequence >   
  19.         </ xs:complexType >   
  20.     </ xs:element >   
  21.     < xs:element   name = "Name"   type = "xs:string" />   
  22. </ xs:schema >   
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated from echo.xml by XMLBuddy -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://www.upyaya.org/echo/schemas"
           xmlns="http://www.upyaya.org/echo/schemas"
           elementFormDefault="qualified">
	<xs:element name="Echo">
		<xs:complexType>
			<xs:sequence>
				<xs:element ref="Name"/>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
	<xs:element name="EchoRequest">
		<xs:complexType>
			<xs:sequence>
				<xs:element ref="Echo"/>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
	<xs:element name="Name" type="xs:string"/>
</xs:schema>

 

当你熟悉了XSD的写法的时候,完全不用前面的XML开路。编辑一下XSD让其好看点,并未这个定义加上web services响应代码。结果如下:

Xml代码
  1. < xs:schema   xmlns:xs = "http://www.w3.org/2001/XMLSchema"   
  2.     xmlns:tns = "http://www.upyaya.org/echo/schemas"   elementFormDefault = "qualified"   
  3.     targetNamespace = "http://www.upyaya.org/echo/schemas" >   
  4.     < xs:element   name = "EchoRequest" >   
  5.         < xs:complexType >   
  6.             < xs:all >   
  7.                 < xs:element   name = "Echo"   type = "tns:EchoType" />   
  8.             </ xs:all >   
  9.         </ xs:complexType >   
  10.     </ xs:element >   
  11.     < xs:element   name = "EchoResponse" >   
  12.         < xs:complexType >   
  13.             < xs:all >   
  14.                 < xs:element   name = "EchoResponse"   type = "tns:ReturnType" />   
  15.             </ xs:all >   
  16.         </ xs:complexType >   
  17.     </ xs:element >   
  18.     < xs:complexType   name = "EchoType" >   
  19.         < xs:sequence >   
  20.             < xs:element   name = "Name"   type = "xs:string" />   
  21.         </ xs:sequence >   
  22.     </ xs:complexType >   
  23.   
  24.     < xs:complexType   name = "ReturnType" >   
  25.         < xs:sequence >   
  26.             < xs:element   name = "Message"   type = "xs:string" />   
  27.         </ xs:sequence >   
  28.     </ xs:complexType >   
  29. </ xs:schema >   
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:tns="http://www.upyaya.org/echo/schemas" elementFormDefault="qualified"
    targetNamespace="http://www.upyaya.org/echo/schemas">
    <xs:element name="EchoRequest">
        <xs:complexType>
            <xs:all>
                <xs:element name="Echo" type="tns:EchoType"/>
            </xs:all>
        </xs:complexType>
    </xs:element>
    <xs:element name="EchoResponse">
        <xs:complexType>
            <xs:all>
                <xs:element name="EchoResponse" type="tns:ReturnType"/>
            </xs:all>
        </xs:complexType>
    </xs:element>
    <xs:complexType name="EchoType">
        <xs:sequence>
            <xs:element name="Name" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="ReturnType">
        <xs:sequence>
            <xs:element name="Message" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>

至此你的服务就完成。EchoRequest用于发送请求,EchoResponse用于响应。

 

  • 后台服务

定义后台服务接口。代码

Java代码
  1. package  org.upyaya.sample.echo.service;  
  2.   
  3. public   interface  EchoService {  
  4.     public  String echo(String name);  
  5. }  
package org.upyaya.sample.echo.service;

public interface EchoService {
	public String echo(String name);
}

 

 

实现如下:为了简单,略去后台的调用。

Java代码
  1. package  org.upyaya.sample.echo.service;  
  2.   
  3. import  java.text.SimpleDateFormat;  
  4. import  java.util.Calendar;  
  5.   
  6. import  org.upyaya.sample.echo.domain.dao.EchoDao;  
  7.   
  8. public   class  EchoServiceImpl  implements  EchoService {  
  9.     //private EchoDao echoDao;   
  10.   
  11.     public  String echo(String name) {  
  12.         if  (name ==  null  || name.trim().length() ==  0 ) {  
  13.             return   "echo back: -please provide a name-" ;  
  14.         }  
  15.         SimpleDateFormat dtfmt = new  SimpleDateFormat( "MM-dd-yyyy hh:mm:ss a" );  
  16.         return   "echo back: name "  + name +  " received on "   
  17.                 + dtfmt.format(Calendar.getInstance().getTime());  
  18.     }  
  19.   
  20. /*  public EchoDao getEchoDao() {  
  21.         return echoDao;  
  22.     }  
  23.  
  24.     public void setEchoDao(EchoDao echoDao) {  
  25.         this.echoDao = echoDao;  
  26.     }*/   
  27. }  
package org.upyaya.sample.echo.service;

import java.text.SimpleDateFormat;
import java.util.Calendar;

import org.upyaya.sample.echo.domain.dao.EchoDao;

public class EchoServiceImpl implements EchoService {
	//private EchoDao echoDao;

	public String echo(String name) {
		if (name == null || name.trim().length() == 0) {
			return "echo back: -please provide a name-";
		}
		SimpleDateFormat dtfmt = new SimpleDateFormat("MM-dd-yyyy hh:mm:ss a");
		return "echo back: name " + name + " received on "
				+ dtfmt.format(Calendar.getInstance().getTime());
	}

/*	public EchoDao getEchoDao() {
		return echoDao;
	}

	public void setEchoDao(EchoDao echoDao) {
		this.echoDao = echoDao;
	}*/
}

 

  • ApplicationContext组合的纽带

Spring的ApplicationContext就是Spring的魔法棒,指挥着组件间的合作。

 

1) 几个类的介绍:

  • org.springframework.ws.transport.http.MessageDispatcherServlet, 类比Spring MVC的DispacherServlet,它把其中的三个关键类 WebServiceMessageReceiverHandlerAdapter,MessageDispatcher,WsdlDefinitionHandlerAdapter, 分开来处理。该类放置在web.xml里面。这些类的功能可能的话在下篇的源码分析中介绍。
  • org.springframework.ws.soap.server.SoapMessageDispatcher, 类比于Spring MVC的DispatherServlet.这里dispather的是传入的web services 消息到endpoint. 此类是WebServiceMessageReceiver的子类,MessageDispatcherServlet会在加 载的时候去初始化它。他的功能是注册EndpointMapping,并使传入的消息mapping到特定的endpoint对象 此类通常定义在spring的application context里面。
  • Endpoint-- MessageEndpoint,MethodEndpoint,PayloadEndpoint,类比于Spring MVC的Controller.功能是把传入的消息传递到服务器。然后转换成响应(如果有响应)。此类就像Spring MVC里面一样,需要自己实现。
  • EndpointMapping, 类似于Spirng MVC的controller mapping,把消息mapping到特定的处理类(Endpoint的子类或者实现类)。常用的两个 是:PayloadRootQNameEndpointMapping,SoapActionEndpointMapping
  • org.springframework.ws.wsdl.wsdl11.DynamicWsdl11Definition,此类为动态发布wsdl的定义类。

2)Endpoint的实现,

 

endpoint是把传入消息处理后转为响应的类,通过继承AbstractMarshallingPayloadEndpoint重写invokeInternal方法来实现,invokeInternal

是这样的:protected Object invokeInternal(Object request) throws Exception,传入的是请求消息。返回的是响应消息。代码如下

Java代码
  1. package  org.upyaya.sample.echo.endpoint;  
  2.   
  3. import  org.springframework.ws.server.endpoint.AbstractMarshallingPayloadEndpoint;  
  4. import  org.upyaya.sample.echo.domain.schema.EchoRequest;  
  5. import  org.upyaya.sample.echo.domain.schema.EchoResponse;  
  6. import  org.upyaya.sample.echo.domain.schema.EchoType;  
  7. import  org.upyaya.sample.echo.domain.schema.ReturnType;  
  8. import  org.upyaya.sample.echo.service.EchoService;  
  9.   
  10. public   class  EchoMasharlingEndpoint  extends  AbstractMarshallingPayloadEndpoint {  
  11.     private  EchoService echoService;  
  12.   
  13.     public  EchoService getEchoService() {  
  14.         return  echoService;  
  15.     }  
  16.   
  17.     public   void  setEchoService(EchoService echoService) {  
  18.         this .echoService = echoService;  
  19.     }  
  20.       
  21.     protected  Object invokeInternal(Object request)  throws  Exception {  
  22.         EchoRequest echoRequest = (EchoRequest)request;  
  23.         EchoType echoType = echoRequest.getEcho();  
  24.         System.out.println("-------here----------" );  
  25.         System.out.println(echoType.getName());  
  26.         String returnMessage = echoService.echo(echoType.getName());  
  27.           
  28.         EchoResponse response = new  EchoResponse();  
  29.         ReturnType returnType = new  ReturnType();  
  30.         returnType.setMessage(returnMessage);  
  31.         response.setEchoResponse(returnType);  
  32.         return  response;  
  33.     }  
  34. }  
package org.upyaya.sample.echo.endpoint;

import org.springframework.ws.server.endpoint.AbstractMarshallingPayloadEndpoint;
import org.upyaya.sample.echo.domain.schema.EchoRequest;
import org.upyaya.sample.echo.domain.schema.EchoResponse;
import org.upyaya.sample.echo.domain.schema.EchoType;
import org.upyaya.sample.echo.domain.schema.ReturnType;
import org.upyaya.sample.echo.service.EchoService;

public class EchoMasharlingEndpoint extends AbstractMarshallingPayloadEndpoint {
	private EchoService echoService;

	public EchoService getEchoService() {
		return echoService;
	}

	public void setEchoService(EchoService echoService) {
		this.echoService = echoService;
	}
	
	protected Object invokeInternal(Object request) throws Exception {
		EchoRequest echoRequest = (EchoRequest)request;
		EchoType echoType = echoRequest.getEcho();
		System.out.println("-------here----------");
		System.out.println(echoType.getName());
		String returnMessage = echoService.echo(echoType.getName());
		
		EchoResponse response = new EchoResponse();
		ReturnType returnType = new ReturnType();
		returnType.setMessage(returnMessage);
		response.setEchoResponse(returnType);
		return response;
	}
}

 

注:本例采用的是Marshalling方式。因此需要使用JAX-B的API来对消息进行转换,JAX-B的eclipse插件可以轻松的实现XSD->JAVA.插件地址:https://jaxb-workshop.dev.java.net/

 

     3.总结和附件

Spring Web services的优缺点。

1)优点方面

  • Spring这个流行框架的支持。
  • 继承了Spring框架的一贯优点,采用依赖注入方式。
  • 集成较多的处理工具。XML API. 消息处理比较完善。
  • 安全性的支持比较好。主要支持Acegi,也支持SimpleTextPassword。不过目前的SAAJ框架存在bug,简单认证还有一定的问题。
  • 良好的API文档说明和例子学习。

2)缺点方面

  • 客户端的支持比较简单,需要加强。
  • 由于以前没咋用其他框架,缺点方面需要大家指出。

暂时做个总结吧

 

分享到:
评论

相关推荐

    spring web flow入门demo

    首先,项目会包含Spring Web Flow的相关配置,如`flow-executor.xml`和`flow-builder-services.xml`,这些配置文件用于设置Flow Executor(流程执行器)和Flow Builder Services(流程构建服务),它们是Spring Web ...

    webService入门教程_java_webservice_

    9. **持续学习和进阶**:理解了基础的Java WebServices后,可以深入研究WS-I Basic Profile、WS-Security等高级主题,以及Spring框架中的WebServices支持,如Spring-WS和Spring-Boot的Actuator模块。 10. **实践...

    CXF框架入门例子和与Spring整合的例子.zip

    首先,"CXF框架入门例子"是一个基础教程,它演示了如何创建和运行一个简单的CXF服务。这个例子可能包括以下步骤: 1. **设置环境**:确保安装了Java Development Kit(JDK),并配置了相应的环境变量。同时,需要在...

    Java Web项目加入Spring框架

    本篇文章将详细讲解如何将Spring框架整合到一个Java Web项目中,适合初学者入门。 首先,理解Spring的核心概念是至关重要的。Spring是一个开源的Java平台,它提供了一个丰富的容器来管理应用对象的生命周期和依赖...

    xfire+spring+webservice入门例子

    本入门实例将深入探讨如何使用XFire框架与Spring集成来构建和消费Web服务。XFire是Apache CXF的前身,是一个轻量级、高性能的Java Web服务实现库,而Spring则是一个广泛使用的应用框架,它提供了对Web服务的全面支持...

    spring-framework-reference4.3.1

    Spring框架适用于各种不同的使用场景,无论是在简单的Web应用还是复杂的分布式系统中都能发挥其优势。这些场景包括单体应用、微服务架构以及混合型应用等。 #### 三、Spring框架的依赖管理与命名约定 **3.1 依赖...

    CXF入门简单实例(spring整合)

    这个"CXF入门简单实例(spring整合)"的压缩包文件提供了使用Spring框架与CXF集成的基础教程。让我们深入了解一下CXF和Spring的整合以及如何通过这个实例来创建一个简单的Web服务。 首先,CXF支持多种协议,如SOAP、...

    spring-dm-reference

    **Spring Dynamic Modules** 是一个基于 Spring 框架的扩展项目,它为 OSGi 环境提供了一套全面的集成解决方案。Spring DM 主要用于简化在 OSGi 平台上开发 Spring 应用程序的过程,并提供了许多高级功能来支持动态...

    基于XFire与Spring集成的Web Service实现

    具体包含了创建服务接口和服务实现类(Echo 和 EchoImpl),并在Spring的应用上下文中配置XFire Exporter进行Web服务发布以及相应的XML配置细节介绍。最后演示了简单的Web服务客户端的测试流程。该文档旨在帮助软件...

    Spring_3.x企业应用开发实战 目录

    - **Spring Web Services**:简化 SOAP 和 RESTful Web 服务的开发。 - **Spring Security (Acegi Security)**:提供了安全性的支持。 - **Spring LDAP**:简化了与 LDAP 的交互。 - **Spring Rich Client**:...

    spring入门小例子.rar

    5. **Spring Web Services**:用于创建和消费Web服务,支持WSDL-first和契约优先的开发模式。 6. **Spring Boot**:简化了Spring应用的初始搭建和运行过程,采用“约定优于配置”的原则,让开发者可以快速启动和...

    Spring mvc(从入门到精通)

    Spring MVC 是一个基于 Java 的 Web 应用程序框架,基于模型-视图-控制器(MVC)模式。它提供了一个灵活的方式来开发 Web 应用程序,具有良好的可扩展性和灵活性。 Spring MVC 的核心组件 在 Spring MVC 中,...

    Spring Boot 简介(入门篇)

    4. spring-boot-starter-web-services:用于使用 Spring Web 服务 5. spring-boot-starter-mail:用于使用 Java Mail 和 Spring 框架的电子邮件发送支持 6. spring-boot-starter-data-redis:用于使用 Redis 键值...

    SSH三大框架经典入门教程 PDF清晰版

    Spring可以控制Struts的动作(Actions)和业务服务(Services),同时提供数据访问的抽象层,用于集成Hibernate。Struts处理HTTP请求,展示视图,而Hibernate则负责数据持久化,处理与数据库的交互。 SSH框架的入门...

    Axis2从入门到精通--Webservice在eclipse下开发教程

    3. **零配置发布**:通过POJO(Plain Old Java Object)直接发布服务,无需XML配置文件,极大地提高了开发效率。 接下来,我们将详细介绍开发流程: 1. **下载和安装Axis2**:访问Apache官方网站获取最新版本的...

    spring学习入门工程(可执行)

    Jersey是Java RESTful Web服务的实现,它提供了基于JAX-RS(Java API for RESTful Web Services)标准的实现。Spring可以与Jersey集成,用于构建RESTful API。通过Jersey,开发者可以方便地创建RESTful资源并处理...

    CXF 入门视频教程及例子程序的使用方法

    **CXF入门视频教程及例子程序的使用方法** 在IT行业中,Apache CXF是一个流行的开源框架,用于构建和开发Web服务。...继续深入研究,你将能够利用CXF构建复杂的分布式系统,实现高效的Web服务交互。

Global site tag (gtag.js) - Google Analytics