Webservice实践(三)基于JDK的jax ws进行服务端开发

来源:互联网 发布:随机算法 知乎 编辑:程序博客网 时间:2024/05/30 23:03

上一节实践了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<String> ListLesson;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;}}
实体操作接口StudentDAO

package com.study.dao;import com.study.entity.Student;public interface StudentDAO {//学生操作,新增学生boolean addStudent(Student student);//学生操作,删除学生boolean delStudent(Student  student);//学生操作,修改学生信息boolean modifyStudent(Student  student);//学生操作,查询学生信息,查询到返回学生对象,否则返回nullStudent queryStudent( String  StudentName);}
操作接口实现 StudentDAOImpl

package com.study.dao.impl;import com.study.dao.StudentDAO;import com.study.entity.Student;public class StudentDAOImpl implements StudentDAO {@Overridepublic boolean addStudent(Student student) {// TODO Auto-generated method stubreturn false;}@Overridepublic boolean delStudent(Student student) {// TODO Auto-generated method stubreturn false;}@Overridepublic boolean modifyStudent(Student student) {// TODO Auto-generated method stubreturn false;}@Overridepublic Student queryStudent(String StudentName) {// TODO Auto-generated method stubreturn 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 {List<String > listStudentInfo=new ArrayList<String>();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工具调试

最后介绍一个soap工具,因为webservice是基于soap协议的,因此可以用soap工具来进行测试,这里简单介绍一个soap工具soapUi

通过这个工具可以不用开发webservice客户端直接通过工具调测接口。

新建一个工程:

OK后,在左边的树上选择要测试的接口,双击打开测试界面,输入参数,执行,可以在输出区看到输出结果。


0 0