Webservices with Spring, XFire and jsr181

Just wanted to share my experiences i made yesterday while implementing webservices via XFire. Since i migrated to Java5 yesterday, i thought its a good idea to use its strengths in form of using annotations for webservices. Because i am using Spring, XFire was an obvious choice because of its neat integration into Spring. So take a seat and see yourself how easy it is to create webservices with this combination.
 

I will NOT talk about bootstrapping a Spring context and stuff, so lets start with writing an application Context for XFire.

First lets focus on the web.xml:

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/conf/spring/applicationContext.xml,
            /WEB-INF/conf/spring/xfire-servlet.xml
  </param-value>
</context-param><servlet>
   <servlet-name>XFireServlet</servlet-name>
   <servlet-class>
       org.codehaus.xfire.spring.XFireSpringServlet
   </servlet-class>
</servlet><servlet-mapping>
   <servlet-name>XFireServlet</servlet-name>
   <url-pattern>/servlet/XFireServlet/*</url-pattern>
</servlet-mapping><servlet-mapping>
   <servlet-name>XFireServlet</servlet-name>
   <url-pattern>/services/*</url-pattern>
</servlet-mapping>The "contextConfigLocation" tells Spring where to find the applicationContext XML files. applicationContext.xml was there before and i just added an XFire one. Of course you can put the stuff below also in the applicationContext.xml but i like to seperate things. In fact, in reality i have a lot more XMLs in there, but i left them out for this example.

After that you only have to define the XFireServlet which handles the requests that comes to the URLs specified in "url-pattern". You are free to change this of course.

Lets look at the Spring applicationContext for XFire called xfire-servlet.xml

 

<beans>
 <bean id="webAnnotations"
     class="org.codehaus.xfire.annotations.jsr181.Jsr181WebAnnotations"/>
 <bean id="handlerMapping"
     class="org.codehaus.xfire.spring.remoting.Jsr181HandlerMapping">
        <property name="typeMappingRegistry">
            <ref bean="xfire.typeMappingRegistry"/>
        </property>
        <property name="xfire">
            <ref bean="xfire"/>
        </property>
        <property name="webAnnotations">
            <ref bean="webAnnotations"/>
        </property>
 </bean> <bean id="annotatedHello"
     class="de.logentis.netversys.domain.webservice.HelloImpl"/> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="urlMap">
            <map>
                <entry key="/">
                    <ref bean="handlerMapping"/>
                </entry>
            </map>
        </property>
    </bean>    <import resource="classpath:org/codehaus/xfire/spring/xfire.xml"/>
</beans>This basically defines the handler for the http requests and imports some other xfire stuff. All this is one-time plumbing. After that you only define your webservice POJOs like seen with "annotatedHello". You only define your implementation webservice POJO in here and thats it. No more magic needed.

Be aware of the fact that xfire.xml which gets imported uses its own PropertyEditor called "customEditorConfigurer". Because this is a very common name in Spring for defining your own editors and the lack of namespaces in Spring 1.x, it could be that your own bean with the same name gets overridden, so be aware of that and use a different name if you have customEditors. I ran into this...

Now lets take a look at the webservice POJO:

 

import javax.jws.WebService;@WebService(
        serviceName = "HelloService",
        endpointInterface = "Hello"
)
public class HelloImpl implements Hello{    public String world() {
        return "hello World!";
    }    public String world2() {
        return "my name is slim shady";
    }    public Person world3() {
        Person o = new Person("Foo", 21);
        o.setAddress(new Address("fooStreet", "12", "New York"));
        return o;
    }}This is really simple, we only define the @WebService annotation with some parameters like webservice name as its used on client side and tell the jsr181 processor that there is an interface to export the webservice methods.

You dont need to have an interface for it but its a better programming style, so we create also an interface. If you dont want to do it, you can put all the other annotations also in the implementation class.

 

package de.logentis.netversys.domain.webservice;import javax.jws.WebService;
import javax.jws.WebResult;@WebService
public interface Hello {    public String world();    @WebResult(name="slimName")
    public String world2();    @WebResult(name="MyObject")
    public Person world3();
}In the interface we dont need to define the @WebMethod annotation, because all methods in the interface get exported. Things like @WebResult are totally optional and let you control how the WSDL looks like. You can leave it out without any problems. There are in fact a lot more annotations to shape the WSDL to non-default values.

And what more? Nothing. Thats it. Deploy and you can test your webservice by using XFire as well or by just using <a href="http://www.soapui.org/">SOAPUI</a>.

In case you want to use XFire for testing, here the is the client code:

 

import org.codehaus.xfire.service.Service;
import org.codehaus.xfire.service.binding.ObjectServiceFactory;
import org.codehaus.xfire.client.XFireProxyFactory;
import org.codehaus.xfire.annotations.AnnotationServiceFactory;
import de.logentis.netversys.domain.webservice.Hello;
import de.logentis.netversys.domain.webservice.HelloImpl;
import de.logentis.netversys.domain.webservice.Person;import java.net.MalformedURLException;
public class TestRunner { public static void main(String[] args) {
    Service serviceModel = new AnnotationServiceFactory().create(
               HelloImpl.class);    try {
       Hello service = (Hello)new XFireProxyFactory().create(
              serviceModel,
              "http://localhost:8080/mycontext/services/HelloService");
       String s = service.world();
       System.out.println(s);
    } catch (MalformedURLException e) {
            e.printStackTrace();
    } }
}Remember, if you copy and paste, you need at least change the "mycontext" to your current application context.

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/mengxuwq/archive/2007/03/05/1520801.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值