Webservice远程调用及 apache 的CXF的使用

  1. 什么是webservice
    Web service是一个平台独立的,低耦合的,自包含的、基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的互操作的应用程序。[1]
    Web Service技术, 能使得运行在不同机器上的不同应用无须借助附加的、专门的第三方软件或硬件, 就可相互交换数据或集成。依据Web Service规范实施的应用之间, 无论它们所使用的语言、 平台或内部协议是什么, 都可以相互交换数据。Web Service是自描述、 自包含的可用网络模块, 可以执行具体的业务功能。Web Service也很容易部署, 因为它们基于一些常规的产业标准以及已有的一些技术,诸如标准通用标记语言下的子集XML、HTTP。Web Service减少了应用接口的花费。Web Service为整个企业甚至多个组织之间的业务流程的集成提供了一个通用机制。

  2. webservice的特点
    •WebService通过HTTP POST方式接受客户的请求
    •WebService与客户端之间一般使用SOAP协议传输XML数据
    •它本身就是为了跨平台或跨语言而设计的

  3. 基于jdk1.7发布一个WebService服务
    3.1服务端发布
    第一步:创建一个Java项目 第二步:创建一个类,加入Webservice注解
    第三步:提供一个方法sayHello
    第四步:在main方法中调用jdk提供的发布服务的方法
    第五步:访问服务的wsdl文档(服务的发布地址+?wsdl)http://192.168.115.87:8080/hello?wsdl

	@WebService
	public class HelloService {
		public String sayHello(String name,int i){
			System.out.println("服务端的sayHello方法被调用了。。。。");
			return "helle" + name;
		}
		public static void main(String[] args) {
			String address = "http://192.168.115.87:8080/hello";
			Object implementor = new HelloService();
			Endpoint.publish(address, implementor);
		}
	}

3.2.2客户端调用
1、使用wsimport命令解析wsdl文件生成本地代码
2、通过本地代码创建一个代理对象
3、通过代理对象实现远程调用

/**
 1. 1、使用wsimport命令解析wsdl文件生成本地代码
 	

webservice必须发布成功后,才能使用命令来生成本地代码
命令 为 wsimport -d . webservice地址?wsdl


 3. 2、通过本地代码创建一个代理对象
 4. 3、通过代理对象实现远程调用
 @author zhaoqx
  */
public class App {
	public static void main(String[] args) {
		HelloServiceService ss = new HelloServiceService();
		//创建客户端代理对象,用于远程调用
		HelloService proxy = ss.getHelloServicePort();
		String ret = proxy.sayHello("小明", 10);
		System.out.println(ret);
	}
}
  1. 注意点:
    每个webservice都有一个协议文档,如果在webservice发布成功后,直接在浏览器中访问 webservice 的地址 然后拼上 ?wsdl 就会出来响应的协议文档
    http://192.168.5.149:8182/bos-cxf-crm/service/customer?wsdl
    如果前面的链接换成webservice地址能访问成功,出现类似下面的文档说明,说明webservice发布成功了
  注:这只是一个范例:能访问表示发布成功
  <?xml version="1.0" encoding="UTF-8" ?> 
 1. <wsdl:definitions name="CustomerServiceImplService" targetNamespace="http://service.crm.bos.puya.com/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://service.crm.bos.puya.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 2. <wsdl:types>
 3. <xs:schema attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://service.crm.bos.puya.com/" xmlns="http://service.crm.bos.puya.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
 4. <xs:complexType name="customer">
 5. <xs:sequence>
  <xs:element minOccurs="0" name="address" type="xs:string" />
  <xs:element maxOccurs="unbounded" minOccurs="0" name="return" type="customer" /> 
  </xs:sequence>
  </xs:complexType>
  <xs:element name="findListNotAssociation" type="findListNotAssociation" /> 
 6. <xs:complexType name="findListNotAssociation">
  <xs:sequence /> 
  </xs:complexType>
  <xs:element name="findListNotAssociationResponse" type="findListNotAssociationResponse" /> 
 7. <xs:complexType name="findListNotAssociationResponse">
 8. <xs:sequence>
  <xs:element maxOccurs="unbounded" minOccurs="0" name="return" type="customer" /> 
  </xs:sequence>
  </xs:complexType>
  <xs:element name="findListHasAssociation" type="findListHasAssociation" /> 
 9. <xs:complexType name="findListHasAssociation">
 10. <xs:sequence>
  <xs:element minOccurs="0" name="arg0" type="xs:string" /> 
  </xs:sequence>
  </xs:complexType>
  <xs:element name="findListHasAssociationResponse" type="findListHasAssociationResponse" /> 
 11. <xs:complexType name="findListHasAssociationResponse">
 12. <xs:sequence>
  <xs:element maxOccurs="unbounded" minOccurs="0" name="return" type="customer" /> 
 13. <wsdl:message name="assigncustomerstodecidedzoneResponse">
  <wsdl:part element="tns:assigncustomerstodecidedzoneResponse" name="parameters" /> 
  </wsdl:message>
 14. <wsdl:message name="findListHasAssociation">
  <wsdl:part element="tns:findListHasAssociation" name="parameters" /> 
  </wsdl:message>
 15. <wsdl:message name="findListHasAssociationResponse">
  <wsdl:part element="tns:findListHasAssociationResponse" name="parameters" /> 
  </wsdl:message>
 16. <wsdl:message name="findAllResponse">
  <wsdl:part element="tns:findAllResponse" name="parameters" /> 
  </wsdl:message>
 17. <wsdl:portType name="ICustomerService">
 18. <wsdl:operation name="findAll">
  <wsdl:input message="tns:findAll" name="findAll" /> 
  <wsdl:output message="tns:findAllResponse" name="findAllResponse" /> 
  </wsdl:operation>
 19. <wsdl:operation name="findListNotAssociation">
  <wsdl:input message="tns:findListNotAssociation" name="findListNotAssociation" /> 
  <wsdl:output message="tns:findListNotAssociationResponse" name="findListNotAssociationResponse" /> 
  </wsdl:operation>
 20. <wsdl:operation name="findListHasAssociation">
  <wsdl:input message="tns:findListHasAssociation" name="findListHasAssociation" /> 
  <wsdl:output message="tns:findListHasAssociationResponse" name="findListHasAssociationResponse" /> 
  </wsdl:operation>
 21. <wsdl:operation name="assigncustomerstodecidedzone">
  <wsdl:input message="tns:assigncustomerstodecidedzone" name="assigncustomerstodecidedzone" /> 
  <wsdl:output message="tns:assigncustomerstodecidedzoneResponse" name="assigncustomerstodecidedzoneResponse" /> 
  </wsdl:operation>
  </wsdl:portType>
 22. <wsdl:binding name="CustomerServiceImplServiceSoapBinding" type="tns:ICustomerService">
  <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> 
 23. <wsdl:operation name="findAll">
  <soap:operation soapAction="" style="document" /> 
 24. <wsdl:input name="findAll">
  <soap:body use="literal" /> 
  </wsdl:input>
 25. <wsdl:output name="findAllResponse">
  <soap:body use="literal" /> 
  </wsdl:output>
  </wsdl:operation>
 26. <wsdl:operation name="findListNotAssociation">
  <soap:operation soapAction="" style="document" /> 
 27. <wsdl:input name="findListNotAssociation">
  <soap:body use="literal" /> 
  </wsdl:input>
 28. <wsdl:output name="findListNotAssociationResponse">
  <soap:body use="literal" /> 
  </wsdl:output>
  </wsdl:operation>
 29. <wsdl:operation name="findListHasAssociation">
  <soap:operation soapAction="" style="document" /> 
 30. <wsdl:input name="findListHasAssociation">
  <soap:body use="literal" /> 
  </wsdl:input>
 31. <wsdl:output name="findListHasAssociationResponse">
  <soap:body use="literal" /> 
  </wsdl:output>
  </wsdl:operation>
 32. <wsdl:operation name="assigncustomerstodecidedzone">
  <soap:operation soapAction="" style="document" /> 
 33. <wsdl:input name="assigncustomerstodecidedzone">
  <soap:body use="literal" /> 
  </wsdl:input>
 34. <wsdl:output name="assigncustomerstodecidedzoneResponse">
  <soap:body use="literal" /> 
  </wsdl:output>
  </wsdl:operation>
  </wsdl:binding>
 35. <wsdl:service name="CustomerServiceImplService">
 36. <wsdl:port binding="tns:CustomerServiceImplServiceSoapBinding" name="CustomerServiceImplPort">
  <soap:address location="http://192.168.5.149:8182/bos-cxf-crm/service/customer" /> 
  </wsdl:port>
  </wsdl:service>
  </wsdl:definitions>

5.在实际开发中,往往使用框架比较多,比如apache的 CXF框架, 相应的资源请上apache.org官方下载,l另外CXF是依赖spring的框架的,需要引用响应spring的jar包

  • 第一步:创建动态web项目
  • 第二步:导入CXF相关jar包
  • 第三步:在web.xml中配置CXF框架提供的一个Servlet
    <!-- 配置CXF框架提供的Servlet -->
  <servlet>
  	<servlet-name>cxf</servlet-name>
  	<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>cxf</servlet-name>
  	<url-pattern>/service/*</url-pattern>  <!-- 请求路径上包含service的路基处理服务 -->
  </servlet-mapping>
  • 第四步:在类路径下提供cxf.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"
xmlns:soap="http://cxf.apache.org/bindings/soap"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans 
					http://www.springframework.org/schema/beans/spring-beans.xsd
					http://cxf.apache.org/bindings/soap 
					http://cxf.apache.org/schemas/configuration/soap.xsd
					http://cxf.apache.org/jaxws 
					http://cxf.apache.org/schemas/jaxws.xsd
					http://www.springframework.org/schema/context
						http://www.springframework.org/schema/context/spring-context.xsd
						http://www.springframework.org/schema/aop
						http://www.springframework.org/schema/aop/spring-aop.xsd
						http://www.springframework.org/schema/tx 
						http://www.springframework.org/schema/tx/spring-tx.xsd
					">
	<!-- 引入CXF Bean定义如下,早期的版本中使用 -->
	<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="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
		<property name="url" value="jdbc:mysql:///bos_puya32"/>
		<property name="username" value="root"/>
		<property name="password" value="123456"/>
	</bean>
	
	<!-- 事务管理器 -->
	<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"/>
	</bean>
	
	<!-- 支持事务注解 -->
	<tx:annotation-driven transaction-manager="txManager"/>
	
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource"/>
	</bean>
	
	<bean id="customerService" class="com.puya.bos.crm.service.CustomerServiceImpl">
		<property name="jdbcTemplate" ref="jdbcTemplate"/>
	</bean>
	
	<!-- 注册服务 -->
	<jaxws:server id="myService" address="/customer">  //这个是地址最后的名字
		<jaxws:serviceBean>
			<ref bean="customerService"/>
		</jaxws:serviceBean>
	</jaxws:server>
</beans>
  • 第六步:写一个接口,注解webservice
@WebService
public interface ICustomerService {
	public List<Customer> findAll();
	//查询未关联到定区的客户
	public List<Customer> findListNotAssociation();
	//查询已经关联到指定定区的客户
	public List<Customer> findListHasAssociation(String decidedzoneId);
	//定区关联客户
	public void assigncustomerstodecidedzone(String decidedzoneId,Integer[] customerIds);
}
  • 第七步:创建接口的实现类
@Transactional
public class CustomerServiceImpl implements ICustomerService {
	private JdbcTemplate jdbcTemplate;
	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}
	
	//http://localhost:8182/bos-cxf-crm/service/customer?wsdl
	//访问地址  http://192.168.5.149:8182/bos-cxf-crm/service/customer?wsdl
	@Transactional(readOnly=true)
	public List<Customer> findAll() {
		String sql = "select * from t_customer";
		List<Customer> list = jdbcTemplate.query(sql, new RowMapper<Customer>(){
			public Customer mapRow(ResultSet rs, int arg1) throws SQLException {
				int id = rs.getInt("id");//根据字段名称从结果集中获取对应的值
				String name = rs.getString("name");
				String station = rs.getString("station");
				String telephone = rs.getString("telephone");
				String address = rs.getString("address");
				String decidedzone_id = rs.getString("decidedzone_id");
				return new Customer(id, name, station, telephone, address, decidedzone_id);
			}
		});
		return list;
	}
	
	//查询未关联到定区的客户
	public List<Customer> findListNotAssociation() {
		String sql = "select * from t_customer where decidedzone_id is null";
		List<Customer> list = jdbcTemplate.query(sql, new RowMapper<Customer>(){
			public Customer mapRow(ResultSet rs, int arg1) throws SQLException {
				int id = rs.getInt("id");//根据字段名称从结果集中获取对应的值
				String name = rs.getString("name");
				String station = rs.getString("station");
				String telephone = rs.getString("telephone");
				String address = rs.getString("address");
				String decidedzone_id = rs.getString("decidedzone_id");
				return new Customer(id, name, station, telephone, address, decidedzone_id);
			}
		});
		return list;
	}
	
	//查询已经关联到指定定区的客户
	public List<Customer> findListHasAssociation(String decidedzoneId) {
		String sql = "select * from t_customer where decidedzone_id = ?";
		List<Customer> list = jdbcTemplate.query(sql, new RowMapper<Customer>(){
			public Customer mapRow(ResultSet rs, int arg1) throws SQLException {
				int id = rs.getInt("id");//根据字段名称从结果集中获取对应的值
				String name = rs.getString("name");
				String station = rs.getString("station");
				String telephone = rs.getString("telephone");
				String address = rs.getString("address");
				String decidedzone_id = rs.getString("decidedzone_id");
				return new Customer(id, name, station, telephone, address, decidedzone_id);
			}
		},decidedzoneId);
		return list;
	}

	//定区关联客户
	public void assigncustomerstodecidedzone(String decidedzoneId, Integer[] customerIds) {
		String sql = "update t_customer set decidedzone_id = null where decidedzone_id = ?";
		jdbcTemplate.update(sql, decidedzoneId);
		sql = "update t_customer set decidedzone_id = ? where id = ?";
		for (Integer id : customerIds) {
			jdbcTemplate.update(sql, decidedzoneId,id);
		}
	}
}

发布服务即完成了服务端的配置,访问
http://192.168.5.149:8182/bos-cxf-crm/service/customer?wsdl如有数据即表示服务端没有问题

  • 第八步

客户端利用jdk(6.0版本以上)生成本地代码,然后拷贝进自己的项目
如果使用的是spring框架,在application中注册服务即可,记得将相应的约束页拷贝进来

xmlns:jaxws=“http://cxf.apache.org/jaxws
xmlns:soap=“http://cxf.apache.org/bindings/soap
http://cxf.apache.org/bindings/soap
http://cxf.apache.org/schemas/configuration/soap.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd

<!-- 注册crm客户端代理对象 -->
	<jaxws:client id="crmClient" 
			serviceClass="com.puya.bos.crm.ICustomerService"
			address="http://192.168.5.149:8182/bos-cxf-crm/service/customer"/>
	

使用

/*调用远程服务  start    在application中注册cxf的  服务对象先  */
	//spring 注册服务代理对象
	@Autowired
	private ICustomerService proxy;

	//获取所有没有管理分区的客户
	public String findListNotAssociation() {
		List<Customer> list = proxy.findListNotAssociation();
		
		this.java2Json(list, new String[] {});
		
		return NONE;
	}

完成:希望对读者有一点点帮助!

wsimport -s . 地址 :这个会生成java 和 class文件
wsimport -d . 地址 : 这个指挥生成class文件

猜你喜欢

转载自blog.csdn.net/puyaCheer_xu/article/details/84650005