6、CXF与spring的整合(WebService的整合)

一、环境搭建

  • 这里只是初步整合,我们直接将CXF中的lib目录中的所有jar包全部加入(除去jetty相关包、geronimo-servlet_3.0_spec-1.0.jar)。
  • 将之前工程中的包拷贝到本工程(cxf_spring)中,
    分别是org.fkjava.cxf.ws.domain、org.fkjava.cxf.ws.service、org.fkjava.cxf.ws.service.impl、org.fkjava.cxf.ws、org.fkjava.cxf.ws.impl、org.fkjava.cxf.ws.util、org.fkjava.cxf.ws.server
  • 相关的配置文件

web.xml





    
        contextConfigLocation
        /WEB-INF/applicationContext.xml
    
    
    
    
        org.springframework.web.context.ContextLoaderListener
    
    
    
    
        cxf
        
        org.apache.cxf.transport.servlet.CXFServlet
    
    
    
        cxf
        /myService/*
    

说明:这里主要配置了spring的配置文件地址,spring监听器、CXF核心控制器。

applicationContext.xml




    
    
        
    

说明:

  • 这里我们需要将CXF相关的配置文件加入进去,同时配置相关的业务类。
  • spring配置文件(applicationContext.xml)中注入CXF提供的schema、xml配置。
    • 对于schema的配置:
      beans标签中加入xmlns:jaxws=http://cxf.apache.org/jaxws然后在xsi:schemaLocation中加入http://cxf.apache.org/jaxws(命名空间)http://cxf.apache.org/schemas/jaxws.xsd(物理路径)。
    • 对于xml的配置:
      web应用的类加载路径有两类:1.WEB-INF/classes目录。2.WEB-INF/lib目录下,两者的唯一区别是前者是散的class文件,后者是打成jar包的class文件。

      其实导入的cxf-servlet.xmlcxf.extension-soap.xml一般不需要,在之后的版本中可以不需要导入了,一般只是为了兼容性才会导入。

二、进行开发

2.1 暴露WebService

spring的配置文件中使用jaxws:endpoint元素来暴露WebService,这里有两种方式:

<1>直接给定服务器提供者的类名(不太好用)



然后我们就可以将工程部署到tomcat中,在浏览器中使用
地址http://localhost:8080/cxf_spring/myService访问我们的WebService工程。

1

  • 新建一个java工程进行测试(工程Call_CXFSpring
    首先还是使用命令:wsdl2java http://localhost:8080/cxf_spring/myService/fkjava?wsdl将相关文件考出来。之后刷新工程,在工程中新建一个类MyClient.java访问WebService即可。

MyClient.java

package org.fkjava.cxf.ws.client;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.fkjava.cxf.ws.auth.AddHeaderInterceptor;
import org.fkjava.cxf.ws.Entry;
import org.fkjava.cxf.ws.HelloWorld;
import org.fkjava.cxf.ws.StringCat;
import org.fkjava.cxf.ws.impl.HelloWorldWs;

public class MyClient {

    public static void main(String[] args) {
        HelloWorldWs factory = new HelloWorldWs();
        HelloWorld hw = factory.getHelloWorldWsPort();
        System.out.println(hw.sayHi("张三"));
        
        StringCat sc = hw.getAllCats();
        for(Entry entry : sc.getEntries()){
            System.out.println(entry.getKey() + ":" + entry.getValue().getName());
        }
    }
}

注意:myService指定我们的服务名字(在web.xml中配置),而fkjava指定服务提供者的地址(在applicationContext.xml中配置)。同时这种集成不好,因为将地址写死了,没有使用spring的注入方式。
我们看HelloWorldWs.java这个服务类:

package org.fkjava.cxf.ws.impl;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.jws.WebService;
import org.fkjava.cxf.ws.HelloWorld;
import org.fkjava.cxf.ws.domain.Cat;
import org.fkjava.cxf.ws.domain.User;
import org.fkjava.cxf.ws.service.UserService;
import org.fkjava.cxf.ws.service.impl.UserServiceImpl;

@WebService(endpointInterface = "org.fkjava.cxf.ws.HelloWorld", serviceName = "HelloWorldWs")
public class HelloWorldWs implements HelloWorld {

    @Override
    public String sayHi(String name) {
        return name + "您好!" + "现在的时间是: " + new Date();
    }

    @Override
    public List getCatsByUser(User user) {
        //这里我们需要手工new,如果交给spring管理可以将对象注入进来
        UserService service = new UserServiceImpl();
        return service.getCatByUser(user);
    }
    
    //新增方法
    @Override
    public Map getAllCats() {
        UserService service = new UserServiceImpl();
        return service.getAllCats();
    }
}

可以看到其中的实际业务处理类还是使用的手工方法进行实例化,没有使用spring的注入方式。

<2>使用注入方式

spring的配置文件中改变暴露WebService的方式:


        
    
    
    

说明:#号是为了让服务器知道这个名字不是一个类 ,而只是一个id
然后改造HelloWorldWs.java服务类:

package org.fkjava.cxf.ws.impl;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.jws.WebService;
import org.fkjava.cxf.ws.HelloWorld;
import org.fkjava.cxf.ws.domain.Cat;
import org.fkjava.cxf.ws.domain.User;
import org.fkjava.cxf.ws.service.UserService;
import org.fkjava.cxf.ws.service.impl.UserServiceImpl;

@WebService(endpointInterface = "org.fkjava.cxf.ws.HelloWorld", serviceName = "HelloWorldWs")
public class HelloWorldWs implements HelloWorld {
    
    private UserService userService;
    @Override
    public String sayHi(String name) {
        return name + "您好!" + "现在的时间是: " + new Date();
    }

    @Override
    public List getCatsByUser(User user) {
        return userService.getCatByUser(user);
    }
    
    //新增方法
    @Override
    public Map getAllCats() {
        return userService.getAllCats();
    }
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
}

然后我们再次使用之前的地址进行访问,发现效果还是一样的。

2.2 添加拦截器

在上面配置的基础上进行添加,在applicationContext.xml中:


    
    
        
        
        
        
        
        
    

此时,和以前一样我们需要在客户端(工程Call_CXFSpring)那边加上拦截器,添加上用户名和密码的头,然后对服务器进行访问。以此来进行验证。客户端中我们运行类:
MyClient.java

package org.fkjava.cxf.ws.client;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.fkjava.cxf.ws.auth.AddHeaderInterceptor;
import org.fkjava.cxf.ws.Entry;
import org.fkjava.cxf.ws.HelloWorld;
import org.fkjava.cxf.ws.StringCat;
import org.fkjava.cxf.ws.impl.HelloWorldWs;

public class MyClient {

    public static void main(String[] args) {
        HelloWorldWs factory = new HelloWorldWs();
        HelloWorld hw = factory.getHelloWorldWsPort();
        
        Client client = ClientProxy.getClient(hw) ;//调用此方法,以远程WebService的代理为参数
        client.getOutInterceptors().add(new AddHeaderInterceptor("大熊", "111"));
        
        System.out.println(hw.sayHi("张三"));
        StringCat sc = hw.getAllCats();
        for(Entry entry : sc.getEntries()){
            System.out.println(entry.getKey() + ":" + entry.getValue().getName());
        }
    }
}

访问服务端。


6、CXF与spring的整合(WebService的整合)_第1张图片
2

三、另一种整合方式

传统的SSH项目中,一般在本地是有相关的数据的,但是有一种场景是我们需要调用别人的数据,但是别人的数据不可能让我们进行修改等操作,那么别人只会暴露一个WebService,而我们就需要去调用别人的WebService服务器。我们在访问别人时,只能得到WSDL文档。此时我们的项目中就不需要业务逻辑组件了,直接去调用别人的WebService的一个代理即可。

3.1 环境

首先我们拷贝上面的工程,改名为cxf_springClient,然后需要增加struts2的相关jar包:

asm-3.3.jar(会和CXF包中的重复,删掉低版本)、
asm-commons-3.3.jar、
asm-tree-3.3.jar、
commons-lang3-3.2.jar、
commons-fileupload-1.3.1.jar、
commons-io-2.2.jar、
commons-lang-2.4.jar(会和CXF中的重复,删掉低版本)、
freemarker-2.3.22.jar、
javassist-3.11.0.GA.jar、
ognl-3.0.6.jar、
struts2-core-2.3.24.jar、
xworks-core-2.3.24.jar。
strut22-spring-plugin-2.3.24.1.jar(用于和spring集成的插件)

将原有的一些包删掉,留下权限包org.fkjava.cxf.ws.auth。然后我们启动工程Auth_Server提供远程服务。在web工程中生成相应的包及程序。

3.2 配置

web.xml





    
        contextConfigLocation
        /WEB-INF/applicationContext.xml
    

    
    
        struts2
        org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
    
    
        struts2
        /*
    
    
    
    
        org.springframework.web.context.ContextLoaderListener
    

说明:这里我们不再需要CXFservlet了,因为不需要业务类了,我们直接调用远程业务即可。同时配置struts2的核心控制器。

applicationContext.xml





    
        
    
    
                    
                        
                            
                            
                        
                    
    

说明:这里我们同样不需要业务类了,但是需要配置远程业务代理类(serviceClass)。同时注意:不要将端口设置为8080,会冲突。可以看到我们使用serviceClass将接口配置进去,而这里的id不能随便写,要和action中定义的接口名一致。由于远程服务器设置了权限拦截,所以这里使用过滤器将用户名和密码设置到wsdl文档的头中。然后在这个类中我们需要使用execute方法去获取相应的数据。

struts.xml




    
    
    
        
            
                /WEB-INF/content/listCats.jsp
            
        
    

3.3 Action

ListCatsAction .java

package org.fkjava.cxf.ws.action;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.fkjava.cxf.ws.Entry;
import org.fkjava.cxf.ws.Cat;
import org.fkjava.cxf.ws.HelloWorld;
import org.fkjava.cxf.ws.StringCat;
import com.opensymphony.xwork2.ActionSupport;

public class ListCatsAction extends ActionSupport {
    
    private HelloWorld hw ;
    private Map cats;
    
    public HelloWorld getHw() {
        return hw;
    }
    public void setHw(HelloWorld hw) {
        this.hw = hw;
    }

    public Map getCats() {
        return cats;
    }
    public void setCats(Map cats) {
        this.cats = cats;
    }
    
    //此处的action调用的是远程WebService方法
    public String execute(){
        StringCat sc = hw.getAllCats();
        Map map = new HashMap();
        for(Entry entry : sc.getEntries()){
            map.put(entry.getKey(), entry.getValue());
        }
        setCats(map);
        return SUCCESS;
    }
}

说明:此时我们就可以使用地址http://localhost:8080/cxf_springClient/listCats进行访问了,当然会报找不到jsp的错误。

3.4 listCats.jsp

content/listCats.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
            pageEncoding="UTF-8" isELIgnored="false"%>
<%@taglib prefix="s" uri="/struts-tags"%>




所有的猫


    
  • ${entry.key }-->${entry.value.name }-->${entry.value.color }

说明:此时访问就可以看到

1

这样就表示成功。

你可能感兴趣的:(6、CXF与spring的整合(WebService的整合))