您的位置:首页 > 编程语言 > Java开发

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

2016-10-30 22:27 711 查看
         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;
}
@Override
public 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/jaxws http://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

        访问结果:

        




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

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

若有错误、不全、可优化的点,欢迎纠正与补充;转载请注明出处!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring cxf 调用服务端