当前位置: 首页 > java >正文

WebService的学习

1、WebService基本学习

WebService 即 Web服务,它是一种支持跨编程语言和跨操作系统的远程调用技术。比如,WebService服务端采用PHP语言编写,而客户端(Client)可以使用PHP,也可以使用JAVA语言来访问WebService服务端。

实现WebService的方式有不少。比如,使用JDK自带的JAX-WS,或者使用Apache CXF框架。这里,我们使用Apache CXF框架进行WebService的服务发布(服务端搭建)和 客户端远程访问(客户端搭建)。

Apache CXF官方文档:http://cxf.apache.org/docs/index.html

2、WebService规范

JAVA中有三种WebService规范:JAX-WS、JAX-RS、JAXM&SAAJ,常用的两种WebService规范是 JAX-WS 和 JAX-RS

JAX-WS,全称 Java Api For Xml-WebService,采用SOAP协议。

JAX-RS 采用HTTP协议,它发行比较晚,使用的是Restful风格定义的一套WebService规范。

SOAP协议,即简单对象访问协议(Simple Object Access Protocol),WebService使用的一种通信协议,用于客户端和服务端之间的通信。

3、wsdl说明书

WebService描述语言:WSDL(WebService Definition Language),实际就是一个XML文件,文件里描述了对外发布的服务名,接口的方法名,接口参数,返回值类型等等。

4、WebService服务端搭建

Maven依赖

    <dependencies><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-frontend-jaxws</artifactId><version>3.0.1</version></dependency><!--内置jetty web服务器,如果整合了SpringBoot,就不需要这个依赖,SpringBoot自带了tomcat服务器--><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-transports-http-jetty</artifactId><version>3.0.1</version></dependency></dependencies>

接口请求参数

public class User {private String username;private Integer age;private String password;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}
}

定义对外发布的服务和接口信息

/*** 对外发布的服务名*/
public interface UserService {/*** 对外发布的接口** @param username* @return*/String queryUserInfo(String username, String password);/*** 对外发布的接口** @param* @return*/void saveUser(User user);
}

服务端接口的实现类

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;/*** @WebService不传属性值,默认类名作为服务名*/
@WebService(name = "UserWebServiceDemo", serviceName = "UMR")
public class UserServiceImpl implements UserService {@WebMethod@WebResult(name = "QueryResult")public String queryUserInfo(@WebParam(name = "username") String username,@WebParam(name = "password") String password) {return username + "查询信息成功";}@WebMethod(operationName = "saveFunction")@WebResultpublic void saveUser(@WebParam(name = "accountInfo") User user) {System.out.println("保存用户信息");}
}

发布服务

import org.apache.cxf.jaxws.JaxWsServerFactoryBean;public class ServiceProvider {public static void main(String[] args) {//发布服务的工厂JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();//设置服务地址factory.setAddress("http://localhost:9180/ws");//服务类factory.setServiceBean(new UserServiceImpl());//发布服务factory.create();System.out.println("服务发布成功");}
}

5、wsdl说明书的使用

wsdl说明书的访问地址:服务地址?wsdl

wsdl说明书的阅读顺序:从下往上阅读 

根据wsdl文件最下面的service节点找到服务名

然后,根据服务名绑定的 "UMRSoapBinding" 进行搜索

找到bingding节点的operation子节点,operation的name属性就是接口的方法名

input节点的name属性 就是 输入参数名,output节点的是 返回参数名

根据 输入参数名 和 返回参数名,找到真正的参数信息

6、WebService客户端搭建

① Maven依赖 和 接口请求参数 ,跟服务端搭建时保持一致

② 定义客户端接口(不需要写他的实现类)

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;@WebService(name = "UserWebServiceDemo", serviceName = "UMR", targetNamespace = "http://impl.service.com/")
public interface UserClient {@WebMethod@WebResult(name = "QueryResult")String queryUserInfo(@WebParam(name = "username") String username,@WebParam(name = "password") String password);@WebMethod(operationName = "saveFunction")@WebResultvoid saveUser(@WebParam(name = "accountInfo") User user);
}

③ 访问远程服务端

import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;public class UserConsumer {public static void main(String[] args) {//创建cxf代理工厂JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();//设置服务端的地址factory.setAddress("http://localhost:9180/ws");//设置接口类型factory.setServiceClass(UserClient.class);//生成代理对象UserClient userClient = factory.create(UserClient.class);String result = userClient.queryUserInfo("hello", "123");System.out.println(result);}
}

收到了服务端的返回 

7、常见异常

Exception in thread "main" javax.xml.ws.soap.SOAPFaultException:

Unexpected wrapper element {http://client.com/} queryUserInfo found.  

Expected {http://impl.service.com/} queryUserInfo.

遇到 Unexpected wrapper element 错误,通常是客户端发的消息结构和服务端WSDL中定义的不匹配。

针对上面那个异常,是命名空间不一致导致的。服务端生成WSDL的时候,命名空间默认是包名倒序。而客户端跟服务端包路径不一致,就导致出现命名空间的错误。

所以,我才在客户端的@WebService注解中,用targetNamespace属性指定了命名空间,保证和服务端的一致。

http://www.xdnf.cn/news/4075.html

相关文章:

  • 电子邮件相关协议介绍
  • NetSuite 2025.1 学习笔记
  • Java基础学完,继续深耕(0505)Linux 常用命令
  • TS 类class修饰符
  • 接口测试过程中常见的缺陷详解
  • Go小技巧易错点100例(三十)
  • 算法刷题篇
  • 基于Redis实现优惠券秒杀——第3期(分布式锁-Redisson)
  • UniGetUI 使用指南:轻松管理 Windows 软件(包括CUDA)
  • 【Springboot知识】Springboot计划任务Schedule详解
  • 前端懒加载(Lazy Loading)实战指南
  • 旋转图像(中等)
  • RPC是什么
  • Linux文件复制命令精要指南:cp与scp详解
  • Three.js + React 实战系列 - 客户评价区细解教程 Clients 组件✨(回答式评价 + 评分星级)
  • 51c大模型~合集124
  • TS 类型兼容性
  • 乡村饮用水厂无线网络规划与设计:融合 LoRaWAN、5G、Mesh 的分层异构方案
  • unity TMP字体使用出现乱码方框
  • 最长回文子串(动规 + 中心拓展)
  • 反转字符串2
  • 杰理-JL701-充电开机,芯片不进入休眠
  • Spring Boot 中 @Bean 注解详解:从入门到实践
  • 无人机 | 无人机设计概述
  • Springclound常用五大组件及其使用原理
  • 防止交叉验证中的数据泄露:提升模型在实际环境中的性能
  • 怎样获得真实带宽之宽带升级后
  • 014枚举之指针尺取——算法备赛
  • C++类与对象深度解析:从基础到应用
  • kotlin 01flow-StateFlow 完整教程