CXF 學習(1,使用內置的jetty服務器發佈服務。2,CXF與spring集成)

cxf爲何會用到jetty系列的jar包,jetty是cxf的內置服務器,下面這種方式就是使用的jettyjavascript

通過測試使用的最基本的jar包爲:html

cxf-2.6.0.jar
jetty-continuation-8.1.15.v20140411.jar
jetty-http-8.1.15.v20140411.jar
jetty-io-8.1.15.v20140411.jar
jetty-server-8.1.15.v20140411.jar
jetty-util-8.1.15.v20140411.jar
neethi-3.0.2.jar
wsdl4j-1.6.2.jar
xmlschema-core-2.0.2.jar
package ws.client;

import java.util.ArrayList;
import java.util.List;

import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;

import ws.service.HelloWorld;
import ws.service.model.User;

public class HelloWorldClient {
	public static void main(String[] args){
		JaxWsProxyFactoryBean svr=new JaxWsProxyFactoryBean();
		String addr="http://localhost:8080/webservice/helloWorld";
		svr.setAddress(addr);
		svr.setServiceClass(HelloWorld.class);
		HelloWorld service=(HelloWorld) svr.create();
		String text=service.sayHi("hello you are very good!");
		System.out.println(text);
		User user=new User();
		user.setName("user1");
		text=service.sayHiToUser(user);
		System.out.println(text);
		User user2=new User();
		user2.setName("user2");
		List<User> users=new ArrayList<>();
		users.add(user);
		users.add(user2);
		String texts[]=service.sayHiToUsers(users);
		System.out.println(texts[0]+texts[1]);
	}
}
package ws.service.app;

import javax.xml.ws.Endpoint;


import ws.service.impl.HelloWorldImpl;

public class HelloWorldApp {
	public static void main(String[] args){
		System.out.println("hello world service start");
		HelloWorldImpl implementor=new HelloWorldImpl();
		String addr="http://localhost:8080/webservice/helloWorld";
		Endpoint.publish(addr, implementor);
		System.out.println("hello world service started");
	}
}
package ws.service;

import java.util.List;

import javax.jws.WebParam;
import javax.jws.WebService;

import ws.service.model.User;

@WebService
public interface HelloWorld {
	public String sayHi(@WebParam(name="text")String text);
	public String sayHiToUser(User user);
	public String[] sayHiToUsers(List<User> users);
}
package ws.service.impl;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.jws.WebParam;
import javax.jws.WebService;

import ws.service.HelloWorld;
import ws.service.model.User;

@WebService(endpointInterface="ws.service.HelloWorld",serviceName="helloWorld")
public class HelloWorldImpl implements HelloWorld{

	private Map<Integer, User> userMap=new LinkedHashMap<Integer, User>();
	
	@Override
	public String sayHi(@WebParam(name = "text") String text) {
		return text;
	}

	@Override
	public String sayHiToUser(User user) {
		return user.getName();
	}

	@Override
	public String[] sayHiToUsers(List<User> users) {
		String[] names=new String[users.size()];
		int index=0;
		for(User user:users){
			userMap.put(index, user);
			names[index]=user.getName();
			index++;
		}
		return names;
	}

}
package ws.service.model;

public class User {
	private String name;

	/**
	 * @return name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name 要設置的 name
	 */
	public void setName(String name) {
		this.name = name;
	}
	
}

注意:服務接口不能有重載方法,由於CXF不支持有重載方法的接口。否則會報如下異常:java

Exception in thread "main" javax.xml.ws.WebServiceException: java.lang.IllegalArgumentException: An operation with name [{http://app.service.ws/}sayHiToUser] already exists in this service
	at org.apache.cxf.jaxws.EndpointImpl.doPublish(EndpointImpl.java:357)
	at org.apache.cxf.jaxws.EndpointImpl.publish(EndpointImpl.java:246)
	at org.apache.cxf.jaxws.spi.ProviderImpl.createAndPublishEndpoint(ProviderImpl.java:151)
	at javax.xml.ws.Endpoint.publish(Endpoint.java:240)
	at ws.service.app.test.HelloWorldService.main(HelloWorldService.java:12)

2:spring集成CXF。web

引入jar包的時候,spring的jar包版本在4.2.x以上的話,CXF的jar包版本要在3.0.x以上才行否則會報錯:spring

java.lang.NoSuchMethodError: org.springframework.aop.support.AopUtils.isCglibProxyClass(Ljava/lang/Class;)Zexpress

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'helloWorld': Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: org.springframework.aop.support.AopUtils.isCglibProxyClass(Ljava/lang/Class;)Z
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    .....
    .....
Caused by: java.lang.NoSuchMethodError: org.springframework.aop.support.AopUtils.isCglibProxyClass(Ljava/lang/Class;)Z
	at org.apache.cxf.common.util.SpringAopClassHelper.getRealClassInternal(SpringAopClassHelper.java:85)
	at org.apache.cxf.common.util.ClassHelper.getRealClass(ClassHelper.java:55)

必須引入的jar包有:apache

aopalliance-1.0.jar
commons-logging-1.2.jar
cxf-2.6.0.jar
jaxb-api-2.2.jar
jaxb-impl-2.2.5.jar
jetty-continuation-8.1.15.v20140411.jar
jetty-http-8.1.15.v20140411.jar
jetty-io-8.1.15.v20140411.jar
jetty-server-8.1.15.v20140411.jar
jetty-util-8.1.15.v20140411.jar
neethi-3.0.2.jar
spring-aop-3.1.0.RELEASE.jar
spring-asm-3.1.0.RELEASE.jar
spring-beans-3.1.0.RELEASE.jar
spring-context-3.1.0.RELEASE.jar
spring-context-support-3.1.0.RELEASE.jar
spring-core-3.1.0.RELEASE.jar
spring-expression-3.1.0.RELEASE.jar
spring-web-3.1.0.RELEASE.jar
wsdl4j-1.6.2.jar
xmlschema-core-2.0.2.jar

配置文件:api

1 - web.xml:服務器

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>SpringTest2</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
  
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/conf/appContext.xml</param-value>
  </context-param>
  
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  
  <servlet>
    <servlet-name>CXFServlet</servlet-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>/webservice/*</url-pattern>
  </servlet-mapping>
</web-app>

配置文件裏面的<context-param>元素的<param-value>的值有兩種形式,上面是一種。另外一種就是:app

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:appContext.xml</param-value>
</context-param>

這種classpath形式要求context配置文件在類路徑下,即src資源包下。不寫classpath就放在WEB-INF文件夾下。

2 - context配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <jaxws:endpoint id="helloWorldService" implementor="ws.service.app.impl.HelloWorldImpl" address="http://localhost:8081/springtest2/webservice/hello"/>
    
    <bean id="client" class="ws.service.app.HelloWorld" factory-bean="clientFactory" factory-method="create"/>        
    
    <bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
        <property name="address" value="http://localhost:8081/springtest2/webservice/hello"></property>
        <property name="serviceClass" value="ws.service.app.HelloWorld"></property>
    </bean>   
</beans>

這個配置文件沒什麼好說的。

測試類:

package ws.service.app.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

import ws.service.app.HelloWorld;

public class HelloWorldTest {
	public static void main(String[] args) {
		ApplicationContext context=new FileSystemXmlApplicationContext("WebContent/WEB-INF/conf/appContext.xml");
		HelloWorld client=(HelloWorld) context.getBean("client");
		String textString=client.sayHi("test success!");
		System.out.println(textString);
	}
}

注意:

FileSystemXMLApplicationContext:是加載WEN-INF文件夾下的資源文件。如上。

ClasspathXMLApplicationContext:是加載src資源包下的資源文件。以下:

這時能夠寫成:

package ws.service.app.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

import ws.service.app.HelloWorld;

public class HelloWorldTest {
	public static void main(String[] args) {
		//ApplicationContext context=new FileSystemXmlApplicationContext("WebContent/WEB-INF/conf/appContext.xml");
		ApplicationContext context=new ClassPathXmlApplicationContext("appContext.xml");
		HelloWorld client=(HelloWorld) context.getBean("client");
		String textString=client.sayHi("test success!");
		System.out.println(textString);
	}
}

這時訪問地址:

http://localhost:8081/springtest2/webservice/hello?wsdl

就能夠看到wsdl文件,控制檯也有輸出信息。

相關文章
相關標籤/搜索