webservice
来源:互联网 发布:structure软件 使用 编辑:程序博客网 时间:2024/04/30 14:51
WebService 概述
网络服务,是RPC 的一种实现方式
客户端要调用 必须遵循 TCP协议, 而 WebService 使用更高以及的 HTTP协议; — 用来获取数据,数据本身必须是
WS是一种基于 Http协议和XML技术,并使用 WSDL描述和使用SOAP协议传输的异构系统解决方案
拓展: webService三要素:SOAP、WSDL(WebServicesDescriptionLanguage)、UDDI(UniversalDescriptionDiscovery andIntegration) SOAP --- 用来描述传递信息的格式, WSDL --- 用来描述如何访问具体的接口, UDDI --- 用来管理,分发,查询webService RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。 SOAP(简单对象访问协议):是交换数据的一种协议规范,是一种轻量的、简单的、基于XML(标准通用标记语言下的一个子集)的协议,它被设计成在WEB上交换结构化的和固化的信息。应用场景: 1. 由权威机构提供的第三方小功能; 2. 多客户端的整合 针对不同的平台提供不同的客户端,而这些客户端获取数据,使用 RPC,WS就是一种实现方式; 3. 异构系统的整合(跨语言、跨系统) 企业信息化战略规划中常见问题: 信息孤岛(各个系统之间信息不互通) 解决方案: 直接让一个系统提供数据,其他系统远程访问 、 企业服务总线(ESB)--- 发布到总线,其他系统远程访问总线 ESB知识扩展 SOA -- 面向服务的架构 WSDL :描述服务 UDDI : 目录服务,查找服务 SOAP : 简单对象访问协议,调用服务的协议 WS和SOA的区别: Web Service是技术规范,而SOA是设计原则,一种架构模式。 WSDL,UDDI和SOAP是SOA基础的基础部件。 WSDL:用来描述服务; UDDI:用来注册和查找服务; SOAP:作为传输层,用来在客户端和服务器端之间传送消息。
基于 JDK 的 WS
服务端 构建服务 标准在类上 @WebService //标记为WS服务类 @SOAPBinding(style=Style.RPC) //声明访问规范 ,默认 document 标注在方法上 @WebMethod //标记为需要暴露的WS服务方法 发布服务 使用JDK中的Endpoint类发布服务, public static Endpoint publish(String address,Object implementor) 参数: address -一个URI,指定要使用的地址和传输/协议。 implementor -服务实现类。 返回: 新创建的服务端端点。 发布后的xml 中: WSDL service ----- 确定服务发布的名称和 服务地址 binding ---- transport --- 指定传输协议 style --- 定义整个 wsdl文档的编写规范 operation --- 描述了服务方法 portType --- 对服务的方法进行详细描述 message --- 定义方法传入的参数,返回值 types --- 只对document有效,RPC不会存在 定义类型 WSDL : 用来描述WS和说明如何与WS通信的XML语言,即基于XML的语言的,用于描述Webservice及其方法、参数和返回值的一种语言,服务交互所需的所有细节都位于其WSDL文件中。 客户端 (远程调用服务 ) -- 创建单独项目 使用 在%JAVA_HOME%\bin下的 wsimport.exe工具 生成客户端代码 生成过程中 ,服务端应该处于开启状态 %JAVA_HOME%\bin 配置在 环境变量path中 步骤: 1) 使用wsimport生成客户端代码 wsimport -s . http://192.168.1.3:9999/weather?wsdl 注意:服务端不能关闭 wsimport所在%JAVA_HOME%\bin,这个路径要放到path中,方便调用。 在客户端代码src下面执行命令 2) 使用生成的类编写代码完成对服务端的调用 //getWeatherServicePort 这个方法会生成一个WeatherService的代理对象,完成对服务端的调用。 WeatherService weatherService = new WeatherServiceService().getWeatherServicePort(); System.out.println(weatherService.getClass().getName()); //通过代理完成远程调用 String weather = weatherService.getWeather(""); System.out.println(weather); SOAP,调用远程方法和响应都是以SOAP的消息实现的。 Envelope 信封 header 头部,有的ws是需要收费的。一般当你给钱后,就给你发用户名和密码。ws服务端就要完成登录校验需要客户端传递用户名和密码。 就可以把用户名和密码放到头部。 body 主体,完成调用方法和传入参数说明,已经响应值的描述。 WebService常见标签详解 代码详解 @WebService标签 endpointInterface:定义服务抽象WebService 协定的服务端点接口的完整名称。不允许在端点上使用此成员值,该元素的值必须有 WebService标签。默认情况下,服务器自动生成服务端接口。 name:服务接口名称(对应wsdl: portType的name属性,用在服务接口上); serviceName:服务类名称。默认为,实现类名+Service(对应service的name和definition上的name属性对应,用在实现类上)。 portName:Web Service的端口名称。此名称被用作wsdl:port的名称。 targetNamespace:目标命名空间,描述服务的预定义WSDL的位置(同时用在实现类和服务接口上,需统一)。 wsdlLocation:WSDL地址(服务端除了WSDL优先的情况外可不写,客户端代理接口上必须配置此属性,指向web端WSDL文件地址) 只要在 类上添加了此标签,该类中的所有方法默认都会暴露出去 ; 要暴露指定的方法,需要手动配置 不暴露的方法上添加 @WebMethod(exclude=true) -- 置于接口中的方法上才会生效,实现类不行 只要配置 endpointInterface , 想要修改属性,必须在 接口中修改才可以 @WebMethod标签 operationName:指定暴露服务方法的别名。 exclude:是否暴露此标记的方法。 @WebResult标签 name:定义返回值的名称。 header:布尔类型,是否把值放到header元素中进行传递。 @WebResult(name="result")String SayYes(@WebParam(name="name") String name); @SOAPBinding SOAPBinding.ParameterStyleparameterStyle 确定方法参数是否表示整个消息正文,或者参数是否是包装在以操作命名的顶层元素中的元素。 SOAPBinding.ParameterStyle.WRAPPED,默认,使用对参数进行包装 SOAPBinding.ParameterStyle.BARE,不对参数进行包装 SOAPBinding.Style style 定义发 送到Web Service 的消息 和从Web Service发送的消息的编码样式。 SOAPBinding.Style.RPC:面向RPC SOAPBinding.Style.DOCUMENT 默认,面向文档 SOAPBinding.Useuse 定义发送到WebService的消息和从WebService发送的消息的格式样式。 SOAPBinding.Use.LITERAL,默认,字面量风格,若服务端和客户端不在一起开发,就应该使用这个 SOAPBinding.Use.ENCODED使用SOAP编码风格,可能导致WS互操作方面失败问题,尽量避免使用。 实践总结: /** * endpointInterface : 定义服务抽象WebService 协定的服务端点接口的权限命名, 对应接口上也要标注 @WebService * name:服务接口名称(对应wsdl: portType的name属性,用在服务接口上); * portName : Web Service的端口名称。此名称被用作wsdl:port的名称 --- 标注在实现类上 * serviceName : 服务类名称。默认为,实现类名+Service( 对应service的name 和 definition上的name属性 对应,用在实现类上) * targetNamespace : 目标命名空间 -- 实现类和接口上都要标注 * wsdlLocation :WSDL地址(服务端除了WSDL优先的情况外可不写,客户端代理接口上必须配置此属性,指向web端WSDL文件地址) * @SOAPBinding(style=Style.RPC) : 声明访问规范 ,默认 document , * 当定义了服务抽象webservice协定的服务端点接口时,必须标注在接口上,否则会被忽略 */
CXF
是 XFire 和 Celtrix 的整合
优点:
是 SOA框架(面向服务编程) — ws只会用到 XFire
CXF内置 Jetty Web 服务器
使用CXF开发Web Server端组件都需要“接口”和“实现类”两部分。
支持多种数据格式:XML和JSON(Restful)。
可以与Spring进行快速无缝的整合
灵 活 的 部 署 : ant(build.xml) maven(pom.xml)
可 以 运 行 在 Tomcat , Jboss , Jetty(内 置web 服 务器) , IBMWebsphere , BeaWebLogic 上面。
下载官网: http://cxf.apache.org/ CXF 需要 配置 对应的 bin 到 环境变量path 中导包: asm 是字节码相关的包; logging 是日志相关的包; cxf 是框架核心包; geronimo-servlet 是servlet相关包; neethi 是网络安全相关包; wsdl4j 是wsdl解析用的包; xmlschema 是schema相关的包。 jetty服务器相关包 wsdl2java工具 --- 客户端代码生成工具 -d参数,指定代码生成的目录。 -p参数,指定生成的新的包结构。 在控制台执行: wsdl2java –d . -p org.leiax00.cxf http://192.168.1.3:9999/hello?wsdl 也可以进入客户端项目的src下执行命令: wsdl2java http://192.168.1.3:9999/hello?wsdl 通过 CXF 创建 服务端 1. 创建项目 2. 导入 cxf 的必须包,同时没有容器时还要导入jetty的包 3. 写代码测试 1) 写一个普通服务类 2) 标注注解, 成为一个 ws 服务类 3) 使用cxf来发布 //1. 创建JaxWsServerFactoryBean的对象,用于发布服务 JaxWsServerFactoryBean jaxWsServerFactoryBean = new JaxWsServerFactoryBean(); //2. 设置服务发布地址 jaxWsServerFactoryBean.setAddress("http://192.168.1.3:9999/hello"); //3. 设置服务发布接口 jaxWsServerFactoryBean.setServiceClass(IHelloService.class); //4. 设置服务发布对象 jaxWsServerFactoryBean.setServiceBean(new HelloServiceImpl()); //5. 设置拦截器 jaxWsServerFactoryBean.getInInterceptors().add(new AuthInInterceptor()); jaxWsServerFactoryBean.getInInterceptors().add(new LoggingInInterceptor()); //6. 通过create方法发布服务 jaxWsServerFactoryBean.create(); System.out.println("发布成功!!"); 4) 测试 --- wsdl地址时候能访问 通过 CXF 生成 客户端 通过 wsdl2java 工具生成客户端代码,在src目录下运行cmd: wsdl2java http://192.168.1.3:9999/hello?wsdl 生成后,只保留接口类 ,其余删除 --- 此时接口类报错 (@XmlSeeAlso({ObjectFactory.class})) ,将此注解也删除 获取服务: 1.创建JaxWsProxyFactoryBean的对象,用于接收服务 2.设置服务的发布地址,表示去哪里过去服务 3.设置服务的发布接口,使用本地的代理接口 4.通过create方法返回接口代理实例 5.调用远程方法
public static void main(String[] args) { //1. 创建JaxWsProxyFactoryBean的对象,用于接收服务 JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean(); //2. 设置服务的发布地址,表示去哪里过去服务 jaxWsProxyFactoryBean.setAddress("http://192.168.1.3:9999/hello"); //3. 设置服务的发布接口,使用本地的代理接口jaxWsProxyFactoryBean.setServiceClass(IHelloService.class); //4. 添加拦截器 jaxWsProxyFactoryBean.getOutInterceptors().add(new AuthOutInterceptor("admin", "root")); //4. 通过create方法返回接口代理实例 IHelloService helloService = (IHelloService)jaxWsProxyFactoryBean.create(); //5. 调用服务端的方法(远程) helloService.sayHello("李雷");}
CXF 自定义拦截器 --- 权限控制 1、声明一个类,来充当拦截器。这个类需要继承或实现某个接口或基类 , 一般直接继承 AbstractPhaseInterceptor类 。 2、完成拦截器的逻辑。 3、把拦截器配置到环境中。 使用自带的日志拦截器: --- 可监控到 soap消息 LoggingInInterceptor–信息输入时的拦截器-请求 LoggingOutInterceptor–信息输出时的拦截器-响应 服务端通过
jaxWsServerFactoryBean.getInInterceptors().add(new LoggingInInterceptor());
来添加拦截器 客户端通过
jaxWsProxyFactoryBean.getOutInterceptors().add(new LoggingOutInterceptor());
来添加拦截器
获取当前调用的方法 --- soap的body中存储了当前调用的方法 //4. 获取当前调用的方法
Exchange exchange = message.getExchange(); BindingOperationInfo bop = exchange.get(BindingOperationInfo.class); MethodDispatcher md = (MethodDispatcher) exchange.get(Service.class).get(MethodDispatcher.class.getName()); Method method = md.getMethod(bop); System.out.println("********method name:" + method.getName());
0 0
- WebService
- WebService
- webservice
- webservice
- WebService
- webservice
- webService
- WebService
- WebService
- webService
- WEBService
- webService
- WebService
- [WebService]
- webservice
- WebService
- webservice
- WebService
- iTerm2
- 图-有权图-最小生成树
- 模拟掷骰子
- 面试的角度诠释Java工程师(一)
- 8VC Venture Cup 2017
- webservice
- 图-有权图-最短路径算法
- 3743: [Coci2015]Kamp
- iOS
- PAT B1044/A1100 Mars Numbers (20)
- MySQL数据库基础(一)(启动-停止、登录-退出、语法规范及最基础操作)(持续更新中)
- 抽象类详解
- JavaScript创建对象的方式
- 使用Git分布式版本控制系统