您的位置:首页 > 其它

分分钟玩转 Web Services

2016-09-09 15:00 169 查看
文章转载自:http://www.58maisui.com/2016/09/09/372/

当大型需求被数个公司分割开来,各公司系统相互交换数据的问题就会接踵而来。

   毕竟是多家不同的公司的产品,研发开发语言、采用技术框架基本上是百花齐放。

   怎样让自家系统提供的服务具有跨平台、跨语言、跨各种防火墙,让其他公司的研发用起来没障碍和爽呢?

   进过前期的技术调研和实践,最终将目光放在了轻量级 webService 服务上面。

 

   


 

1. WebService 服务技术的关键点 

XML:     做为 WebService 的基本数据表示,特点即容易组织和分析,而且又与开发平台无关。
SOAP:   做为 WebService 的传输协议,特定能运行在任何传输协议(TCP/UDP..)上面,将程序中的对象编码为 XML 的规则,执行远程调用。
WSDL:  做为描述 WebService 的语言,你能很清晰的知道提供的服务是什么、入参、返回的数据,机器和人都很容器进行阅读。
   公司自己实现 WebService 服务铁定不现实,如果你公司有一群热爱技术的大牛、有一颗想造轮子的匠心,有老总的支持,还是可以放手一战的。

   目前已有的 WebService 开发框架有:  Axis、Axis2、Xfire、CXF、JAX-WS。

   除了 JAX-WS 为 JDK 1.6 发布的的 WebService 开发框架以外,其余的都是第三方开源框架。

   其中 Axis 和 XFire 随着技术更新和发展已经慢慢的谈出了人们的视线,并且官方已经有很长时间没有更新,这里暂且不表。

   CXF是Apache旗下一个重磅的SOA简易框架,它实现了ESB(企业服务总线)。

   CXF 原型来源与 XFire + Client, 就像 Struts2 来自 WebWork 一样,当让你也能预言到 XFire 的命运会和 WebWork 一样,会淡出开发者的视线。

   Axis2 是 Apache 下的一个重量级 WebService 框架,准确说它是一个Web Services / SOAP / WSDL 的引擎,是 WebService 框架的集大成者。

   Axis2 不但能制作和发布WebService,而且可以生成Java和其他语言版WebService客户端和服务端代码。这是它的优势所在。

   丰满意味着臃肿和庞大,不可避免的导致了Axis2的复杂性,听使用过她的人,它所依赖的包数量和大小都是很惊人的,打包部署发布很麻烦。

   源于对第三方开源框架的恐惧和颤抖,结合自身公司的业务复杂度,技术团队一致选定 JDK JAX-WS 作为公司的 Webservice 框架。

   上述参考出处:

   http://zhidao.baidu.com/link?url=H_CijOzBSzpLnZ

   http://baike.baidu.com/link?url=OHYozkeWQkpZDmnKeDk9Ja

2. JAX-WS 服务端无 MVC 框架开发实践

   我这里的说的无 MVC 框架指的是没有使用任何像 Struts/Spring MVC/WebWork….这些东西,Java EE 项目最纯真的 Servlet 时代。

   在 main 函数中静态方式防部的方式这里就不提了,咱需要 webServer 服务和 web 项目一起启动起来,同呼吸共命运。

   main 静态发布方式参考的集中方式:http://www.xuebuyuan.com/1955910.html

maven 依赖

<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.2.10</version>
</dependency>


   如果是非 mavn的传统项目, 需要的 jar (大概 5M)



服务类和实现类

   项目包结构



@WebService
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface MyFirstWebService {

/**
* 执行测试的WebService方法(有参)
*/
@WebMethod
String sayHi(@WebParam(name = "name") String name);

}


@WebService(endpointInterface = "com.rambo.cwe.jws.inter.MyFirstWebService")
@SOAPBinding(style = SOAPBinding.Style.RPC)
public class MyFirstWebServiceImpl implements MyFirstWebService {

public String sayHi(String name) {
return "Hi, " + name + "! ";
}
}


 web 项目的起点,web.xml 的配置

<listener>
<listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
</listener>

<servlet>
<servlet-name>MyFirstWebService</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>MyFirstWebService</servlet-name>
<url-pattern>/services/sayHi</url-pattern>
</servlet-mapping>


 服务配置文件 sun-jaxws.xml,放置到 WEB-INF

<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0">
<endpoint name="myFirstWebService" implementation="com.rambo.cwe.jws.impl.MyFirstWebServiceImpl"
url-pattern="/services/sayHi"/>
</endpoints>


   注意服务配置文件中的 url-pattern 和 servlet 中的 url-pattern 是一致的。

   通过上面的4步的操作,启动 web 项目吧,不出什么意外的话,启动 web 容器打印日志是这样。



   浏览器访问 http://localhost:5050/cwe/services/sayHi



3. JAX-WS 服务端与 Spring 集成开发实践

   在 Spring 中集成相当简单,分分钟配置集成。

mavn 依赖需要添加的支持 jar(500K)

<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-core</artifactId>
<version>2.3.0.RELEASE</version>
</dependency>


Spring Bean 添加 WebServer 服务支持

<bean class="org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter">
<property name="baseAddress" value="http://localhost:8089/services/"/>
</bean>


   地址你随意,配置为和 web 项目一致也没问题。

服务实现类 Bean 配置

   大体的想法是你得让 Spring 知道有这样一个服务实现类。

   如果你比较传统,可以配置在 Spring-***.xml 中,像这样

<bean id="myFirstWebServiceImpl" class="com.rambo.cwe.jws.impl.MyFirstWebServiceImpl">
...
</bean>


   当然你也可以,使用注解,像这样



   简单的三步之后,把你的 web 容器启动起来吧,webServer 服务就发布成功了。

4. 客户端  JAX-WS 服务的调用

  服务端编写好之后,使用 JDk 自带的 wsimport 工具生成客户端代理类。

  wsimport 只需要指定 url 就能生成 java 调用的客户端,你完全不用去了解这个 WebServer 服务是用什么语言编写的。

  关于 wsimport 生成代理类:http://blog.csdn.net/aqsunkai/article/details/51711087

  生成客户端代理类之后,只需要两行代码就能,实现 webServer 服务的调用。

wsimport -s f:  http://localhost:5050/cwe/services/sayHi?wsdl[/code] 

  wsimport 常用参数参考

参数说明
-p定义客户端生成类的包名称
-s指定客户端执行类的源文件存放目录
-d指定客户端执行类的class文件的存放目录
-keep                                                     表示生成客户端执行类的源代码
-b指定jaxws/jaxb绑定文件或额外的schemas
-extension使用扩展来支持SOAP1.2
   生成的代理类(生成姿势多种多样,自行参考上面常用参数,没有标准只有最适合):



   将代理类放入客户端,调用代码

MyFirstWebServiceImplService service = MyFirstWebServiceImplService();
MyFirstWebService implPort = service.getMyFirstWebServiceImplPort();
System.out.println(implPort.sayHi("Orson"));


   其实我一直想尝试,不再客户端添加任何类调用 webServer 服务,很遗憾没能成功。

   最接近的的是,在客户端放入服务端的 接口类,代码可以这样写。

URL url = new URL("http://localhost:5050/cwe/services/sayHi?wsdl");
QName serviceName = new QName("http://impl.jws.cwe.rambo.com/", "MyFirstWebServiceImplService");
QName portName = new QName("http://impl.jws.cwe.rambo.com/", "MyFirstWebServiceImplPort");

Service service = Service.create(url,serviceName);
MyFirstWebService servicePort = service.getPort(portName,MyFirstWebService.class);
System.out.println(servicePort.sayHi("Orson"));


   自行定义连接地址、服务名称、、端口名称,生成服务实例进行访问,代码完全没有代理类那样清晰。

   等下次,你们公司需要给其他公司提供服务时,只需要编写好 WebServer,抽象好接口,撸好实现层。

   直接甩一个地址给其他公司,顺便可以把我这篇博客地址发过去,然后整个世界就安静了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  web services