`
free_xiang
  • 浏览: 50893 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

cxf2.1服务端的构建过程

    博客分类:
  • java
阅读更多

Setting up your build

Open up your favorite IDE and create a new project. The first thing we need to do is add the necessary CXF dependencies to the project. You can find these dependencies in the CXF distribution in the lib directory.

commons-logging-1.1.jar
geronimo-activation_1.1_spec-1.0-M1.jar (or Sun's Activation jar)
geronimo-annotation_1.0_spec-1.1.jar (JSR 250)
geronimo-javamail_1.4_spec-1.0-M1.jar (or Sun's JavaMail jar)
geronimo-servlet_2.5_spec-1.1-M1.jar (or Sun's Servlet jar)
geronimo-ws-metadata_2.0_spec-1.1.1.jar (JSR 181)
jaxb-api-2.0.jar
jaxb-impl-2.0.5.jar
jaxws-api-2.0.jar
neethi-2.0.jar
saaj-api-1.3.jar
saaj-impl-1.3.jar
stax-api-1.0.1.jar
wsdl4j-1.6.1.jar
wstx-asl-3.2.1.jar
XmlSchema-1.2.jar
xml-resolver-1.2.jar

The Spring jars:

aopalliance-1.0.jar
spring-core-2.0.8.jar
spring-beans-2.0.8.jar
spring-context-2.0.8.jar
spring-web-2.0.8.jar

And the CXF jar:

cxf-2.1.jar

Writing your Service

First we'll write our service interface. It will have one operation called "sayHello" which says "Hello" to whoever submits their name.

package demo.spring;

import javax.jws.WebService;

@WebService
public interface HelloWorld {
    String sayHi(String text);
}

Our implementation will then look like this:

package demo.spring;

import javax.jws.WebService;

@WebService(endpointInterface = "demo.spring.HelloWorld")
public class HelloWorldImpl implements HelloWorld {

    public String sayHi(String text) {
        System.out.println("sayHi called");
        return "Hello " + text;
    }
}

The@WebServiceannotation on the implementation class lets CXF know which interface to use when creating WSDL. In this case its simply our HelloWorld interface.

Declaring your server beans

CXF contains support for "nice XML" within Spring 2.0. For the JAX-WS side of things, we have a <jaxws:endpoint> bean which sets up a server side endpoint.

Lets create a "beans.xml" file in our WEB-INF directory which declares an endpoint bean:

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:jaxws="http://cxf.apache.org/jaxws"
	xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">

	<import resource="classpath:META-INF/cxf/cxf.xml" />
	<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
	<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

	<jaxws:endpoint 
	  id="helloWorld" 
	  implementor="demo.spring.HelloWorldImpl" 
	  address="/HelloWorld" />
	  
</beans>

If you want to reference a spring managed-bean, you can write like this:

<bean id="hello" class="demo.spring.HelloWorldImpl" />

<jaxws:endpoint id="helloWorld" implementor="#hello" address="/HelloWorld" />

The bean uses the following properties:

  • idspecifies the id of the bean in the Spring context.
  • implementorspecifies the implementation class.
  • addressspecifies the location the service will be hosted. This should just be a related path. This is because CXF can't know the war name and the servlet container's listening port, CXF will update the endpoint address with the request url at the runtime.

To provide a bean name instead of a classname as an implementor, simply supply the bean-name prepended with "#", e.g. implementor="#myBean".

You can also do more sophisticated things with the<jaxws:endpoint>element like add nested tags to attach JAX-WS Handlers or CXF Interceptors to the service. For more on this seeJAX-WS Configuration.

Setting up the Servlet

We'll need to add two things to our web.xml file:

  1. the SpringContextLoaderLister. This starts Spring and loads our beans.xml file. We can specify where our file is via acontext-paramelement.
  2. the CXF Servlet
    <web-app>
    	<context-param>
    		<param-name>contextConfigLocation</param-name>
    		<param-value>WEB-INF/beans.xml</param-value>
    	</context-param>
    
    	<listener>
    		<listener-class>
    			org.springframework.web.context.ContextLoaderListener
    		</listener-class>
    	</listener>
    
    	<servlet>
    		<servlet-name>CXFServlet</servlet-name>
    		<display-name>CXF Servlet</display-name>
    		<servlet-class>
    			org.apache.cxf.transport.servlet.CXFServlet
    		</servlet-class>
    		<load-on-startup>1</load-on-startup>
    	</servlet>
    
    	<servlet-mapping>
    		<servlet-name>CXFServlet</servlet-name>
    		<url-pattern>/*</url-pattern>
    	</servlet-mapping>
    </web-app>
    

It is important to note that the address that you chose for your endpoint bean must be one your servlet listens on. For instance, if my Servlet was register for "/some-services/*" but my address was "/more-services/HelloWorld", there is no way CXF could receive a request.

Create a Client (Easy Way)

Just like the<jaxws:endpoint>used on the server side, there is a<jaxws:client>that can be used on the client side. You'll give it a bean name, the service interface, and the service URL, and it will create a bean with the specified name, implementing the service interface, and invoking the remote SOAP service under the covers:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">

    <jaxws:client id="helloClient"
                  serviceClass="demo.spring.HelloWorld"
                  address="http://localhost:9002/HelloWorld" />
</beans>

You can now inject that "helloClient" bean into any other Spring bean, or look it up from the Spring application context manually with code like this:

ApplicationContext context = ...; // your Spring ApplicationContext
HellWorld client = (HelloWorld) context.getBean("helloClient");

You can also do more sophisticated things with the<jaxws:client>element like add nested tags to attach JAX-WS Handlers or CXF Interceptors to the client. For more on this seeJAX-WS Configuration.

Create a Client (More Manual Way)

CXF includes a JaxWsProxyFactory bean which create a client for you from your service interface. You simply need to tell it what your service class is (the HelloWorld interface in this case) and the URL of your service. You can then create a client bean via the JaxWsProxyFactory bean by calling it's create() method.

Here's an example:

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:jaxws="http://cxf.apache.org/jaxws"
	xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schema/jaxws.xsd">

    <bean id="client" class="demo.spring.HelloWorld" 
      factory-bean="clientFactory" factory-method="create"/>
    
	<bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
	  <property name="serviceClass" value="demo.spring.HelloWorld"/>
	  <property name="address" value="http://localhost:9002/HelloWorld"/>
	</bean>
	  
</beans>

If you were going to access your client you could now simply pull it out of the Spring context (or better yet, inject it into your application using Spring!):

ApplicationContext context = ...; // your Spring ApplicationContext
HellWorld client = (HelloWorld) context.getBean("client");

client code athttp://svn.apache.org/repos/asf/cxf/trunk/distribution/src/main/release/samples/java_first_spring_support/src/demo/spring/client/Client.java

Some usage scenarios will require more extensive configuration (and this is not the case with the<jaxws:client>syntax described above). For more information, seeJAX-WS Configuration.
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics