`

Web Services from a Spring Enabled Web-App

阅读更多
I spent some time recently working on an web-application using spring and webwork. (<tangent>this combination created the core of one of the cleanest architectures I've worked with</tangent>). Someone asked how easy it might be to expose some functionality as a web service, so I thought I'd give it a go.

Grabbing a copy of Apache Axis was my first step. It's documentation guided me most of the way, but the only missing bit was how to get at a spring-created bean from an axis-aware class. Here's what I did.

After putting the required libraries (axis-ant.jar, axis.jar, commons-discovery.jar, commons-loggin.jar, jaxrpc.jar, wsdl4j.jar, saaj.jar) on the classpath, I had to declare all of the appropriate axis stuff in my web.xml file.

<web-app>
    <listener>
        <listener-class>org.apache.axis.transport.http.AxisHTTPSessionListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>axis</servlet-name>
        <servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>axis</servlet-name>
        <url-pattern>/services/*</url-pattern>
    </servlet-mapping>

    <mime-mapping>
        <extension>wsdl</extension>
        <mime-type>text/xml</mime-type>
    </mime-mapping>
</web-app>

The next step was to create a class which would be exposed as a web service by Axis:

public class TodoItemWebService {
    public String getTodoItemDescription(String title) {
        return "dummy description";
    }
}

To get the service to run, I also had to create a file named server-config.wsdd in the WEB-INF directory of my web application. I figured out what this looked like by going through the Axis tutorial which dynamically registers a service in your app. Statically creating the file works fine though too. Here's what mine looked like:

<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
    <handler name="LocalResponder" type="java:org.apache.axis.transport.local.LocalResponder"/>
    <handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper"/>
    <handler name="Authenticate" type="java:org.apache.axis.handlers.SimpleAuthenticationHandler"/>

    <service name="items" provider="java:RPC" style="wrapped" use="literal">
        <operation name="getTodoItemDescription" qname="ns1:getTodoList" returnQName="ns1:getTodoItemDescriptionResult"
            returnType="xsd:string" soapAction="" xmlns:ns1="http://wrytradesman.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
            <parameter qname="ns1:TodoItemTitle" type="xsd:string"/>
        </operation>
        <parameter name="allowedMethods" value="*"/>
        <parameter name="className" value="com.wrytradesman.todolist.web.service.TodoItemWebService"/>
        <parameter name="wsdlTargetNamespace" value="http://wrytradesman.com/"/>
    </service>

    <transport name="http">
        <requestFlow>
            <handler type="URLMapper"/>
            <handler type="java:org.apache.axis.handlers.http.HTTPAuthHandler"/>
        </requestFlow>
        <parameter name="qs:list" value="org.apache.axis.transport.http.QSListHandler"/>
        <parameter name="qs:wsdl" value="org.apache.axis.transport.http.QSWSDLHandler"/>
        <parameter name="qs.list" value="org.apache.axis.transport.http.QSListHandler"/>
        <parameter name="qs.method" value="org.apache.axis.transport.http.QSMethodHandler"/>
        <parameter name="qs:method" value="org.apache.axis.transport.http.QSMethodHandler"/>
        <parameter name="qs.wsdl" value="org.apache.axis.transport.http.QSWSDLHandler"/>
    </transport>

    <transport name="local">
        <responseFlow>
            <handler type="LocalResponder"/>
        </responseFlow>
    </transport>
</deployment>

The service definition in bold is what I had to write to get the service running. All of the surrounding info is setup stuff that is just needed to configure axis. At this stage of the game, I could deploy my web application and hit a url http://localhost//services/items?wsdl to get the WSDL definition for my service. In the space of about 5 minutes, a cow-orker had used that WSDL to create a .NET based client which called the service and got my hard-coded response.

With my web service now up and running, the only remaining problem was to create a "real" implementation that used one of my spring managed objects instead of a hard-coded response. The trick here is to get a reference to the application context first. Everything from that point is easy. The simplest path to that is get a reference to the servlet from the Axis message context, then use the servlet context to get the application context from spring. Then just call your spring bean as per normal. Here's what my final code looks like:

public class TodoItemWebService {
    public String getTodoItemDescription(String title) {
        HttpServlet servlet = (HttpServlet) MessageContext.getCurrentContext().getProperty(
                HTTPConstants.MC_HTTP_SERVLET);
        ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servlet.getServletContext());

        Map beans = context.getBeansOfType(TodoListRepository.class, false, false);
        Iterator iterator = beans.values().iterator();
        TodoListRepository repository = (TodoListRepository) iterator.next();

        TodoItem item = repository.getTodoList().getItem(title);
        return item.getDescription();
    }
}

Thats it. Pretty straight forward really. There's a few corner cases to be covered off, but vertical slice is complete. The whole exercise took less than a days effort, which included learning about how Axis hangs together.

Posted by marty at December 14, 2004 10:42 AM [0 Trackbacks]
Comments

Another option is to extend org.springframework.remoting.jaxrpc.ServletEndpointSupport.

I'm using this to insert a level of indirection, where the Axis-registered service class delegates to a bean it retrieves from the application context.

import org.springframework.context.ApplicationContext;
import org.springframework.remoting.jaxrpc.ServletEndpointSupport;


public class JaxRpcVerzeichnisService extends ServletEndpointSupport
implements RemoteMyService {

private MyService _service;

protected void onInit() {
ApplicationContext ac = getWebApplicationContext();
assert ac != null : "no ApplicationContext available";
_service = (MyService)ac.getBean("myservice");
}

public Object myServiceMethod() {
assert _service != null : "_service not initialized";
return _service.myServiceMethod();
}
}

Posted by: Michael Schuerig at December 14, 2004 08:50 PM

THANK YOU! Man I started looking at this last Friday and was dreading the fight... you've made it easy. Thanks VERY VERY much!

R

Posted by: Robert S. Sfeir at December 15, 2004 01:24 AM

you might also take a look at:

http://opensource.atlassian.com/projects/spring/browse/SPR-371

Posted by: The VoodooChile at December 15, 2004 11:53 PM

Interessting options. It would be really helpful to have an official route documented in the Spring docs but i cant find any Webservice-Section at all.

The proposed url of "The VoodooChile" is quite promising though and i think i will take this route. But great blog on this topic, i appreciated the reading.

Marc

Posted by: Marc Logemann at January 27, 2005 01:09 AM

This code doesn't work- specifically

1. what's TodoItem?
2. what's TodoListRepository?

Appreciate your response.

Thx.
lkj


ublic class TodoItemWebService {
public String getTodoItemDescription(String title) {
HttpServlet servlet = (HttpServlet) MessageContext.getCurrentContext().getProperty(
HTTPConstants.MC_HTTP_SERVLET);
ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servlet.getServletContext());

Map beans = context.getBeansOfType(TodoListRepository.class, false, false);
Iterator iterator = beans.values().iterator();
TodoListRepository repository = (TodoListRepository) iterator.next();

TodoItem item = repository.getTodoList().getItem(title);
return item.getDescription();
}
}

Posted by: lalit at January 27, 2005 09:49 AM
分享到:
评论

相关推荐

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

    标题 "Spring Web Services 框架入门研究--发布服务" 提到的是关于使用Spring框架构建Web服务的内容。Spring Web Services是Spring生态体系中的一部分,它专注于创建基于SOAP(Simple Object Access Protocol)的互...

    Spring Web Services API(Spring Web Services 开发文档).CHM

    Spring Web Services 官网 Spring Web Services API。 Spring Web Services 开发文档。

    使用-Spring-3-来创建-RESTful-Web-Services

    使用 Spring 3 创建 RESTful Web Services RESTful Web Services 是一种基于 HTTP 和 REST 原理实现的 Web Service。使用 Spring 3,可以轻松地创建 Java 实现的服务器端 RESTful Web Services。本文将介绍使用 ...

    building restful web services with spring 5 2e

    Marrying the two technologies is therefore a very natural choice.This book takes you through the design of RESTful web services and leverages the Spring Framework to implement these services....

    Web-services-using-java-from-sun.zip_web

    Java技术,尤其是Java API for Web Services (JAX-WS) 和Java API for RESTful Web Services (JAX-RS),为开发Web服务提供了强大的支持。这些技术来自Sun Microsystems,后来被Oracle公司收购,但其在Web服务领域的...

    spring-ws-security-soap-example:显示如何在Spring中设置安全的SOAP Web服务的示例

    Spring Web Services WS-Security示例 设置各种协议的样本 SOAP Web服务。 支持WS-Security的两种实现,即和 。 对于每种认证方法,每种认证方法都有一个不同的终结点: 不安全。 普通密码。 摘要密码。 签名...

    Spring web services 2 cookbook

    本书《Spring web services 2 cookbook》是一本专注于Spring Web Services技术的实用指南。Spring Web Services是基于Spring框架的一个构建Web服务的解决方案,它允许开发者设计、开发和使用基于Spring框架的SOAP ...

    spring-ws-core-2.3.0.RELEASE.jar

    Spring Web Services (Spring-WS) is a product of the Spring community focused on creating document-driven Web services.

    Spring Web Services 2 Cookbook

    《Spring Web Services 2 Cookbook》是一本专注于Spring Web Services 2框架实践的书籍,于2012年2月发布。这本书旨在帮助开发者更高效地利用Spring Web Services框架构建健壮且灵活的Web服务。Spring Web Services...

    WebServices服务接口调用---用ducument方式应用

    Web服务(Web Services)是一种基于互联网的、使用标准XML(Extensible Markup Language)进行通信的软件组件,允许不同系统间的应用程序进行交互。标题中的“WebServices服务接口调用---用document方式应用”指的是...

    java webservices.jar

    在java开发services中,会用到: 1.webservices-api.jar 2.webservices-extra.jar 3.webservices-rt.jar 4.webservices-tools.jar 5.webservices-extra-api.jar 此压缩文件里就是这五个jar文件。

    spring-web.jar

    2. Spring Web Services:Spring Web Services模块提供了创建基于SOAP的Web服务的功能,与`spring-web.jar`结合可以方便地构建服务端和消费端。 3. Spring Security:用于Web应用的安全控制,它可以与`spring-web....

    Accessing Web Services from a Visual Web Application

    "Accessing Web Services from a Visual Web Application"这一主题主要关注如何在基于Visual Web的应用程序中集成Web服务。Visual Web工具通常提供了直观的界面,使开发者能够轻松地连接到Web服务并使用它们的功能。...

    Web Services平台架构

    总的来说,Web Services平台架构在Java中的实现涉及多个层面:定义服务接口(WSDL)、传输消息(SOAP)、服务发现(UDDI)、安全(WS-Security)以及开发工具(如JAX-WS、Spring Web Services和JAX-RS)。...

    Getting started with Spring Framework: covers Spring 5(epub)

    Database interaction using Spring and Hibernate/JPA- Spring Data JPA- Spring Data MongoDB- Messaging, emailing and caching support- Spring Web MVC- Developing RESTful web services using Spring Web ...

    webservices的开发图片和文档

    - WSDL(Web Services Description Language)用于定义Web服务的接口,描述服务提供的操作、消息格式以及如何调用这些操作。 2. **RESTful API** - REST(Representational State Transfer)是一种流行的Web服务...

    webservices-api.jar包

    webservices-api.jar包

    webservices-jar包

    例如,你可以使用`webservices-api`和`webservices-extra-api`来定义服务接口和数据模型,`webservices-rt`来处理服务的运行时逻辑,而`webservices-tools`则帮助你在开发过程中进行验证和调试。 总的来说,"web...

    spring 整合flex,整合webService

    在Spring中,可以通过Spring Web Services模块创建和消费WebServices。这个模块提供了强大的支持,包括自动创建WSDL文档、处理XML消息、安全机制等。 Spring整合Flex并利用WebServices的步骤如下: 1. **配置...

Global site tag (gtag.js) - Google Analytics