The Artima Developer Community
Sponsored Link

Agile Buzz Forum
Web Services from a Spring Enabled Web-App

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Marty Andrews

Posts: 190
Nickname: wry
Registered: Dec, 2003

Marty Andrews is an agile coach and developer for Thoughtworks Australia
Web Services from a Spring Enabled Web-App Posted: Dec 13, 2004 8:49 PM
Reply to this message Reply

This post originated from an RSS feed registered with Agile Buzz by Marty Andrews.
Original Post: Web Services from a Spring Enabled Web-App
Feed Title: Ramblings of the Wry Tradesman
Feed URL: http://www.wrytradesman.com/blog/index.rdf
Feed Description: Marty Andrews talks about the day to day issues he faces as an agile coach on large enterprise applications in Australia.
Latest Agile Buzz Posts
Latest Agile Buzz Posts by Marty Andrews
Latest Posts From Ramblings of the Wry Tradesman

Advertisement

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.

Read: Web Services from a Spring Enabled Web-App

Topic: White Book v2 Previous Topic   Next Topic Topic: Information Smog

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use