webservice远程调用

一、webservice是什么、能干什么?

(1)webservice是一种使用http发送soap协议数据的远程调用技术。

(2)wsdl:webservice description language(web服务描述语言),通过xml的形式说明服务在哪里,如何调用。

(3)soap:simple object access protocol (简单对象访问协议),用http协议传输xml数据。

(4)sei:WebService EndPoint Interface(web服务终端接口),两个重要的类。

(4.1)@WebService:定义Webservice接口。

(4.2)@WebMethod:设置Webservice的方法。

(4.3)@WebParam:设置Webservice的参数。

(4.4)@WebResult:设置Webservice的返回值。

注意:

当使用SOAP12以后,wsimport和Eclipse和WSExplorer都不可以正常使用了,必须使用cxf提供的wsdl2java工具生成本地代码。

webservice性能不高。

二、用jdk提供的类发布webservice服务

1、发布服务方实现

package com.cjh.service.impl;

import javax.jws.WebMethod;
import javax.jws.WebService;
import com.cjh.service.IUserService;
/**
 * SEI定义发布服务
 * @author 陈嘉豪
 *
 */
@WebService
public class UserServiceImpl implements IUserService{
	@Override
	public String queryUserName() {
		return "chen jia hao";
	}
	@WebMethod(exclude=true)
	@Override
	public String queryUserPassword() {
		return "123456";
	}
}
package com.cjh.provider;
import javax.xml.ws.Endpoint;
import com.cjh.service.impl.UserServiceImpl;

/**
 * 发布服务
 * @author 陈嘉豪
 */
public class UserProvider {
	public static void main(String[] args) {
		Endpoint.publish("http://127.0.0.1:8080/user", new UserServiceImpl());
		System.out.println("userService publihser...");
	}
}

更多:Endpoint.publish()将会开启一个新的线程,不会影响主线程的运行。

发布的服务至少需要有一个可发布的方法,其中方法不能是静态或者final方法。

在需要发布的服务类上使用@WebService注解,这样Endpoint发布时才能正确将服务类绑定到一个地址。

2、服务调用方实现

(1)使用jdk自带的工具wsimport.exe(在JAVA_HOME/bin里面)来生成相应的java类。

命令行窗口:输入wximport -s http://127.0.0.1:8080?wsdl。这样就可以生成客户端java代码。

 

可选参数:

-d<目录> :将生成.class文件。默认参数。

-s<目录> :将生成.java文件。

-p<生成的新包名> -将生成的类,放于指定的包下,自定义包结构。

wsdlurl :http://127.0.0.1:8080?wsdl,必须的参数。

package com.cjh.client;

import com.cjh.service.impl.UserServiceImpl;
import com.cjh.service.impl.UserServiceImplService;
/**
 * 客户端远程调用
 * @author 陈嘉豪
 *
 */
public class WebServiceClient {
	public static void main(String[] args) {
		UserServiceImplService userServiceImplService = new UserServiceImplService();
		UserServiceImpl userServiceImplPort = userServiceImplService.getUserServiceImplPort();
		System.out.println(userServiceImplPort.queryUserName());;
	}
}

远程调用成功效果:

 

二、spring集成cxf实现webservice远程调用

1、jar包准备:apache-cxf-2.7.18,下载地址:http://cxf.apache.org/download.html

2、web.xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>WebServiceProvider</display-name>
  
    <context-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value>classpath:config/spring-cxf.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>  
        <load-on-startup>1</load-on-startup>  
    </servlet>  
    <servlet-mapping>  
         <servlet-name>CXFServlet</servlet-name>  
         <url-pattern>/*</url-pattern>  
    </servlet-mapping>  
    
   <!-- 字符过滤器 -->    
    <filter>    
        <filter-name>encoding</filter-name>    
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>    
        <init-param>    
            <param-name>encoding</param-name>    
            <param-value>UTF-8</param-value>    
        </init-param>    
        <init-param>    
            <param-name>forceEncoding</param-name>    
            <param-value>true</param-value>    
        </init-param>  
    </filter>    
    <filter-mapping>
    	<filter-name>encoding</filter-name>
    	<url-pattern>/</url-pattern>
    </filter-mapping>
  
  <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>
</web-app>

3、发布服务方spring-cxf.xml配置,在该配置里面配置需要暴露的服务接口和调用地址:

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/context 
	http://www.springframework.org/schema/context/spring-context.xsd
	http://cxf.apache.org/jaxws 
	http://cxf.apache.org/schemas/jaxws.xsd">

	<context:component-scan base-package="com.cjh.*" />
	
	<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" />

	<!--第一种 方式: 暴露 Web Service服务 -->
	<!-- <jaxws:server 
		id="userWebService" 
		serviceClass="com.cjh.service.IUser"
		address="/UserWebService">
		<jaxws:serviceBean>
			<ref bean="userService" />
		</jaxws:serviceBean>
	</jaxws:server> -->
	
	<!-- 第二种方式:暴露Web Service服务 -->
	<jaxws:endpoint
		id="userWebService"
		address="/UserWebService"
		implementor="com.cjh.service.UserServiceImpl">
	</jaxws:endpoint>
	

</beans>
package com.cjh.service;

import javax.jws.WebService;
/**
 * 发布方暴露的接口
 * @author 陈嘉豪
 */
@WebService
public interface IUserService {
	public String queryUserName();
}
package com.cjh.service;

import javax.jws.WebService;

/**
 * 发布方需要暴露的服务
 * @author 陈嘉豪
 */
@WebService
public class UserServiceImpl implements IUserService{
	@Override
	public String queryUserName(){
		return "chen jia hao...";
	}
	
}

4、服务调用方spring.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">

		
	  <!--web service 远程调用服务 ,这个就相当于 普通 bean了-->
	  <jaxws:client
	    id="userService"
	  	serviceClass="com.cjh.service.IUserService"
	  	address="http://localhost:8080/Spring-webservice/UserWebService"/>
	  	
</beans>

5、最后调用者做下测试:

package com.cjh.client;

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

import com.cjh.service.IUserService;

/**
 * 调用方测试
 * @author 陈嘉豪
 *
 */
public class WebserviceClient {
	
	public static void main(String[] args) {
		
		ApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("classpath:config/spring.xml");
		IUserService userService = (IUserService) classPathXmlApplicationContext.getBean("userService");
		System.out.println(userService.queryUserName());
	}
}

如果显示,那么恭喜你,远程调用成功了O(∩_∩)O~。
 

 

三、通过axis2调用webservice服务

1、引入maven依赖:

<!-- Axis2 -->
        <dependency>
            <groupId>org.apache.axis2</groupId>
            <artifactId>axis2</artifactId>
            <version>1.6.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.ws.commons.axiom</groupId>
            <artifactId>axiom</artifactId>
            <version>1.2.20</version>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>org.apache.ws.commons.axiom</groupId>
            <artifactId>axiom-api</artifactId>
            <version>1.2.20</version>
        </dependency>
        <dependency>
            <groupId>org.apache.ws.commons.axiom</groupId>
            <artifactId>axiom-impl</artifactId>
            <version>1.2.20</version>
        </dependency>
        <dependency>
            <groupId>wsdl4j</groupId>
            <artifactId>wsdl4j</artifactId>
            <version>1.6.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.ws.xmlschema</groupId>
            <artifactId>xmlschema-core</artifactId>
            <version>2.2.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.neethi</groupId>
            <artifactId>neethi</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.axis2</groupId>
            <artifactId>axis2-transport-local</artifactId>
            <version>1.7.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.axis2</groupId>
            <artifactId>axis2-transport-http</artifactId>
            <version>1.7.7</version>
        </dependency>

        <!-- Axis2 End -->

2、关键代码实现(以调用天气webservice为例学习):

package com.cjh.test.webservice;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;
import org.junit.Test;

import javax.xml.namespace.QName;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * @author chen jia hao
 */
public class AxisTest {

    /***
     * 获取天气,这是完整的webservice调用小例子
     * @throws AxisFault
     */
    @Test
    public void testRPCClient() throws AxisFault {
        try {
            // 使用RPC方式调用WebService
            RPCServiceClient serviceClient = new RPCServiceClient();
            // 创建WSDL的URL
            // String url = "http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl";
            String url = "http://ws.webxml.com.cn/WebServices/WeatherWS.asmx";
            // 指定调用WebService的URL
            EndpointReference targetEPR = new EndpointReference(url);
            Options options = serviceClient.getOptions();
            // 确定目标服务地址
            options.setTo(targetEPR);
            // 确定调用方法(wsdl 命名空间地址 (wsdl文档中的targetNamespace) 和 方法名称 的组合)
            options.setAction("http://WebXml.com.cn/getWeather");

            // 创建服务名称
            // 1.namespaceURI - 命名空间地址 (wsdl文档中的targetNamespace)
            // 2.localPart - 服务视图名 (wsdl文档中operation的方法名称,例如<wsdl:operation name="getWeather">)
            QName qname = new QName("http://WebXml.com.cn/", "getWeather");

            OMFactory omFactory = OMAbstractFactory.getOMFactory();
            OMNamespace omNamespace = omFactory.createOMNamespace("http://WebXml.com.cn/", "");
            //方法
            OMElement method = omFactory.createOMElement("getWeather", omNamespace);
            //参数
            OMElement theCityCode = omFactory.createOMElement("theCityCode", omNamespace);
            //对于参数的值
            theCityCode.setText("长沙");

            method.addChild(theCityCode);
            //method.build(); //可选

            OMElement responseOMElement = serviceClient.sendReceive(method);
            System.out.println(responseOMElement);

            String hr = "-------------------------------------------------------";
            System.out.println(hr);
            System.out.println(hr);
            OMElement firstElement = responseOMElement.getFirstElement();
            Iterator childElements = firstElement.getChildElements();
            while (childElements.hasNext()) {
                OMElement element = (OMElement) childElements.next();
                System.out.println(element.getText());
                System.out.println(hr);
            }

        } catch (AxisFault e) {
            e.printStackTrace();
        }
    }

    /***
     * 测试客户端WebServiceClient
     * @throws AxisFault
     */
    @Test
    public void test() throws AxisFault {

        String url = "http://ws.webxml.com.cn/WebServices/WeatherWS.asmx";
        String namespace = "http://WebXml.com.cn/";
        String method = "getWeather";
        Map<String, String> params = new HashMap<>();
        params.put("theCityCode","长沙");

        OMElement result = WebServiceClient.request(url, namespace, method, params);
        System.out.println(result);

        String hr = "-------------------------------------------------------";
        System.out.println(hr);
        System.out.println(hr);
        OMElement firstElement = result.getFirstElement();
        Iterator childElements = firstElement.getChildElements();
        while (childElements.hasNext()) {
            OMElement element = (OMElement) childElements.next();
            System.out.println(element.getText());
            System.out.println(hr);
        }
    }

}

/***
 * webservice 客户端调用服务
 * @author chen jia hao
 */
class WebServiceClient {
    /***
     * 远程调用
     * @author chen jia hao
     * @param url
     * @param namespace
     * @param method
     * @param params
     * @return
     * @throws AxisFault
     */
    public static OMElement request(String url, String namespace, String method, Map<String, String> params) throws AxisFault {

        assert (url!=null && namespace!=null && method!=null):"参数不能为null";

        String action = namespace + method;
        if (params == null) {
            params = new HashMap<>(0);
        }
        // 使用RPC方式调用WebService
        RPCServiceClient serviceClient = new RPCServiceClient();
        // 指定调用WebService的URL
        EndpointReference targetEPR = new EndpointReference(url);
        Options options = serviceClient.getOptions();
        // 确定目标服务地址
        options.setTo(targetEPR);
        // 确定调用方法(wsdl 命名空间地址 (wsdl文档中的targetNamespace) 和 方法名称 的组合)
        options.setAction(action);

        // 创建服务名称
        // 1.namespaceURI - 命名空间地址 (wsdl文档中的targetNamespace)
        // 2.localPart - 服务视图名 (wsdl文档中operation的方法名称,例如<wsdl:operation name="getWeather">)
        //QName qname = new QName(namespace, method);
        OMFactory omFactory = OMAbstractFactory.getOMFactory();
        OMNamespace omNamespace = omFactory.createOMNamespace(namespace, "");
        //方法
        OMElement methodElement = omFactory.createOMElement(method, omNamespace);
        for (Map.Entry<String, String> item : params.entrySet()) {
            //参数
            OMElement paramElement = omFactory.createOMElement(item.getKey(), omNamespace);
            //对于参数的值
            paramElement.setText(item.getValue());
            methodElement.addChild(paramElement);
        }
        methodElement.build(); //可选

        //远程调用
        OMElement responseOMElement = serviceClient.sendReceive(methodElement);
        return responseOMElement;
    }

}

返回结果:

 

 

更多参考:参考1参考2参考3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值