本文共 7482 字,大约阅读时间需要 24 分钟。
上一节实践了Webservice的客户端开发,那么核心问题服务是如何开发和发布呢?Webservice 服务端的开发有多种方式:
1、利用jdk+myeclipse ,发布和开发一个后台服务(适合独立服务)
2、利用axis2+myeclipse+tomcat 开发和发布(适合web工程)
3、利用cxf + myeclipse +tomcat 开发和发布(适合web工程)
4、利用 xfire +myeclipse+tomcat 开发和发布(适合web工程)
从本节开始,将实践这些不同的发布webservice的方法,本节就先实践第一种,利用 jdk+myeclipse来发布一个后台服务
1、掌握jdk中编写webservice服务端工程的设置和开发过程
2、编写客户端
3、服务端和客户端发布,并进行调试
1、创建一个服务端工程StudyWsStudent ( 关于学生的webservice 服务)
为了便于服务端的程序进行扩展,在服务端的设计上,采用接口编程的方式,即采用 实体类,dao接口,dao实现,接口类的方式才组织。 代码都很简单。
进入后的选项要注意一下
Framework这里,注意选JAX-WS, 另外JTL 这里选none
先看一下工程的结构:
代码如下:
实体类Student
package com.study.entity;import java.util.List;public class Student { String Name; String Sex; String Birth; String DateIn; //已经选择的课程 List实体操作接口StudentDAOListLesson; public String getName() { return Name; } public void setName(String name) { Name = name; } public String getSex() { return Sex; } public void setSex(String sex) { Sex = sex; } public String getBirth() { return Birth; } public void setBirth(String birth) { Birth = birth; } public String getDateIn() { return DateIn; } public void setDateIn(String dateIn) { DateIn = dateIn; } //采用dao 方式开发的情况下,实体类是否要设计action? boolean selectLesson( String Lesson ){ if(ListLesson.size()>10) { System.out.println("You have select ten Lesson, cannot select more!"); return false; } else{ ListLesson.add(Lesson); } return true; } }
package com.study.dao;import com.study.entity.Student;public interface StudentDAO { //学生操作,新增学生 boolean addStudent(Student student); //学生操作,删除学生 boolean delStudent(Student student); //学生操作,修改学生信息 boolean modifyStudent(Student student); //学生操作,查询学生信息,查询到返回学生对象,否则返回null Student queryStudent( String StudentName); }操作接口实现 StudentDAOImpl
package com.study.dao.impl;import com.study.dao.StudentDAO;import com.study.entity.Student;public class StudentDAOImpl implements StudentDAO { @Override public boolean addStudent(Student student) { // TODO Auto-generated method stub return false; } @Override public boolean delStudent(Student student) { // TODO Auto-generated method stub return false; } @Override public boolean modifyStudent(Student student) { // TODO Auto-generated method stub return false; } @Override public Student queryStudent(String StudentName) { // TODO Auto-generated method stub return null; }}最后是Webservice 接口服务StudentOptApi
package com.study.student.service;import java.util.ArrayList;import java.util.List;import javax.jws.WebMethod;import javax.jws.WebParam;import javax.jws.WebService;import javax.xml.ws.Endpoint;import com.study.dao.StudentDAO;import com.study.dao.impl.StudentDAOImpl;import com.study.entity.Student;@WebService public class StudentOptApi { ListlistStudentInfo=new ArrayList (); StudentDAO studentDAO ; // public StudentOptApi(){// System.out.println("studentDAO is init");// studentDAO= new StudentDAOImpl();// } @WebMethod(exclude = true) public StudentDAO getStudentDAO() { return studentDAO; } @WebMethod(exclude = true) public void setStudentDAO(StudentDAO studentDAO) { this.studentDAO = studentDAO; } public boolean addStudent( Student student){ //调用studentDAO.addStudent 方法入库 System.out.println("Now put student into DB!"); studentDAO.addStudent(student); //listStudent模拟数据库中的student对象集合 listStudentInfo.add("Name:"+student.getName()+",sex:"+student.getSex()+",birthday:"+student.getBirth());// for( Student aStudent : listStudent ){// System.out.println(aStudent.getName());// } return true; } @WebMethod(operationName = "queryStudent") public String queryStudent( @WebParam(name = "StudentName")String studentName){ for(String aStudentInfo : listStudentInfo ) { if(aStudentInfo.startsWith("Name:"+studentName+",")){ System.out.println("queryStudent Infomation successfully !"); return aStudentInfo; } else{ System.out.println("queryStudent Infomation failture !"); } } return "null"; } public static void main(String[] args) { // create and publish an endpoint StudentOptApi studentWs = new StudentOptApi(); studentWs.studentDAO= new StudentDAOImpl(); Student student1 = new Student(); student1.setName("Tom"); student1.setSex("male"); student1.setBirth("1970/05/08"); Student student2 = new Student(); student2.setName("Lili"); student2.setSex("female"); student2.setBirth("1972/05/23"); studentWs.addStudent(student1); studentWs.addStudent(student2); //Endpoint endpoint = Endpoint.publish("http://localhost:8080/StudentService/", studentWs); Endpoint endpoint = Endpoint.publish("http://localhost:8080/StudentService/queryStudent", studentWs); } }
这里需要注意一下 StudentService 类,它采用了Webservice的annotation,@WebMethod(operationName = "addStudent",exclude = true), 如果不加 exclude = true 会报告下列错误
错误这里说明了,JAXB 不支持interfaces类。 而我们的服务是面向接口的编程,因此需要通过 exclude = true 来解决这个问题。
另外,如果没有写类的初始化方法,也会报下面的异常
Exception in thread "main" com.sun.xml.internal.ws.model.RuntimeModelerException: The web service defined by the class com.study.student.service.StudentService does not contain any valid WebMethods. at com.sun.xml.internal.ws.model.RuntimeModeler.buildRuntimeModel(RuntimeModeler.java:233) at com.sun.xml.internal.ws.server.EndpointFactory.createSEIModel(EndpointFactory.java:328) at com.sun.xml.internal.ws.server.EndpointFactory.createEndpoint(EndpointFactory.java:190)
好,现在运行一下这个服务类,我们通过URL来打开这个服务
http://localhost:8080/StudentService/queryStudent
也给出了wsdl的地址,可以通过这个地址获取wsdl文件,并编写客户端
根据上一篇的说明,客户端的开发步骤如下:
1)获取wsdl 文件
2)并写编译成本地java 文件
3)编写客户端代码
在本例中,由于服务在本地搭建的,所以可以1),2) 两步合并处理,使用的命令为:
C:\jdk1.6.0_43\bin\wsimport -d E:\tmp -s E:\cwqwork\myeclipse_workspace\StudyDubboCli\src -keep -verbose http://localhost:8080/StudentService/queryStudent?wsdl
wsimport 的几个参数含义这里列一下:
-keep:是否生成java源文件 -d:指定输出目录 -s:指定源代码输出目录 -p:以package的形式生成文件 -verbose:在控制台显示输出信息
执行上面的命令后,就可以生成客户端需要的java文件,如下图:
下面,列一下客户端的编码: StudentWsCli.java
package com.study.webservice.client;import com.study.student.service.StudentOptApi;import com.study.student.service.StudentOptApiService;public class StudentWsCli { public static void main(String[] args) { //从webservice接口中获取到接口对象 StudentOptApi studentService = new StudentOptApiService().getStudentOptApiPort() ; String info1 = studentService.queryStudent("Tom"); System.out.println(info1); String info2 = studentService.queryStudent("Lili"); System.out.println(info2); String info3 = studentService.queryStudent("Jerry"); System.out.println(info3); }}在myeclipse里面,工程情况如下:
运行客户端,客户端打印如下:
查询"Tom", “Lili”,接口返回 Tom的相关信息,查询“Jerry",接口返回null
下面尝试将服务端发布到虚拟机上运行,实践一下服务端部署的过程。
因为是部署到虚拟机,客户端要从宿主机连接,所以修改一下服务端的endpoint代码,将localhost修改为 0.0.0.0 表示允许全部的外部ip接入。将服务端用fatjar 打包后,传送到虚拟机192.168.136.144上, 运行 java -jar StudyWsStudent_fat.jar
打开http://192.168.136.144:8080/StudentService/queryStudent 无法打开(原因后面说)
http://192.168.136.144:8080/StudentService/queryStudent?wsdl 正常打开
用客户端连接,注意客户端要修改一下StudentOptApiService.java文件中的ip地址,否则要用http://192.168.136.144:8080/StudentService/queryStudent?wsdl 这个地址重新编译。
客户端连接正常,说明程序是发布正常的。
现在回过来检查 http://192.168.136.144:8080/StudentService/queryStudent 无法打开的原因,因为我们是用java自带的编写webservice服务,所以检查一下144上的java版本,发现jar包是用jdk 1.6而 144上是java 1.8 。 144上有另外一个java 1.7,用1.7来运行,这下可以正常打开URL了
最后介绍一个soap工具,因为webservice是基于soap协议的,因此可以用soap工具来进行测试,这里简单介绍一个soap工具soapUi
通过这个工具可以不用开发webservice客户端直接通过工具调测接口。
新建一个工程:
点OK后,在左边的树上选择要测试的接口,双击打开测试界面,输入参数,执行,可以在输出区看到输出结果。