CXF-10: CXF 与 Spring 的整合 之 使用别人暴露的 Web Service 接口

来源:互联网 发布:jira软件下载 编辑:程序博客网 时间:2024/05/29 08:25

         CXF 与 spring 的整合: Java EE 应用可以使用其他项目暴露的 Web Service 接口, Java EE 应用实现多平台、多语言、多功能的编写的程序;

            

 * 在传统Spring项目基础上增加 Web Service 的步骤(SSH ):
        1 . 让 Controller 依赖远程 Web Service 的接口; 

        2 . 复制 CXF 的 jar 包(最核心的6个), jar 包地址 http://pan.baidu.com/s/1jHJ56BW   注:请选择性复制 (Apache官网上也可以下载)
asm-3.3.jar    commons-logging-1.1.1.jar    cxf-2.4.1.jar    neethi-3.0.0.jar    wsdl4j-1.6.2.jar    xmlschema-core-2.0.jar

客户端的 Web 项目,我的这次配置要用到Struts2的 jar 包(jar 包地址 http://pan.baidu.com/s/1gfDNXBH)
        3 . 在 Spring 配置文件中导入 CXF 提供 Schema、XML(cxf.jar 包里提供)
                * Schema 文件
                        <beans xmlns:jaxws="http://cxf.apache.org/jaxws" 
                                xsi:schemaLocation="
                                        http://cxf.apache.org/jaxws //命名空间
                                        http://cxf.apache.org/schemas/jaxws.xsd">//物理路径
                * XML 的配置文件
                        <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"/>
        4 . 在 Spring 配置文件中使用 jaxws:client 元素类暴露 Web Service;

        5 . 添加拦截器,在 jaxws:endpoint 元素里添加 inInterceptors、outInterceptors 子元素;

 * 代码有时比语言更有说服力,新建一个 Web Project 项目代码如下:

         

①FoodsManageController.java

import java.util.HashMap;import java.util.List;import java.util.Map;import org.apache.cxf.endpoint.Client;import org.apache.cxf.frontend.ClientProxy;import org.apache.cxf.interceptor.LoggingInInterceptor;import org.apache.cxf.interceptor.LoggingOutInterceptor;import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;import org.fjava.cxf.ws.Entry;import org.fjava.cxf.ws.Food;import org.fjava.cxf.ws.HelloWorld;import org.fjava.cxf.ws.StringFood;import org.fjava.cxf.ws.auth.AddHeaderInterceptor;import org.fjava.cxf.ws.impl.HelloWorldWs;import org.springframework.stereotype.Controller;import com.opensymphony.xwork2.ActionSupport;@Controller public class FoodsManageController extends ActionSupport{//要用到CXF的jar包,要用到Spring的jar包,可以将服务端的jar包根据情况复制过来//是一个Web项目,要用到Struts2的jar包//此时的Controller依赖的是远程Web Service的代理对象private HelloWorld factory;public void setFactory(HelloWorld factory) {this.factory = factory;}private Map<String , Food> foods;public Map<String, Food> getFoods() {return foods;}public void setFoods(Map<String, Food> foods) {this.foods = foods;}public String execute(){//Controller调用的是远程Web Service代理的方法Map<String, Food> foods = new HashMap<String, Food>();StringFood allFoods = factory.getAllFoods();for (Entry entry : allFoods.getEntries()) {foods.put(entry.getKey() , entry.getValue());}setFoods(foods);return SUCCESS;}}

②AddHeaderInterceptor.java

import java.util.List;import javax.xml.namespace.QName;import org.apache.cxf.binding.soap.SoapMessage;import org.apache.cxf.headers.Header;import org.apache.cxf.helpers.DOMUtils;import org.apache.cxf.interceptor.Fault;import org.apache.cxf.phase.AbstractPhaseInterceptor;import org.apache.cxf.phase.Phase;import org.w3c.dom.Document;import org.w3c.dom.Element;public class AddHeaderInterceptor extends AbstractPhaseInterceptor<SoapMessage> {private String userId;private String password;public AddHeaderInterceptor(String userId, String password) {super(Phase.PREPARE_SEND);//在准备发送Soap消息时启用该拦截器this.userId = userId;this.password = password;}@Overridepublic void handleMessage(SoapMessage msg) throws Fault {List<Header> headers = msg.getHeaders();//创建Document对象Document document = DOMUtils.createDocument();Element eleAuthHeader = document.createElement("authHeader");//此处创建的元素应该与服务器的拦截元素相同Element eleUserId = document.createElement("userId");eleUserId.setTextContent(userId);Element elePassword = document.createElement("password");elePassword.setTextContent(password);eleAuthHeader.appendChild(eleUserId);eleAuthHeader.appendChild(elePassword);/* * 上面代码生成了一个如下XML文档片段: * <authHeader> *<userId></userId> *<password></password> *</authHeader> *///把ele元素包装成Header,并添加到SOAP消息的Header列表中。headers.add(new Header(new QName("fjava"),eleAuthHeader));}}

③struts.xml

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE struts PUBLIC"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN""http://struts.apache.org/dtds/struts-2.3.dtd"><struts><constant name="struts.enable.DynamicMethodInvocation" value="false" /><constant name="struts.devMode" value="true" /><package name="default" namespace="/" extends="struts-default"><action name="listFoods" class = "org.fjava.cxf.controller.FoodsManageController"><result>/WEB-INF/listFoods.jsp</result></action><action name="*" class = "org.fjava.cxf.controller.FoodsManageController"><result>/WEB-INF/index.jsp</result></action></package></struts>

④applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:p="http://www.springframework.org/schema/p" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://cxf.apache.org/jaxwshttp://cxf.apache.org/schemas/jaxws.xsd        http://www.springframework.org/schema/beans         http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- Web应用的类加载路径有两类1.WEB-INF/classes目录2.WEB-INF/lib目录下 --><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"/><!-- Controller依赖的是远程Web Service的代理为了保证该Web Service代理对象可以自动装配给Controller应该保证该id属性值与Controller方法中的setter方法的方法名有对应关系 --><jaxws:client id="factory"serviceClass="org.fjava.cxf.ws.HelloWorld"address="http://192.168.0.159:6786/sayHello"><!-- 添加了两个Out拦截器 --><jaxws:outInterceptors><bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"/><!-- 嵌套Bean,创建一个Bean --><bean class="org.fjava.cxf.ws.auth.AddHeaderInterceptor"><constructor-arg value="admin"/><constructor-arg value="admin"/></bean></jaxws:outInterceptors></jaxws:client></beans>

⑤listFoods.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%><%@ taglib prefix="s" uri="/struts-tags" %><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <title>蟹老板的辉煌食物派对!</title>  </head>    <body>  <ul>    <s:iterator value="foods" var="entry">    <li>${entry.key } --> ${entry.value.describe }</li>    </s:iterator>        </ul>  </body></html>

⑥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" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">  <display-name></display-name>  <context-param>    <param-name>contextConfigLocation</param-name>    <param-value>/WEB-INF/applicationContext.xml</param-value>  </context-param>  <!-- 该Listener会保证在Web应用启动时加载Spring容器 -->  <listener>    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  </listener>   <!-- 配置struts2的核心控制器 --><filter><filter-name>struts2</filter-name><filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class></filter><filter-mapping><filter-name>struts2</filter-name><url-pattern>/*</url-pattern></filter-mapping>  <welcome-file-list>    <welcome-file>index.jsp</welcome-file>  </welcome-file-list></web-app>
服务端必须是开启状态,开启客户端,打开页面访问地址 http://192.168.0.159:8080/CXF_Spring_Client/listFoods

        访问结果:

        

做一个权限控制,有用户名和密码的时候才允许调用 Web Service 该功能完成!

希望对你有帮助,祝你有一个好心情,加油!

若有错误、不全、可优化的点,欢迎纠正与补充;转载请注明出处!

1 0
原创粉丝点击