import com.lct.web_service.CalculatorService;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Logger;
* Created by Administrator on 2019/1/25 0025.
public class Web_service {
//日志记录器
public static final Logger logger = Logger.getGlobal();
public static void main(String[] args) {
try {
/** url:webservice 服务端提供的服务地址,结尾必须加 "?wsdl"*/
URL url = new URL("http://192.168.1.20:3333/web_server/calculator?wsdl");
/** QName 表示 XML 规范中定义的限定名称,QName 的值包含名称空间 URI、本地部分和前缀。
* QName(final String namespaceURI, final String localPart):指定名称空间 URI 和本地部分的 QName 构造方法。
* 如下所示的两个数据都可以浏览器访问服务端时返回 xml 中第一行找到,如:
* <definitions xmlns:wsu=xxxxxxx targetNamespace="http://web_service.lct.com/" name="CalculatorServiceImplService">
QName qName = new QName("http://web_service.lct.com/", "CalculatorServiceImplService");
* Service 对象提供 Web 服务的客户端视图
* Service 作为以下内容的工厂:1、目标服务端点的代理,2、用于远程操作的动态面向消息调用的 javax.xml.ws.Dispatch 实例。
* create(java.net.URL wsdlDocumentLocation,QName serviceName):创建 Service 实例。
* wsdlDocumentLocation : 服务 WSDL 文档位置的 URL
* serviceName : 服务的 QName
Service service = Service.create(url, qName);
* 使用 getPorts 方法可以对服务上可用的端口/接口进行枚举
* getPort(Class<T> serviceEndpointInterface):获取支持指定服务端点接口的对象实例
* serviceEndpointInterface:指定返回的代理所支持的服务端点接口
CalculatorService calculatorService = service.getPort(CalculatorService.class);
float added = calculatorService.addition(100, 80);
float multied = calculatorService.multiplication(2.5F, 100);
logger.info("added:" + added);
logger.info("multied:" + multied);
} catch (MalformedURLException e) {
e.printStackTrace();
与《JWS(Java Web Service) 第一个案例入门》完全一致,调用成功。
如果客户端将 wsimport.exe 生成的类全部导入,主要指服务端接口的实现类,也就是上的 CalculatorServiceImplService.java,这样客户端调用服务端方法时,也可以采用如下的方式:
CalculatorServiceImplService calculatorServiceImplService = new CalculatorServiceImplService();
CalculatorService calculatorService = calculatorServiceImplService.getCalculatorServiceImplPort();
float added = calculatorService.addition(100,80);
float multied = calculatorService.multiplication(2.5F,100);
WSDL 文件结构剖析
WebService WSDL 文件结构
WSDL(Web Services Description Language) 是基于 XML web服务描述语言,用于描述 Web Service 及其函数、参数和返回值等,这样客户端才能方便调用。一些开发工具既能根据 Web service 生成 WSDL 文档,又能导入 WSDL 文档,生成调用相应 WebService 的代理类代码。 WSDL 文件保存在Web服务器上,通过一个 url 地址即可访问。客户端要调用一个WebService服务之前,要知道该服务的WSDL文件的地址,WebService 服务提供商通常通过两种方式来暴露它的 WSDL 文件地址:1、注册到UDDI服务器,以便被人查找;2、直接告诉给客户端调用者。 |
1、WSDL 文件作为一个 XML 文件,顶部必须用 <?xml version="1.0" encoding="UTF-8"?> 声明。
2、WSDL 文档的根元素是 definitions 元素,WSDL 文档包含5部分:types, message, portType, binding,service 。
1)definitions 元素
A、WSDL 文档的根元素都是 definition 元素,其中主要的是最后的两个属性,targetNameSpace 与 name。 B、targetNameSpace 属性 对应 @WebService 注解的 targetNameSpace属性,name 属性对应 @WebService 注解的 serviceName 属性。 C、可以在 webService 服务端的接口实现类中的 @WebService 注解中通过修改属性,从而修改 wsdl 文件的definition 元素的属性值,否则 targetNameSpace 为 "http://" 加 "包名的反写",name 为 "实现类名称"+"Service"。 |
2)types 元素:定义访问的类型,如请求的方法名,参数,以及返回值等。
可以浏览器访问 schemaLocation 属性的值,看到详细信息。
3)message:SOAP 协议消息传递的参数,同样包括请求与返回两部分。
message 的元素会和 types 中的元素进行对应。
4)portType:指明服务器的接口,并且通过 operation 绑定相应的 input、ouput 消息。
5)binding:指定消息传到所使用的格式
6)service:指定服务所发布的名称
服务方法数据类型说明
1、Java 默认提供的 JWS API 开发 webService 时,支持自己的 8 种基本类型: boolean、byte、short、int、long、float、double 和 char、也支持引用类型 List、Set、Array,以及自定义的 POJO 对象 等,但唯独不支持 Map 类型。
2、如果服务接口方法的参数或者返回值是 Map 类型,则 Endpoint.publish 发布时直接报错失败,如下所示为方法的返回值使用 Map 类型时,启动服务时报错:
Exception in thread "main" javax.xml.ws.WebServiceException:
class com.lct.web_service.jaxws.GetStudentMapResponse do not have a property of the name return
3、所以要么就服务接口中的方法参数以及返回值尽量不要使用 Map 类型,换成其它类型,如 List 等,如果一定要用 Map 类型,则只能导入 CXF 等第三方框架的 Jar 包,不用改变任何代码,即可正常发布成功。客户端仍然使用 JWS 的 API 即可,可以不用导入 CXF 的 包。
@WebResult 与 @WebParam
1、上面 types 元素定义访问的类型,如请求的方法名,参数,以及返回值等,使用的都是默认值,如果想要进行修改,则可以使用 这两个注解。
@WebResult :定义 wsdl 文件中,服务端方法返回值名称 @WebParam :定义 wsdl 文件中,客户端请求的方法参数名称 定义在接口中的方法上即可,如下所示进行修改,其余内容不变。 |
import javax.jws.*;
* Created by Administrator on 2019/1/25 0025.
* 计算器接口
* SEI(Service Endpoint Interface):服务终端接口,即webService提供的服务接口
* SIB(Service Implemention Bean):服务实现类,即webService提供的服务接口的实现类
* @javax.jws.WebService : 将 Java 类标记为实现 Web Service,或者将 Java 接口标记为定义 Web Service 接口
* 不过是服务端还是客户端,接口上都必须写上此注解
@WebService
public interface CalculatorService {
* @WebResult :定义 wsdl 文件中,服务端方法返回值名称
* @WebParam :定义 wsdl 文件中,客户端请求的方法参数名称
@WebResult(name = "additionResult")
public float addition(@WebParam(name = "a") float a, @WebParam(name = "b") float b);
@WebResult(name = "multiplicationResult")
public float multiplication(@WebParam(name = "a") float a, @WebParam(name = "b") float b);
学生实体验证示例
1、这里提供两个服务,一是查询学生在校是否有惩罚的服务(如警告、记过等),二是查询学生的缴费状态。
服务端内容结构如上。 Student:学生实体类、StudentService:提供的学生服务接口、StudentServiceImpl:服务接口的实现 Web_Service:用于启动 webService 服务 |
import java.util.Date;
* Created by Administrator on 2019/2/13 0013.
* Student 实体
public class Student {
* sID:学生学号
* sName:学生姓名
* sex:性別,true 表示男生、false 表示女生
* birthday:学生生日
* punishStatus:在校是否被惩罚过,未惩罚(0)、警告(1)、记过(2)、记大过(3)、留校察看(4)、开除学籍(5)
private Integer sID;
private String sName;
private Boolean sex;
private Date birthday;
private Integer punishStatus;
//省略 getter、setter、toString 方法未粘贴
import com.lct.domain.Student;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
* Created by Administrator on 2019/2/13 0013.
* 用户登录校验服务接口
* @javax.jws.WebService : 将 Java 类/接口标记为 Web Service(web服务)
* 服务端的 web service 接口与其实现类都必须写 @WebService 注解
@WebService
public interface StudentService {
* 根据学生学号获取学生 "奖惩信息"
* @param sId :学生学号
* @return 返回整个学生的简要实体数据, 主要是演示返回值为实体
@WebResult(name = "getStudentById")
public Student getStudentById(@WebParam(name = "sId") Integer sId);
* 学生是否支付全部学费
* @param student
* @return
* @WebParam 的作用是 java jdk wsimport 工具生成的代理类看起来可以更直观,否则会是 arg0、arg1 ...
* 单纯从调用上来说,写没写 @WebParam 调用都是一样的
* @WebResult 也是同理,作用是使生成的 wsdl 文件看起来更直观,从调用上来说,写不写都是一样的
@WebResult(name = "isPayTuition")
public boolean isPayTuition(@WebParam(name = "Student") Student student);
import com.lct.domain.Student;
import javax.jws.WebService;
import java.util.Date;
import java.util.Random;
import java.util.UUID;
import java.util.logging.Logger;
* Created by Administrator on 2019/2/13 0013.
* @javax.jws.WebService : 将 Java 类/接口标记为 Web Service(web服务),服务端的 web service 接口与其实现类都必须写 @WebService 注解
* endpointInterface:终端接口,定义服务抽象 Web Service 协定的服务端点接口的完整名称,通常设置为服务实现类的全路径
* 写了endpointInterface,@WebResult、@WebParam才会有效
* serviceName:对应生成的 WSDL 文件中的 definitions 元素中的 name 属性值,默认以服务类名称+"Service"为值
* 客户端连接时使用QName创建实例时需要传入此 name 属性值,以及targetNamespace属性值,都可以在 @WebService 中指定
@WebService(endpointInterface = "com.lct.web_service.StudentService", serviceName = "StudentService")
public class StudentServiceImpl implements StudentService {
* 日志记录器
public static final Logger logger = Logger.getGlobal();
@Override
public Student getStudentById(Integer sId) {
/**随机生成一个学生,只做演示*/
Student student = new Student();
student.setsID(sId);
student.setBirthday(new Date());
student.setPunishStatus(new Random().nextInt(6));
student.setsName(UUID.randomUUID().toString());
logger.info("获取学号 " + sId + " 的学生信息结果为:" + student.toString());
return student;
@Override
public boolean isPayTuition(Student student) {
/**随机生成是否已经交费,nextInt(a)生成 [0,a)直接的随机整数*/
boolean flag = new Random().nextInt(2) == 0 ? true : false;
logger.info(student.toString() + " 是否已经全部缴费?" + flag);
return flag;
import javax.xml.ws.Endpoint;
import java.util.logging.Logger;
* Created by Administrator on 2019/1/25 0025.
* webServer 启动类
public class Web_Service {
//日志记录器
public static final Logger logger = Logger.getGlobal();
public static void main(String[] args) {
/**webService服务器提供给客户端访问的地址
* 192.168.1.20 为服务器 ip、3333为指定的端口号、web_server 为应用名称、student 为标识
* 这个地址符合 http 地址即可,为了看起来更像是 web访问,所以才写了应用名,即使是 http://192.168.1.20:3333/xxx 也是可以的
String wsUrl = "http://192.168.1.20:3333/web_server/student";
* javax.xml.ws.Endpoint 表示一个 web service 终端,这是一个抽象类,其中提供了静态方法可以直接调用
* Endpoint publish(String address, Object implementor)
* address:传输协议的 url 地址;
* implementor(实现者):web service 终端的实现类,因为一个 ws 接口可能会有多个实现类
Endpoint.publish(wsUrl, new StudentServiceImpl());
logger.info("webService 服务启动,等待客户端请求...");
2、启动 webService 后,浏览器便可以进行访问,整个 wsdl 文件:http://192.168.1.20:3333/web_server/student?wsdl、数据类型地址:http://192.168.1.20:3333/web_server/student?xsd=1 (可在 types 的 schemaLocation 属性中找到)。
1、新建客户端项目,客户端使用 Java JDK wsimport.exe 工具根据服务端提供的 wsdl 文件地址生成代理类,在 cmd 窗口中操作命令如下: wsimport -d E:/wmx/webservice -keep -verbose http://192.168.1.20:3333/web_server/student?wsdl
2、其中 -d 表示输出内容存放的目录,此目录必须事先存在;最后是 wsdl 地址,结尾必须加上 ?wsdl 参数。
3、如上所需要的一共7个,2个方法输入输出一共生成4个类,加上 ObjectFactory 对象工厂类、以及 Student 实体类、StudentService 服务接口。导入到客户端项目中:
4、其中的 Web_service 用于启动应用,调用服务端方法,其内容如下:
import com.lct.web_service.Student;
import com.lct.web_service.StudentService;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Logger;
* Created by Administrator on 2019/1/25 0025.
public class Web_service {
//日志记录器
public static final Logger logger = Logger.getGlobal();
public static void main(String[] args) {
try {
/** url:webservice 服务端提供的服务地址,结尾必须加 "?wsdl"*/
URL url = new URL("http://192.168.1.20:3333/web_server/student?wsdl");
/** QName 表示 XML 规范中定义的限定名称,QName 的值包含名称空间 URI、本地部分和前缀。
* QName(final String namespaceURI, final String localPart):指定名称空间 URI 和本地部分的 QName 构造方法。
* 如下所示的两个数据都可以浏览器访问服务端时返回 xml 中第一行找到,如:
* <definitions xmlns:wsu=xxxxxxx targetNamespace="http://web_service.lct.com/" name="StudentService">
* namespaceURI 可以通过服务端的 @WebService 的 targetNamespace 属性指定
* localPart 可以通过服务端的 @WebService 的 serviceName 属性指定
QName qName = new QName("http://web_service.lct.com/", "StudentService");
* Service 对象提供 Web 服务的客户端视图
* Service 作为以下内容的工厂:1、目标服务端点的代理,2、用于远程操作的动态面向消息调用的 javax.xml.ws.Dispatch 实例。
* create(java.net.URL wsdlDocumentLocation,QName serviceName):创建 Service 实例。
* wsdlDocumentLocation : 服务 WSDL 文档位置的 URL
* serviceName : 服务的 QName
Service service = Service.create(url, qName);
* 使用 getPorts 方法可以对服务上可用的端口/接口进行枚举
* getPort(Class<T> serviceEndpointInterface):获取支持指定服务端点接口的对象实例
* serviceEndpointInterface:指定返回的代理所支持的服务端点接口
StudentService studentService = service.getPort(StudentService.class);
Student student = studentService.getStudentById(9527);
boolean flag = studentService.isPayTuition(student);
logger.info("获取学生信息:姓名:" + student.getSName() + ",惩罚状态:" + student.getPunishStatus() + ",生日:" + student.getBirthday());
logger.info("此学生是否已经交完学费:" + flag);
} catch (MalformedURLException e) {
e.printStackTrace();
5、先启动服务端,然后运行客户端,结果如下:
webService 调用服务端完全没有问题。
目录wsimport 简介wsimport 使用示例服务端客户端调用测试wsimport 简介1、Java JDK 的 bin文件夹下有一个 wsimport.exe 工具,可依据 wsdl 文件生成相应的类文件,将生成好的类文件拷贝到需要使用的项目中,就可以像调用本地的类一样调用 webService 提供的方法。2、wsimport.exe 工具可以用于非 Ja...
简单的webservice示例,及使用java工具生成客户端
在JDK1.6版本以后,在/bin目录下有一个wsimport.exe工具,该工具可以根据wsdl文件自动生成webservice接口调用的java客户端代码,十分方便。而自己仅需要写一个测试类。
使用过程如下:
1. 获取webservice的wsdl文件。
2. 输入命令wsimport unifiedOrder.wsdl -keep -p wy.soap.order -s d:/mytest即可生成代码到d:/mytest目录。
参数含义如下:
-keep keepgenerated files
-p specifiesthe target package
-s specify where to place generated source files
也可以直接从url生成:
wsimport -d generated http://example.org/stock?wsdl
1、安装jdk Java开发环境
2、编辑(包名,输出路径,wsdl)参数并运行WSDL2Java(URL).bat或者WSDL2Java(file).bat后,将在source中生成WebService客户端代码。
3、直接使用生成的代码调用WebService服务即可。
wcf接口是由.net提供的webservice接口,一般是使用wsdl文件的样式发布,在wsdl文件中,包含该webservice暴露在外面可供使用的接口。
了解到的调用wfc接口方法有三种:
AXIS调用远程webservice
SOAP调用远程webservice
wsimport生成java代码,调用接口
在尝试方法1、2多次失败后,果断放弃,选择了简单易上手的方法3。通过jdk6.0以上版本自带的wsimport工具,即可根据wsdl文件生成相应的类文件。将这些生成的文件放在相应项目,就可以像调用本地的类一样调用webservice提供给的方法了。
具体步骤:
1、通过w
wsimport -s G:\\workspace\\webService\\TheClient\\src -p com.hyan.client -keep http://localhost:9001/Service/ServiceHello?wsdl
1)"src目录"地址不可含空格
2)“wsdl发布地址”不要漏了“?wsdl”
1.1 wsimport命令工具
在我们安装的jdk的bin的bin文件夹中,有一个wsimport.exe,这个工具依据wsdl文件生成相应的类文件,然后用这些类文件,就可以像调用本地的类一样调用WebService提供的方法。
该工具可以用于非Java的服务器,如:用C#编写的WebService,通过wsimport则生成Java的客户端实现。
1.2 使用wsimport 生成webservice客户端代码的思想流程
通过webservice做数据对接时,由于公司的网络和对方网络连不通,访问不了对方提供的webservice链接,为了先了解对方的接口方法,可以根据WSDL文件生成接口。
jdk 提供了一个wsimport命令,可以实现该需求。
用法: wsimport [options] <WSDL_URI>
在cmd命令窗口切换到wsdl文件所在目录,执行即可,命令如下:
>wsimport...
回答: 当系统找不到文件 C:\ProgramData\Oracle\Java\javapath\java.exe时,这通常是由于升级本地JDK版本后未正确更新环境变量所导致的。解决方法是删除C:\ProgramData\Oracle\Java\javapath\java.exe下的三个exe文件,然后再执行java -version命令查看版本。\[1\]另外,你也可以将路径C:\ProgramData\Oracle\Java\javapath复制到地址栏,进入到javapath文件夹,删除其中的三个文件,这样就可以正常使用java命令了。\[2\]
#### 引用[.reference_title]
- *1* [系统找不到C:\ProgramData\Oracle\Java\javapath\java.exe问题及解决方案](https://blog.csdn.net/weixin_44214857/article/details/124947828)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item]
- *2* [【已解决】系统找不到文件 C:\ProgramData\Oracle\Java\javapath\java.exe。](https://blog.csdn.net/weixin_40828511/article/details/124515721)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item]
[ .reference_list ]