首页 技术 正文
技术 2022年11月21日
0 收藏 421 点赞 3,119 浏览 6682 个字

本节将实践目前最流行的第二种web service 发布和调试框架  CXF

Apache CXF 是一个开放源代码框架,提供了用于方便地构建和开发 Web 服务的可靠基础架构。它允许创建高性能和可扩展的服务,您可以将这样的服务部署在 Tomcat 和基于 Spring 的轻量级容器中,以及部署在更高级的服务器上。Java的webService实现本身就是一个很耗性能的实现方案(xml与java对象之间在服务端以及客户端的互转比较消耗性能),目前java主流的webService应用以CXF、AXIS2为主,CXF比AXIS2效率更高,并且在java 应用中CXF很成熟,因此CXF在webservice中占有非常重要的地位。

下面一张网络上的图比较好的说明了CXF 与web service的关系

下面将具体说说如何使用CXF 进行Webservice 开发。关于CXF的实践分2篇,

    第一篇通过注解发布webservice,利用cxf 进行客户端开发。

    第二篇:通过spring与cxf 结合进行发布

前面已经学习了使用JDK发布WebService本文内容,下面学习cxf框架完成服务器发布 和 客户端开发

  需要准备环境 myeclipse 和 cxf 包 (我是用的Myeclipse2017 和 apache-cxf-3.1.15.zip的cxf包、jdk 1.8 环境  — ps:apache-cxf-3.2.4.zip 版本太高,报错 好像跟jdk版本有关系,所以用了 apache-cxf-3.1.15.zip的cxf包)

1、服务端发布方式:用cxf 框架方式

1、首先在myeclipse中创建一个java web project

工程里面的类分别是Student.java   StudentDAO.java  StudentDAOImpl.java  StudentWs.java StudentWsImpl.java,

本文的Student对象用的是单例模式

这里重点贴一下 StudentWs.java  和  StudentWsImpl.java.    StudentWs是暴露的接口类,也是web service 服务接口,  实现类是服务的实现。

项目结构如下图

需要的jar包

我用的是apache-cxf-3.2.4 在lib里面拿过来的

基本代码如下:

Student.java 类

package com.myl.entity;
/**
*
* @author maoyl
* @date 2018.4.15
* 实体类
*
*/
public class Student { private String name;
private String sex;
private String brithday; public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getBrithday() {
return brithday;
}
public void setBrithday(String brithday) {
this.brithday = brithday;
}}

GetStudentUtil.java

package com.myl.entity;/**
*
* @author myl
* @date 2018.4.15
* 单例获取Student
*
*/
public class GetStudentUtil { private static Student student = new Student(); private GetStudentUtil(){ } public static Student getStudent(){
return student;
}}

StudentDao.java

package com.myl.dao;import com.myl.entity.Student;/**
*
* @author myl
* @date 2018.4.15
* Dao层接口
*
*/
public interface StudentDao { public boolean addStudentDao(String name, String sex, String brithday); public Student queryStudentDao(String name); }

StudentDaoImpl.java

package com.myl.dao.daoImpl;import com.myl.dao.StudentDao;
import com.myl.entity.GetStudentUtil;
import com.myl.entity.Student;/**
*
* @author myl
* @date 2018.4.15
* Dao层实现类
*
*/
public class StudentDaoImpl implements StudentDao { public Student student; @Override
public boolean addStudentDao(String name, String sex, String brithday) {
student = GetStudentUtil.getStudent();
System.out.println("student是否为空--"+student);
System.out.println(student.getName());
System.out.println();
student.setName(name);
student.setSex(sex);
student.setBrithday(brithday); return true;
} @Override
public Student queryStudentDao(String name) {
student = GetStudentUtil.getStudent();
//代替DB
// student.setName("mao");
// student.setSex("boy");
// student.setBrithday("22");
System.out.println("------查询学生-------");
if(name == null){
System.out.print("输入为学生名称为null");
return null;
}
if(!name.equals(student.getName())){
System.out.println("没有此人");
student =null;
}
System.out.println("返回student------------------");
return student;
}}

StudentWs.java

package com.myl.service;import com.myl.entity.Student;/**
*
* @author myl
* @date 2018.4.15
* service层接口
*
*/
public interface StudentWs { public boolean addStudentService(String name, String sex, String brithday); public Student queryStudentService(String name);
}

StudentWsImpl.java

package com.myl.service.serviceImpl;import javax.jws.WebMethod;
import javax.jws.WebService;
import com.myl.dao.StudentDao;
import com.myl.dao.daoImpl.StudentDaoImpl;
import com.myl.entity.Student;
import com.myl.service.StudentWs;/**
*
* @author myl
* @date 2018.4.15
* service层实现类,也是暴露给客户端的接口
* exclude = true表示不暴露给客户端
* @WebMethod(operationName = "queryStudentService") 标注自定义方法
* @WebMethod 默认为该方法名
*
*/@WebService
public class StudentWsImpl implements StudentWs { public StudentDao studentDao;// @WebMethod(exclude = true)
// public StudentDao getStudentDao() {
// return studentDao;
// }
//
// @WebMethod(exclude = true)
// public void setStudentDao(StudentDao studentDao) {
// this.studentDao = studentDao;
// }
public StudentWsImpl() {
studentDao = new StudentDaoImpl();
} @WebMethod
@Override
public boolean addStudentService(String name, String sex, String brithday) { System.out.println("addStudent-------------");
boolean result = studentDao.addStudentDao(name, sex, brithday);
return result;
} @WebMethod(operationName = "queryStudentService")
@Override
public Student queryStudentService(String name) { System.out.println("queryStudent-----------");
Student student = studentDao.queryStudentDao(name);
return student;
}}

StudentTest.java

package com.myl.test.publish;import org.apache.cxf.endpoint.Server;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;import com.myl.service.serviceImpl.StudentWsImpl;/**
*
* @author myl
* @date 2018年4月15日 下午11:26:50
* 服务端发布接口
*/
public class StudentTest { public static void main(String[] args) {
System.out.println("web service start");
//获取工厂对象
JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean(); //这里必须传入class,不能是接口,否则客户端会报异常 Could not instantiate service class ... because it is an interface
factory.setServiceClass(StudentWsImpl.class);
//传入接口url
factory.setAddress("http://localhost:5555/studentws");
//创建接口
Server server = factory.create();
//启动接口
server.start();
System.out.println("web service started");
}}

测试发布如下图表示成功

访问http://localhost:5555/studentws?wsdl得到下图所示  ps:如果测试服务端和客户端不在同一个的机器上则localhost应该是本机的IP地址

2、使用CXF 进行 客户端开发

为客户端加上cxf需要的jar包,否则运行会报错误

这些是使用cxf 里面的工具wsdl2java  生成的java类。在命令行执行下面命令,就可以生成这些类

D:\用户目录\下载\apache-cxf-3.1.15\bin>wsdl2java -p com.webservice http://localhost:8080/studentws?wsdl

如下图所示生成客户端代码成功:在本目录下 com.webservice中

wsdl2java用法:
wsdl2java -p com -d src -all wsdl-p 指定其wsdl的命名空间,也就是要生成代码的包名
-d 指定要产生代码所在目录
-client 生成客户端测试web service的代码
-server 生成服务器启动web service的代码
-impl 生成web service的实现代码
-ant 生成build.xml文件
-all 生成所有开始端点代码:types,service proxy,,service interface, server mainline, client mainline, implementation object, and an Ant build.xml file.

  

把生成的代码放的客户端项目中

编写客户端代码

package com.myl.test.service;import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import com.webservice.StudentWsImpl;/**
* @author myl
* @date 2018年4月15日
* 客户端调用服务端发布的接口
*/
public class StudentSerivceTest { public static void main(String[] args) {
//获取工厂对象
JaxWsProxyFactoryBean jwpfb = new JaxWsProxyFactoryBean();
//加载生成的StudentWsImpl类
jwpfb.setServiceClass(StudentWsImpl.class);
//传入url接口地址
jwpfb.setAddress("http://localhost:5555/studentws?wsdl");
//创建接口对象
StudentWsImpl ws = (StudentWsImpl) jwpfb.create();
//调用接口中的方法
ws.addStudentService("mao", "11", "22");
ws.addStudentService("ya", "15", "23");
ws.queryStudentService("mao");
ws.queryStudentService("ya"); }}

运行客户端如图所示(每个方法中随便输出点东西)

以上即为cxf框架完成webservice的方法

——————————————————————————————-

遇到问题:

1、开始我下载的apache-cxf-3.2.4版本的cxf,运行报错

解决方法:

  应该是cxf版本太高,跟jdk1.8的版本有关,于是换了apache-cxf-3.1.15版本的既可以了

2、cxf(3.1.15) 客户端异常 请使用 @XmlType.name 和 @XmlType.namespace 为类分配不同的名称。

原因是:使用wsdk2java生成客户端文件的时候根据源文件生成了客户端代码,方法名字重复

解决方法

    生成代码的时候 使用 -p  com.webservice重命名报名即可

———

网上找的方法

   (1)最佳方案包名createTask 改成 全部小写 createtask

  (2)或者生成代码的时候 使用 -p  com.service.createtask 重命名报名即可

   (3)第三那种解决方案不建议,把createTask.java中的  @XmlType(name = “CreateTask”, propOrder = {   “arg0”}) 中的name 改成 createTask 即可

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,906
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,430
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,247
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,058
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,690
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,727