ssh整合cxf
本文是建立已经整合了ssh的web Project之上,ssh的整合请参考其他文章,在此就不在赘述.
在本人的工程中,各个版本是apache-cxf-2.4.0-src,struts2.1.8.1,spring2.5,hibernate3.2,myeclipse6.5,jdk1.6,tomcat6.x(数据库是mysql5.x)
其中apache-cxf-2.4.0-src,struts2.1.8.1和tomcat6.x需要自己下载,而spring2.5,hibernate3.2是在myeclipse6.5中自带的。
现在,开始我们正式的步骤。
1.把cxf的jar包拷到ssh工程lib,刷新web工程。这一步本来可以多说一下,因为我完成后面的配置后,测试工程运行状况,出现了很多莫名其妙的错误。主要就是因为包的冲突,而且不是一两处,一个个的试。把一些不必要的包删除,试过多次才终于没有报错。
下面是推荐需要加的包,不至于出现太多的冲突或少包,是参考别人,不过本人并没有参考这个,是一个错误一个错误的找的,差点就放弃了......
cxf-2.3.3.jar
geronimo-annotation_1.0_spec-1.1.1.jar
geronimo-jaxws_2.2_spec-1.0.jar
geronimo-stax-api_1.0_spec-1.0.1.jar
geronimo-ws-metadata_2.0_spec-1.1.3.jar
jaxb-api-2.2.1.jar
jaxb-impl-2.2.1.1.jar
neethi-2.0.4.jar
wsdl4j-1.6.2.jar
XmlSchema-1.4.7.jar
wstx-asl-3.2.9.jar(这个包是从CXF2.2.12发布包里拿过来的)
2.把cxf配置到spring中去
这里有两种方式(或更多),第一种是新建一个beans.xml,引入下面将描述的三个xml文件,然后把beans.xml加到web.xml中contextConfigLocation下;另外一种是在spring的引入下面将三个xml文件。
下面以第一种方式演示:
在src下,新建beans.xml,内容如下
<?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/beanshttp://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" />
<!-- 这里配置服务接口,后面描述 -->
</beans>
然后,修改web.xml
在contextConfigLocation添加/WEB-INF/classes/beans.xml。
再然后,在web.xml中添加cxf过滤器,以后要通过web service访问的就需要在/webServices/路径下
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/webServices/*</url-pattern>
</servlet-mapping>
3.cxf开发
(1)开发服务端web service接口
package com.hecx.cxf;
import javax.jws.WebParam;
import javax.jws.WebService;
@WebService
public interface UserService {
String testStr(@WebParam(name="str")String str);
void add(User user)
User[] findAllUsers();
}
(2)实现服务接口
package com.hecx.cxf;
import java.util.List;
import java.util.Vector;
import javax.jws.WebService;
import com.sun.istack.logging.Logger;
@WebService(endpointInterface = "com.hecx.cxf.UserService")//这里要写接口,是必须的
public class UserServiceImpl implements UserService {
static List<User> UserRepository = new Vector<User>();
private static Logger log = Logger.getLogger(UserServiceImpl.class);
{
log.info("CXF正在初始化 UserServiceImpl.");
}
public void add(User user) {
log.info("CXF正在添加一个用户: " + user.getFirst() + "." + user.getLast());
UserRepository.add(user);
}
public User[] findAllUsers() {
System.out.println("findAllUsers...");
User[] users = new User[UserRepository.size()];
UserRepository.toArray(users);
return users;
}
public String testStr(String str) {
String str2=str;
System.out.println("testStr...str2="+str2);
// TODO Auto-generated method stub
return str2;
}
}
(3)服务端配置文件beans.xml(第一种方式,第二种方式在applicationContex.xml)里增加代码,发布服务
【注】address="/userService2"是工程路径下web service的访问路径。
<bean id="userServiceImpl" class="com.hecx.cxf.UserServiceImpl" />
<jaxws:endpoint id="userService"
implementor="#userServiceImpl"
address="/userService2" />
<!-- 这是另外一种写法,建议用第一种
<jaxws:endpoint id="userService"
implementor="com.hecx.cxf.UserServiceImpl" address="/userService" />
-->
4.查看服务发布后的wsdl.
本工程输入http://localhost:8080/webServices/userService2?wsdl,本工程是配置的tomcat ROOT.xml里的,path=""
如果之前的配置都没有问题。如看到一些xml标签的文本内容。
5.调用服务的方法
无参数方法调用:http://localhost:8080/webServices/userService2/findAllUsers
普通变量参数调用:http://localhost:8080/webServices/userService2/testStr?str=xxx
6.客户端服务配置
(1)这里需要说明一下客户端服务,实现应用中应该是在另外一个web工程中。而且也要把web service的配置增加到spring中,及配置相应的web.xml。
另外还客户端还需要有和服务器相同的接口,客户端只需要知道接口是怎样的,不需要自己去实现,而是直接调用服务器端具体的实现。
在本例中,把服务接口拷一个来:(其实在本例中是在同一个工程中,并没有这样做)
package com.hecx.cxf;
import javax.jws.WebParam;
import javax.jws.WebService;
@WebService
public interface UserService {
String testStr(@WebParam(name="str")String str);
void add(User user)
User[] findAllUsers();
}
(2)配置客户端sptring配置文件,本例中新增了一个application-client.xml,并把它增加到web.xml中,实际中应该就是另外一个工程的applicationContext.xml
<!-- 创建客户端配置文件,客户端配置文件applicationContext-client.xml
正常情况下,这个应该是在另外一个客户端web服务器上,也同样需要需要引入cxf包,然后创建同样的服务接口。
-->
<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-2.0.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schema/jaxws.xsd">
<bean id="clientUserService" class="com.hecx.cxf.UserService"
factory-bean="clientFactory" factory-method="create" />
<bean id="clientFactory"
class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="com.hecx.cxf.UserService" />
<property name="address"
value="http://localhost:8080/webServices/userService2" />
<!-- address要以http://localhost:8080/webServices/开头,要和服务器端一致http://localhost:8080/webServices/userService2 -->
</bean>
<!-- 或用这种方式代替上面
<jaxws:client id="clientUserService"
address="http://localhost:8080/clientService"
serviceClass="com.hecx.cxf.UserService" />
-->
</beans>
7.客户端调用测试
(1)下面是一种通过的客户端应用程序获得ApplicationContext的方式,ApplicationContext ctx = new ClassPathXmlApplicationContext("application-client.xml");
package com.hecx.test.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.hecx.cxf.UserService;
public class Example {
/**
* @param args
*/
/*
* 本例中客户端和服务器端都用的一个应用程序
* 这个应该是在客户端服务器上,比较说代理服务器上,需要在代理服务器上引入cxf的包,在客户端应用程序的applicationContext.xml里配置文件加增加
*
* <bean id="clientUserService" class="com.hecx.cxf.UserService"
factory-bean="clientFactory" factory-method="create" />
<bean id="clientFactory"
class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="com.hecx.cxf.UserService" />
<property name="address"
value="http://localhost:8080/webServices/userService2client" />
<!-- address要以http://localhost:8080/webServices/开头,后面的随便取 -->
</bean>
的配置,
然后客户端访问就可以通过如下方式
*
*/
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("application-client.xml");
UserService client = (UserService) ctx.getBean("clientUserService");
System.out.println("test example...client="+client);
client.findAllUsers();
}
}
(2)以下是在实现了ApplicationContextAware回调接口中action中获取ApplicationContext来调用的方式
public String init(){
log.debug("init112223dfdsfds33...");
log.debug("list.size()="+testtableDAO.findAll().size());
testDao.testJdbc();
UserService userService = (UserService)this.getApplicationContext().getBean("clientUserService");
log.debug("init...userService...findAllUsers...userService="+userService);
userService.findAllUsers();
return "SUCCESS";
}
8.cxf复杂对象的传递
暂略
9.cxf返回数据
暂略