一、cxf框架实现soap协议的WebService(JAX-WS的标准)

版权声明:本篇文章由IT_CREATE整理 https://blog.csdn.net/IT_CREATE/article/details/86631996

什么是webservice?https://www.cnblogs.com/xdp-gacl/p/4048937.html

二、cxf框架实现REST风格http协议的WebService(JAX-RS标准):https://blog.csdn.net/IT_CREATE/article/details/86642980

下面我开始讲第一种WebService的客户端和服务器的创建,利用cxf框架和soap协议来实现。

1、首先需要导入相应的jar包:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.gezhi</groupId>
	<artifactId>webservices</artifactId>
	<packaging>war</packaging>
	<version>1.0</version>
	<name>webservices Maven Webapp</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<junit.version>4.12</junit.version>
		<log4j.version>1.2.17</log4j.version>
		<spring.version>4.3.14.RELEASE</spring.version>
		<cxf.version>3.2.0</cxf.version>
		<commons.httpclient.version>3.0.1</commons.httpclient.version>

	</properties> 

	<dependencies>

		<!-- 引入HttpClient 组件JAR包(完成:后台模拟浏览器向服务器发起HTTP请求) -->
		<dependency>
			<groupId>commons-httpclient</groupId>
			<artifactId>commons-httpclient</artifactId>
			<version>${commons.httpclient.version}</version>
		</dependency>

		<!-- 这下面2中JAR包,主要是引入SUN制定的JAX-WS标准的相关组件 -->
		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-rt-frontend-jaxws</artifactId>
			<version>${cxf.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-rt-transports-http</artifactId>
			<version>${cxf.version}</version>
		</dependency>

		<!-- 这下面2中JAR包,主要是引入SUN制定的JAX-RS标准的相关组件 -->
		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-rt-frontend-jaxrs</artifactId>
			<version>${cxf.version}</version>
		</dependency>

		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-rt-rs-service-description</artifactId>
			<version>${cxf.version}</version>
		</dependency>


		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${spring.version}</version>
		</dependency>



		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<!-- 导入junit单元测试框架JAR包 -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
			<scope>test</scope>
		</dependency>


		<!-- 导入LOG4J日志框架JAR包 -->
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>${log4j.version}</version>
		</dependency>


	</dependencies>
	<build>
		<finalName>webservices</finalName>

		<pluginManagement>
			<!-- 配置maven 在构建项目时,采用相关插件 -->
			<plugins>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-compiler-plugin</artifactId>
					<version>3.8.0</version>
					<configuration>
						<source>1.8</source>
						<target>1.8</target>
					</configuration>
				</plugin>
			</plugins>
		</pluginManagement>

	</build>
</project>

JAX-RS标准的相关组件不在这次soap的范围,soap使用的是JAX-WS的标准,也就是WSDL服务描述语言。

2、编写服务器

2.1  新建一个服务接口,这里我就新建了一个 ILoginWebService接口:(提供你想提供的服务)

package com.ge.webservices.soap;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
/**
 * @WebService() 将该接口声明为一个WEB服务接口
 * 
 * targetNamespace 给接口定义一个命名空间,写法是:该接口包名的反缀
 * 
 * serviceName 暴露服务的名称
 * 
 * portName 暴露服务所在的端口
 * 
 * @author Administrator
 *
 */
@WebService(targetNamespace="http://soap.webservices.ge.com",serviceName="LoginWebservice",portName="LoginWebservicePort")
public interface ILoginWebService {

	/**
	 * 登录方法
	 * @param loginName
	 * @param pwd
	 * @return
	 */

	String login(@WebParam(name="arg0")String loginName,@WebParam(name="arg1")String pwd);
	
	/**
	 * 欢迎方法
	 * @param userName
	 * @return
	 */
	@WebMethod(operationName="meth")
	String welcome(@WebParam(name="arg0")String userName);
	
}

服务接口需要用到@WebService注解,有三个属性:

targetNamespace :给接口定义一个命名空间,写法是:http://该接口包名的反缀  ,就是将你定义的接口存在的包反着写
serviceName :暴露服务的名称,自己定义个名字
portName :暴露服务所在的端口,自己定义个名字

以后这些信息作为 wsdl 的访问路径

@WebMethod(operationName="meth")可以给这个方法起一个别名,向外暴露的名字就是你写的这个别名,如果没用这个注解,那么向外暴露的方法名也就是本身的方法名字

@WebParam(name="arg0")同样的,这个注解是给方法参数起别名,向外暴露的参数名字就是你起的这个别名,如果没用这个注解,那么向外暴露的方法参数名就是本身的方法参数名

2.2  实现这个服务接口,这里我就新建了一个LoginWebServiceImpl类继承 ILoginWebService接口:(对提供的服务进行实现)

package com.ge.webservices.soap.impl;

import javax.jws.WebService;
import com.ge.webservices.soap.ILoginWebService;

/**
 * @WebService endpointInterface 描述该类是哪一个WEB接口的实现
 * @author Administrator
 *
 */
@WebService(endpointInterface="com.ge.webservices.soap.ILoginWebService")
public class LoginWebServiceImpl implements ILoginWebService {

	@Override
	public String login(String loginName, String pwd) {
		// TODO Auto-generated method stub
		return loginName + "登录成功!";
	}

	@Override
	public String welcome(String userName) {
		// TODO Auto-generated method stub
		return userName + "你好!";
	}

}

实现类中只有一个@WebService注解,它有一个属性:

endpointInterface 用来指定你实现的接口的名字

3、新建一个配置文件 cxf-servlet.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">


	<!-- 在spring容器中,声明WEB服务,id随便起一个名字,主要是作为被spring识别的id, 
     serviceClass表示你定义的服务接口,address表示起一个作为以后访问的路径-->
	<jaxws:server id="loginWebService" serviceClass="com.ge.webservices.soap.ILoginWebService" address="/loginService">
		
		<!-- 该接口的真实实现类 -->
		<jaxws:serviceBean>
			<bean class="com.ge.webservices.soap.impl.LoginWebServiceImpl"></bean>
		</jaxws:serviceBean>
	
	</jaxws:server>


	<!-- 如果有多个服务,就继续按照上述方式,进行发布即可 -->


</beans>

4、在web.xml文件中进行一些配置(引入cxf-servlet.xml)

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  
  <!-- 启动cxf框架的核心控制器,并启动spring容器,完成WEB服务的注册 -->
  <servlet>
  	<servlet-name>cxf</servlet-name>
  	<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
  	<init-param>
  		<param-name>config-location</param-name>
  		<param-value>classpath:cxf-servlet.xml</param-value>
  	</init-param>
  </servlet>
  <servlet-mapping>
  	<servlet-name>cxf</servlet-name>
  	<!-- 需要区分:与SpringMVC框架的路径请求 -->
  	<url-pattern>/services/*</url-pattern>
  </servlet-mapping>
  
  
</web-app>

上面相当于服务端已经创建完毕了。

5、客户端的编写

开启服务器端tomcat容器,然后就可以通过http://localhost:8080/项目名/services/ 这个地址去访问 SOAP services页面:

就可以看见你提供的服务的一些方法,以及访问地址,蓝色线就是你以后客户端要访问的地址,

点击WSDL,进入描述文件:

从这个描述文件是我这叠起来了的,我们可以看到服务中有两个方法,一个叫做login,一个叫做meth,这是我们之前定义的;同时每个方法都有一个返回。同时这个接口的名字叫做 ILoginWebService,它的命名空间为http://soap.webservices.ge.com。

现在开始找我们能够获得的信息,点开<wsdl:types>标签:

从这里我们可以看到,

login方法有两个参数,arg0和arg1,并且是string类型,而他的响应也就是返回是string类型

meth方法有一个参数arg0,是string类型,并且它有一个返回是string类型

点开<wsdl:service name>标签:

可以看到该服务提供的服务名是:LoginWebservice,提供的端口名字是LoginWebservicePort,根据这些信息我们就可以写客户端了。

根据上面知道的接口名,方法名,参数名,参数类型,命名空间,服务名,端口名,来新建接口(其实说是通过这篇文档来看,但这些信息我们自己是知道的,只是在客户端这边重新写一份接口罢了):

package com.ge.webservices.soap.client;

import javax.jws.WebService;
/**
 * 客户端,需要模拟服务器制定 WEB接口
 * @author Administrator
 *
 */
@WebService(targetNamespace="http://soap.webservices.ge.com",serviceName="LoginWebservice",portName="LoginWebservicePort")
public interface ILoginWebService {

	String login(String arg0,String arg1);
	
	String meth(String arg0);
}

客户端接口的写法和服务端基本一致,但客户端是根据阅读wsdl文档得出来的一些信息,模拟服务器指定web接口。我们在服务器端用了别名的,比如方法别名,参数别名,这里我们也用别名去写,虽然参数名对实际没影响。

然后写客户端测试:

import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.soap.SOAPBinding;


public class SOAPClient {

	private static ILoginWebService loginWebServiceImpl;
	private static final QName SERVICE_NAME = new QName("http://soap.webservices.ge.com", "LoginWebservice");
	private static final QName PORT_NAME = new QName("http://soap.webservices.ge.com", "LoginWebservicePort");
	
	public static void main(String[] args) {
		
		//以下的这两句,使用地址、服务名称、端口名称 确认客户端需要访问哪个具体的WEB服务
		Service service = Service.create(SERVICE_NAME);
		//SOAPBinding.SOAP11HTTP_BINDING 为SOAP协议版本为 HTTP 1.1封装的版本
		service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING, "http://localhost/webservices/services/loginService");
		loginWebServiceImpl = service.getPort(ILoginWebService.class);//获得客户端接口的代理实例
		
		System.out.println(loginWebServiceImpl.login("张三", "123456"));
		
		
		System.out.println(loginWebServiceImpl.meth("李四"));
	}
}

通过上面模拟的服务器指定web接口,我们才能在客户端产生代理实例。

猜你喜欢

转载自blog.csdn.net/IT_CREATE/article/details/86631996
今日推荐