2014.1.4 cxf spring webservice

先创建 webservice 服务端 。 首先下载 cxf jar 包 , cxf-2.7.8 .

新建 web 项目 aa . 将下载的cxf 压缩文件解压,将lib 下的jar 全部build path 到项目下 , 如果 启动项目时 报 找不到 org.springframework.web.context.ContextLoaderListener

请将 所有的jar 包 直接拷贝到项目的lib 下。1. 新建接口  HappyNewYear,, 注意注解必须写@webservice,  其中参数@webresult 和 @webparam 在 客户端 写接口 时 ,这个方法也必须要有同样的 参数,否则报错找不到该方法.  客户端和服务端接口的包名要一致。

package com.service;

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

import com.bean.Person;
@WebService
public interface HappyNewYear {
	public @WebResult(name = "Greet") String sayHello(@WebParam(name = "friend") String person); 
}

 2.新建实现类HappyNewYearImpl  注意注解 和 endpointInterface

package com.service;



import javax.jws.WebService;

import com.bean.Person;


@WebService(endpointInterface = "com.service.HappyNewYear")
public class HappyNewYearImpl implements HappyNewYear 
{

    public String sayHello(String person) 
    {
        return "Hello, " +person;
    }



}

3.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_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>aa</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <context-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value>WEB-INF/applicationContext.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>  
    </servlet>  
    <servlet-mapping>  
        <servlet-name>CXFServlet</servlet-name>  
        <url-pattern>/*</url-pattern>  
    </servlet-mapping> 
</web-app>

4. applicationContext.xml 文件配置,,注意 该文件的路径 和 导入 下面的三个resource 文件。调用 地址 为greetService

<?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">
    <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" />

    <jaxws:endpoint id="greetServicce" implementor="com.service.HappyNewYearImpl" address="/greetServicce" />
</beans> 


访问http://localhost:8080/aa/greetServicce?wsdl  看是否出现你想要的接口 。

二 、客户端代码 。

创建 web 项目test  , 同样导入上面的jar包。

CXF 提供了两种创建客户端的方式,一种是使用wsdl2java 命令生成客户端 ,另一种就是动态创建客户端 、

1. 动态调用 时 涉及参数问题:

//1. 普通的java 语言客户端

/*
* cxf 客户端动态调用 ,,基础类型 直接传入 ,复杂类型 使用这种方式传入
* */



public class Text { public static void main(String[] args) throws Exception{ /* //创建WebService客户端代理工厂 JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); //注册WebService接口 factory.setServiceClass(HappyNewYear.class); //设置WebService地址 factory.setAddress("http://localhost:8082/aa/greetServicce"); HappyNewYear greetingService = (HappyNewYear)factory.create(); Person person=new Person(); person.setFirstName("张三"); person.setLastName("李四"); System.out.println("message context is:"+greetingService.sayHello(person)); */ // 注意这个Person 是 服务端 类 ,而路径对应的不是 服务端项目的路径 ,而是service,,不懂为什么。 JaxWsDynamicClientFactory clientFactory=JaxWsDynamicClientFactory.newInstance(); Client client=clientFactory.createClient("http://localhost:8082/aa/greetServicce?wsdl"); Object orderlist=Thread.currentThread().getContextClassLoader().loadClass("com.service.Person").newInstance(); Method setFirstName=orderlist.getClass().getMethod("setFirstName", String.class); setFirstName.invoke(orderlist, "张三"); Method setLastName=orderlist.getClass().getMethod("setLastName", String.class); setLastName.invoke(orderlist, "李四"); Object[] result=client.invoke("sayHello",orderlist); System.out.println(result[0]); } }

 2. 第二种调用方式

           1. 创建客户端接口

  

package com.service;

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

/*
 * spring cxf
 */
@WebService
public interface HelloWorld {
    //String sayHello(String text);
    //注意把 注解也要带过来
    public @WebResult(name = "Greet") String sayHello(@WebParam(name = "friend") String person); 
}

    2. 调用

  

package com.service;

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



public class HelloWorldClient {
    public static void main(String[] args){
    //private static Logger logger=Logger.getLogger(HelloWorldClient.class);
    ApplicationContext context=new ClassPathXmlApplicationContext("application-client.xml");
    HelloWorld client=(HelloWorld)context.getBean("client",HelloWorld.class);
    System.out.println(client.sayHello("张三"));
    }
}

          3 . application-client.xml配置,同样 放在src 根目录下。

    

<?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">
    <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" />
    
    <!-- 主要bean和接口的路径一定要和 服务端一致 -->
    
    <bean id="client" class="com.service.HelloWorld" factory-bean="clientFactory" factory-method="create"></bean>
    <bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
        <property name="serviceClass" value="com.service.HelloWorld"></property>
        <property name="address" value="http://localhost:8082/aa/greetServicce"></property>
    </bean>
</beans>

初学 ,按照网上来的。能够运行出来,原理什么的还是不懂啊,有高手推荐下学习 资料吗?

rest 风格:

可能需要手动添加jsr331-api-1.1.1.jar。。

接口:

package com.rest;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path(value="/sample")
public interface RestSimple {
	@GET
	@Path("/bean/{name}")
	@Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})
	public String getuser(@PathParam("name")String name);
}

  实现类,注意注解要保持一致。

package com.rest;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;






/**
 * rest 风格webservice
 * @author Administrator
 *
 */
@Path(value="/sample")
public class HelloLove implements RestSimple{

	@Override
	@GET
	@Path("/bean/{name}")
	@Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})
	public String getuser(@PathParam("name")String name) {
		return name;
	}
	
}

  

 配置文件,和上面的类似,

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jaxws="http://cxf.apache.org/jaxws"
    xmlns:jaxrs="http://cxf.apache.org/jaxrs"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://cxf.apache.org/jaxws 
    http://cxf.apache.org/schemas/jaxws.xsd
    http://cxf.apache.org/jaxrs
    http://cxf.apache.org/schemas/jaxrs.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" />
    <bean id="person" class="com.bean.Person"></bean>
    <bean id="restSample" class="com.rest.HelloLove"></bean>  对应实现类
    <context:component-scan base-package="com.*">
        <context:exclude-filter type="annotation" 

expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    <jaxws:endpoint id="greetServicce" implementor="com.service.HappyNewYearImpl" address="/greetServicce" />
    <jaxrs:server id="restServiceContainer" address="/rest">
        <jaxrs:serviceBeans>
            <ref bean="restSample"/>
        </jaxrs:serviceBeans>
        <jaxrs:extensionMappings>
            <entry key="json" value="application/json" />
            <entry key="xml" value="application/xml" />
        </jaxrs:extensionMappings>
        <jaxrs:languageMappings>
           <entry key="en" value="en-gb"/>  
        </jaxrs:languageMappings>
    </jaxrs:server>
</beans>

访问http://localhost:8082/aa/rest?_wadl

客户端applicationContext.xml 配置文件添加

<bean id="webrest" class="org.apache.cxf.jaxrs.client.WebClient" factory-method="create">
        <constructor-arg type="java.lang.String" value="http://localhost:8082/aa/rest"></constructor-arg>
    </bean>

测试1

package com.test;

import javax.ws.rs.core.MediaType;

import org.apache.cxf.jaxrs.client.WebClient;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;





/*
 * 
 * rest 风格测试
 */
public class TestRestLove {
    public static void main(String[] args){
        ApplicationContext ctx=new ClassPathXmlApplicationContext("application-client.xml");
        WebClient client=ctx.getBean("webrest",WebClient.class);
        System.out.println("rest 风格"+client.path("sample/bean/章程").accept(MediaType.APPLICATION_XML).get(String.class));
    }
}

测试2:

配置添加

<bean id="restSampleBean" class="org.apache.cxf.jaxrs.client.JAXRSClientFactory" factory-method="create">
    <constructor-arg type="java.lang.String" value="http://localhost:8000/CXFWebService/rest/" />
    <constructor-arg type="java.lang.Class" value="com.hoo.service.RESTSample" />
</bean>
ApplicationContext ctx = new ClassPathXmlApplicationContext("application-client.xml"); 
RESTSample sample
= ctx.getBean("restSampleBean", RESTSample.class);
System.out.println(sample.getBean("张三"));

客户端整合 :Spring  struts  

导入Spring 和struts  架包 ,和 struts2-spring-plugin.jar ,主要该架包要和struts 包对应,以防冲突

HelloAction 

package com.action;

import org.springframework.beans.factory.annotation.Autowired;

import com.opensymphony.xwork2.ActionSupport;
import com.service.HelloWorld;
import com.service.Person;

public class HelloAction extends ActionSupport{
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    @Autowired
    private HelloWorld hell;//service 也需要setter/getter 方法
    private String text;
    public String execute(){
        Person p=new Person();
        p.setFirstName("张三");
        p.setLastName("李四");
        text=hell.sayHello(p);
        return SUCCESS;
    }
    
    
    public String getText() {
        return text;
    }
    public void setText(String text) {
        this.text = text;
    }


    public HelloWorld getHell() {
        return hell;
    }


    public void setHell(HelloWorld hell) {
        this.hell = hell;
    }
    
}

HelloWorldiml

package com.service;

import javax.servlet.ServletContext;

import org.apache.struts2.ServletActionContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

public class HelloWorldIml implements HelloWorld{

    @Override
    public String sayHello(Person person) {
        /*ApplicationContext context=new ClassPathXmlApplicationContext("classpath*:applicationContext.xml");
        HelloWorld client=(HelloWorld)context.getBean("client",HelloWorld.class);
        return client.sayHello(person);*/ //这种方式只能读指定的xml 文件,
                                        //对import 的xml文件不起作用,bean 引用也不起作用。
                                        //所以找不到client
        
        ServletContext servletContext =ServletActionContext.getServletContext();
        WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
        HelloWorld bean = (HelloWorld)wac.getBean("client");
        return bean.sayHello(person);
        
    }

}

application.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/beans  
        http://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" />
    
    <!-- 主要bean和接口的路径一定要和 服务端一致 -->
    
    <!-- <bean id="client" class="com.service.HelloWorld" factory-bean="clientFactory" factory-method="create"></bean>
    <bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
        <property name="serviceClass" value="com.service.HelloWorld"></property>
        <property name="address" value="http://localhost:8082/aa/greetServicce"></property>
    </bean>
    <bean id="webrest" class="org.apache.cxf.jaxrs.client.WebClient" factory-method="create">
        <constructor-arg type="java.lang.String" value="http://localhost:8082/aa/rest"></constructor-arg>
    </bean> -->
    <import resource="classpath*:application-client.xml"/><!-- classpath 指在classes下的文件,只取第一个。加*表示所有都加载  -->
    <!-- 所有src目录下的文件 编译后都在WEB-INF/classes 目录下 -->
    <bean id="helloService" class="com.service.HelloWorldIml"></bean>
    <bean id="helloAction" class="com.action.HelloAction" scope="prototype">
        <property name="hell" ref="helloService"></property>
    </bean>
</beans>

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_2_5.xsd" id="WebApp_ID" version="2.5">
 <!-- <context-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value>WEB-INF/applicationContext.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>  
    </servlet>  
    <servlet-mapping>  
        <servlet-name>CXFServlet</servlet-name>  
        <url-pattern>/*</url-pattern>  
    </servlet-mapping>  -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml,classpath*:application-client.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</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> 
    <!-- <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath*:application-client.xml,
            applicationContext.xml
        </param-value>
    </context-param> --><!-- 引入多个Spring 配置文件 --> 

</web-app>

jsp 

<?xml version="1.0" encoding="utf-8" ?>
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Insert title here</title>
</head>
<body>
    <font style="color:blue;">${text}</font>
</body>
</html>

struts-xml

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">  <!-- 必须引入2.0。不能是其他版本 -->
    <!-- struts spring 整合需要各自架包 和 struts2-spring-plugin.jar -->
<struts>
    <constant name="struts.i18n.encoding" value="UTF-8"></constant>
    <constant name="struts.devMode" value="true"></constant>
    <constant name="struts.objectFactory" value="spring" />
    <package name="gen" namespace="/" extends="struts-default">
        <global-results>
            <result name="error">error.jsp</result>
        </global-results>
        <global-exception-mappings>
            <exception-mapping result="error" exception="java.lang.Exception"></exception-mapping>
        </global-exception-mappings>
    </package>
    <package name="hello" namespace="/hello" extends="struts-default">
        <action name="helloAction" class="helloAction">
            <result>/hello.jsp</result>
        </action>
    </package>
</struts>

路径问题很常见,我也不是很明白,只能尝试。

原文地址:https://www.cnblogs.com/zhangchenglzhao/p/3505176.html