WebService 教程(包含项目实践)

article/2025/10/12 20:38:46

情景引入:

时间:早晨 8 : 00 am

小白:起床起床,,,公司又来需求了,你还在睡觉,快点起来~!

我:大惊小怪,又怎么了呢?小白,别一惊一乍的,打扰我的美梦

小白:公司给了个新需求,你还记得,咱们上次做的那个项目吗?

我:记得,怎么了呢?不是都已经上线了吗?

小白:对呀,但是,与我们合作的那个公司,他们想把我们项目里面的物流查询功能,放到他们自己开发的一个系统里面去,说这样方便他们自己进行查询,要不然,老是需要额外登录我们的系统,挺麻烦的,而还要特别的给他们一个账号进行管理。所以,他们的需求就是:让物流查询的功能提供给他们。 

我:意思是他们想跨平台用我们的物流功能呢?

小白:是的,,,快,赶紧想想办法,咱们,总不能又给他们写一套一样的代码嵌入吧,这效率太低了。

我:当然不行了,这样写的话,有很多问题的,而且系统与系统进行了多重嵌入会影响整体的执行。

小白:对呀,所以,那咱们怎么办呢?

我:容我思考思考,针对这样的跨平台问题,其实也挺好解决的,那就是采取WebService的方式,我们将物流查询作为一个WebService,这样只需要他们那边进行相应的规则处理就好了。

小白:WebService??这是一个什么东西呢?有这么神奇,还可以跨平台的吗?

我:当然,这在很多地方其实都用到的,比如天气查询功能,你觉得每个公司都会去写一套这样的代码吗?当然不会。

小白:对哦,要不然这多麻烦,你看像微信公众号里面的那么多服务,都是别人写好的,我们开发都是用一定的规则去解析的。

我:对的,那下面,我来说说,到底什么是WebService和它的功能。

一:WebService简介

(1)简介----百度百科(注意标识的重点)

        Web service是一个平台独立的,低耦合的,自包含的、基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的互操作的应用程序。 [1] 
       Web Service技术, 能使得运行在不同机器上的不同应用无须借助附加的、专门的第三方软件或硬件, 就可相互交换数据或集成。依据Web Service规范实施的应用之间, 无论它们所使用的语言、 平台或内部协议是什么, 都可以相互交换数据。Web Service是自描述、 自包含的可用网络模块, 可以执行具体的业务功能。Web Service也很容易部署, 因为它们基于一些常规的产业标准以及已有的一些技术,诸如标准通用标记语言下的子集XML、HTTP。Web Service减少了应用接口的花费。Web Service为整个企业甚至多个组织之间的业务流程的集成提供了一个通用机制。

(2)WebService三元素

UDDI:UDDI 的目的是为电子商务建立标准;UDDI是一套基于Web的、分布式的、为Web Service提供的、信息注册中心的实现标准规范,同时也包含一组使企业能将自身提供的Web Service注册,以使别的企业能够发现的访问协议的实现标准。---简单点说,就是一套规则,方便使用;

WSDL:Web Service描述语言WSDL 就是用机器能阅读的方式提供的一个正式描述文档而基于XML(标准通用标记语言下的一个子集)的语言,用于描述Web Service及其函数、参数和返回值。因为是基于XML的,所以WSDL既是机器可阅读的,又是人可阅读的。----简单点说,就是使用规则,方便人和机器进行阅读;

SOAP协议:基于Http,基于XML,SOAP即简单对象访问协议(Simple Object Access Protocol),它是用于交换XML(标准通用标记语言下的一个子集)编码信息的轻量级协议。它有三个主要方面:XML-envelope为描述信息内容和如何处理内容定义了框架,将程序对象编码成为XML对象的规则,执行远程过程调用(RPC)的约定。SOAP可以运行在任何其他传输协议上。例如,你可以使用 SMTP,即因特网电子邮件协议来传递SOAP消息,这可是很有诱惑力的。在传输层之间的头是不同的,但XML有效负载保持相同。----简单点说,就是传输协议,方便进行传输;

(3)WebService与Socket的区别(两种通信的方式)

(1) Socket是基于TCP/IP的传输层协议。 
    Webservice是基于HTTP协议传输数据,http是基于tcp的应用层协议。 
    Webservice采用了基于http的soap协议传输数据。
(2)Socket接口通过流传输,不支持面向对象。 
    Webservice 接口支持面向对象,最终webservice将对象进行序列化后通过流传输。 
    Webservice采用soap协议进行通信,不需专门针对数据流的发送和接收进行处理,是一种跨平台的面向对象远程调用技术。
(3)Socket适用于高性能大数据的传输,传输的数据需要手动处理,socket通信的接口协议需要自定义。

二:属于自己的第一个WebService程序

1)服务端代码(Java工程项目即可,而不需要是web项目,因为webservice已经作为了java SE里面自带的内容):

package com.hnu.scw.webservice;
import javax.jws.WebService;
import javax.xml.ws.Endpoint;
/**  * <p>Title: MyFirstWebService.java</p>  * <p>Description: </p>  */
@WebService
public class MyFirstWebService {/*** 定义webservice服务器中的方法* @param content* @return*/public String testWebService(String content){System.out.println("我收到了你发的信息:" + content);return "服务器:我转发信息给你";}public static void main(String[] args){//定义自己的webservice服务器发布的地址String address = "http://localhost:9090/MyFirstWebService"; //这个9090端口随便定义,只要不冲突即可//通过该方法进行发布Endpoint.publish(address, new MyFirstWebService());//打印一句话,表示一下服务器进行了开启System.out.println("my webservcie starting");}
}

温馨提示:1:必须加@WebService注解或者@WebServiceProvider

2:至少有一个方法是public,并且不可以用static 和 final进行修饰;原因很明显,因为webservice就是提供给别人各自进行使用的,而不是保持同一个,所以不能是static ,而对于final修饰的话就是不可继承,这也是没有意义的。大家可以试试,将方法进行修改,看会不会报错。

(2)解析WebService服务器的内容

操作:在cmd命令行中执行:wsimport -s . http://localhost:9090/MyFirstWebService

结果:这样的话,就会在你执行这句话的目录下面生成对应的服务器的代码(包括.class文件和.java文件)

(3)客户端代码(Java工程项目即可):

步骤:

1:首先是把上面得到的代码中的.java文件(请注意,.class文件就不需要)拷贝到我们新建的一个客户端的java项目中

2:编写我们的测试方法

 

温馨提示:可以通过浏览器输入:http://localhost:端口号/发布的服务器名字?wsdl     -----------来查看定义service的wsdl文档

这时候,我们只需要首先运行服务器端的java项目,然后再运行我们客户端的@Test方法,这样就可以得到从服务器中获取到的消息内容了。

三:与WebService服务器进行交互的方式

(1)普通客户端调用

这个的话就不多说了,因为在我们上面的第一个WebService的代码中,就已经是这样的一种调用方式。

(2)ajax调用

 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title><script type="text/javascript">/*思路:1.创建一个XMLHTTP对象2.打开链接open("POST",url)3.设置请求头Content-Type4.设置回调函数,处理返回值5.从返回的XML中解析我们要的内容*/var xmlHttpReqquest = new ActiveXObject("Microsoft.XMLHTTP");//alert(xmlHttpReqquest);//发送SOAP请求function sendMsg(){//获取用户输入的内容var name = document.getElementById("name").value;var url = "http://localhost:9090/MyFirstWebService";//下面的这种格式主要是通过Eclipse下载了一个webservice调式工具,这样就可以看到对应的xml格式内容var requestBody = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:q0=\"http://webservice.scw.hnu.com/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"+ "<soapenv:Body><q0:testWebService><arg0>"+name+"</arg0></q0:testWebService></soapenv:Body></soapenv:Envelope>";xmlHttpReqquest.open("POST", url);xmlHttpReqquest.setRequestHeader("Content-Type","text/xml;charset=utf-8");xmlHttpReqquest.onreadystatechange = _back;xmlHttpReqquest.send(requestBody);}//接收SOAP返回,从返回XML中解析function _back(){//处理完毕,处理成功if(xmlHttpReqquest.readystate==4){		//处理完if(xmlHttpReqquest.status==200){	//成功var xml = xmlHttpReqquest.responseXML;//alert(xml);//获取return标签的第一个var ele = xml.getElementsByTagName("return")[0];alert(ele.text);}else{alert(0);}}}</script>
</head>
<body><input type="text" id="name" name="name" value=""/><input type="button" name="send" value="send" οnclick="sendMsg();"/>
</body>
</html>

(3)URLConnection的调用方式

//创建url地址
URL url = new URL(""http://localhost:9090/MyFirstWebService");
//打开连接
URLConnection conn = url.openConnection();
//转换成HttpURL
HttpURLConnection httpConn = (HttpURLConnection) conn;
//打开输入输出的开关
httpConn.setDoInput(true);
httpConn.setDoOutput(true);
//设置请求方式
httpConn.setRequestMethod("POST");
//设置请求的头信息
httpConn.setRequestProperty("Content-type", "text/xml;charset=UTF-8");
//拼接请求消息
String data = "<soapenv:Envelope xmlns:soapenv=" +"\"http://schemas.xmlsoap.org/soap/envelope/\" " +"xmlns:q0=\"http://server.rl.com/\" " +"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"+"<soapenv:Body>"+"<q0:testWebService>"+"<arg0>my name is scw</arg0> "+"</q0:testWebService>"+"</soapenv:Body>"+"</soapenv:Envelope>";
//获得输出流
OutputStream out = httpConn.getOutputStream();
//发送数据
out.write(data.getBytes());
//判断请求成功
if(httpConn.getResponseCode() == 200){//获得输入流InputStream in = httpConn.getInputStream();//使用输入流的缓冲区BufferedReader reader = new BufferedReader(new InputStreamReader(in));StringBuffer sb = new StringBuffer();String line = null;//读取输入流while((line = reader.readLine()) != null){sb.append(line);}//创建sax的读取器SAXReader saxReader = new SAXReader();//创建文档对象Document doc = saxReader.read(new StringReader(sb.toString()));//获得请求响应return元素List<Element> eles = doc.selectNodes("//return");for(Element ele : eles){System.out.println(ele.getText());}
}

(4)QName调用------------推荐这种方式

package com.hnu.scw.test;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import org.junit.Test;
import com.hnu.scw.webservice.MyFirstWebService;
/**  * <p>Title: MyTestQNameWebService.java</p>  * <p>Description: 通过QName的一种调用方式</p>  */
public class MyTestQNameWebService {@Testpublic void test() throws MalformedURLException{//创建一个连接(地址对应的就是webservice服务器中的地址)URL wsdlDocumentLocation = new URL("http://localhost:9090/MyFirstWebService?wsdl");//这个参数,主要是根据我们设定的webService的接口来进行的QName serviceName = new QName("http://webservice.scw.hnu.com/","MyFirstWebServiceService");Service ws = Service.create(wsdlDocumentLocation , serviceName );//获取到调用的对象内容MyFirstWebService port = ws.getPort(MyFirstWebService.class);//方法的调用String result = port.testWebService("my name is scw");System.out.println(result);}
}

温馨提示:(1)这个方式大体和我们之间进行的客户端调用类型,但是注意一点,在我们的客户端的方式的时候,我们是把所解析得到的.java所有文件都拷贝到客户端程序,而如果用QName的形式,我们只需要保留我们对应WebService类的接口那个即可。比如,如下:

客户端的情况:

QName的情况:

(2)当我们只保留上面的java文件的时候,会出现错误,只需要根据下面进行修改即可;

(3)QName对象的参数是如何知道的?那么久看我们保留的那个接口类中;

(4)通过QName的方式可以很明显的感觉比第一种客户端要好,因为,可以对于端口和链接都有灵活性,而且拷贝的代码也相对较少;

四:关于WebService的部分注解

五:初识CXF框架

     官网:http://cxf.apache.org/

    Apache CXF = Celtix + XFire,开始叫 Apache CeltiXfire,后来更名为 Apache CXF 了,以下简称为 CXF。CXF 继承了 Celtix 和 XFire 两大开源项目的精华,提供了对 JAX-WS 全面的支持,并且提供了多种 Binding 、DataBinding、Transport 以及各种 Format 的支持,并且可以根据实际项目的需要,采用代码优先(Code First)或者 WSDL 优先(WSDL First)来轻松地实现 Web Services 的发布和使用。Apache CXF已经是一个正式的Apache顶级项目。

      Apache CXF 是一个开源的 Services 框架,CXF 帮助您利用 Frontend 编程 API 来构建和开发 Services ,像 JAX-WS 。这些 Services 可以支持多种协议,比如:SOAP、XML/HTTP、RESTful HTTP 或者 CORBA ,并且可以在多种传输协议上运行,比如:HTTP、JMS 或者 JBI,CXF 大大简化了 Services 的创建,同时它继承了 XFire 传统,一样可以天然地和 Spring 进行无缝集成。

六:利用CXF框架来搭建我们的WebService

步骤:

(1)首先去官网下载一个版本http://cxf.apache.org/,现在的话,都是3.2.X版本了,这个根据需要即可;

(2)下载之后,里面就有一个lib的目录,就是关于CXF架构的一些依赖包;

可以去官网下载(或者去博文最后的百度云中下载):http://cxf.apache.org/

(3)创建一个web项目(注意:这时候用了web项目,而之前的开发都是用的Java项目),并且把依赖包都复制到项目中的lib目录中(就和正常的开发web项目一样,在拷贝所有的之后,要把里面的WHICH_JARS这个文件删除,否则会报错

服务端代码:

package com.hnu.scw;
import org.apache.cxf.frontend.ServerFactoryBean;
/*** 基于CXF框架的服务端代码* @author Administrator**/
public class FirstCXFService {/*** web服务的方法* @param name* @return*/public String printReciveInfo(String name){System.out.println("客户端发送过来信息:" + name);return "服务器转发给你了"+ name;}	public static void main(String[] args){ServerFactoryBean serverFactoryBean = new ServerFactoryBean();//设置访问地址serverFactoryBean.setAddress("http://localhost:9090/firstService");//设置实现类serverFactoryBean.setServiceClass(FirstCXFService.class);//启动服务serverFactoryBean.create();}
}

温馨提示:不要运行配置的服务器,而是直接运行main函数即可。。。。。这样就开启可服务器

客户端代码:(同样的还是通过cmd中的命令:wsimport -s .  XXXXXXXXXX (SOAP1.1版本)或者wsdl2java –d . XXXXXXXXXX(SOAP1.2版本) 来生成代码),然后再创建一个工程项目,并把生成的.java文件拷贝进去。

 

 

package com.hnu.scw.test;
import org.junit.Test;
import com.hnu.scw.FirstCXFService;
import com.hnu.scw.FirstCXFServicePortType;
/*** 测试CXF框架的客户端* @author Administrator**/
public class CXFClientTest {@Testpublic void printTest(){FirstCXFService firstCXFService = new FirstCXFService();FirstCXFServicePortType firstCXFServicePort = firstCXFService.getFirstCXFServicePort();String result = firstCXFServicePort.printReciveInfo("my name is scw");System.out.println(result);}
}

七:面向接口的编写WebService服务

接口:

package com.hnu.scw;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.ws.BindingType;
import javax.xml.ws.soap.SOAPBinding;
@WebService(serviceName="HelloServer")
@BindingType(value=SOAPBinding.SOAP12HTTP_BINDING)			
public interface FirstServer {@WebMethod(operationName="sayHello")@WebResult(name="returnMsg")public String printReciveInfo(@WebParam(name="name")String name);
}

服务器端实现类:

package com.hnu.scw;
import org.apache.cxf.frontend.ServerFactoryBean;
/*** 基于CXF框架的服务端代码* @author Administrator**/
public class FirstCXFService implements FirstServer{/*** web服务的方法* @param name* @return*/public String printReciveInfo(String name){System.out.println("客户端发送过来信息:" + name);return "服务器转发给你了"+ name;}public static void main(String[] args){ServerFactoryBean serverFactoryBean = new ServerFactoryBean();//设置访问地址serverFactoryBean.setAddress("http://localhost:9090/firstService");//设置接口serverFactoryBean.setServiceClass(FirstServer.class);//设置实现类serverFactoryBean.setServiceBean(new FirstCXFService());//启动服务serverFactoryBean.create();}
}

客户端类型的方法就不多说了,只是需要重新编译下载服务端的代码即可。

八:在WebService服务端添加输入输出监控日志

 方法:其实很简单,就是添加一些默认的拦截器就可以了

服务端代码:

package com.hnu.scw;
import org.apache.cxf.frontend.ServerFactoryBean;
/*** 基于CXF框架的服务端代码* @author Administrator**/
public class FirstCXFService {/*** web服务的方法* @param name* @return*/public String printReciveInfo(String name){System.out.println("客户端发送过来信息:" + name);return "服务器转发给你了"+ name;}	public static void main(String[] args){ServerFactoryBean serverFactoryBean = new ServerFactoryBean();//设置访问地址serverFactoryBean.setAddress("http://localhost:9090/firstService");//设置实现类serverFactoryBean.setServiceClass(FirstCXFService.class);//拦截器serverFactoryBean.getInInterceptors().add(new LoggingInInterceptor());		//拦截请求的链接,打印相关信息(谁调用)serverFactoryBean.getOutInterceptors().add(new LoggingOutInterceptor());		//拦截响应的链接,打印相关信息(返回)//启动服务serverFactoryBean.create();}
}

九:设置WebService的版本是采取SOAP1.2版本

   在前面有说过,JDK是默认支持SOAP1.1版本的,而现在也有1.2版本,那如何将我们的WebService转变成1.2版本的呢?其实很简单,只需要添加一个注解即可:(如果采取的是接口编程,那么就放在接口名上即可)

@BindingType(value=SOAPBinding.SOAP12HTTP_BINDING)

小知识:SOAP1.1和SOAP1.2的区别:

1)命名空间

2)标签变化

温馨提示:在开发中如果使用SOAP1.2实现WebService,在生成本地调用代码时,应该使用CXF提供wsdl2java命令。如果使用SOAP1.1实现WebService,在生成本地调用代码时,应该使用jdk提供wsimport命令。在实际项目中目前尽量使用SOAP1.1版本;

十:CXF和Spring框架的整合(重点知识)

步骤:

(1)导包:将下载下来的CXF中的lib目录中jar导入到web项目中的WEB-INF目录下的lib中(同样,还是需要将其中的WHICH_JARS这个文件删除,否则会报错),不需要额外导入Spring的包,因为在CXF的lib中已经包含有Spring的jar包,这个自己可以进行查看;

(2)创建WebService的类;

比如:

package com.hnu.scw.webservice;
import javax.jws.WebService;
/*** 创建一个webservice服务类* @author scw**/
@WebService
public class MyWebService {/*** 创建WebService的调用方法* @param content* @return*/public String hiMyService(String content){System.out.println("客户端发送过来了:" + content);return "服务器返回:"+ content ;}
}

(3)在WEB-INF目录下面创建一个cxf-servlet.xml-------------------这个就是对于webservice的管理

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"><import resource="classpath:META-INF/cxf/cxf.xml"/><import resource="classpath:META-INF/cxf/cxf-servlet.xml"/><!-- 加载提供的服务 --><jaxws:endpoint id="helloService" address="/mywebservice" implementor="com.hnu.scw.webservice.MyWebService"></jaxws:endpoint>
</beans>

(4)修改web.xml文件内容,将WebService的cxf-servlet.xml进行管理

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee           http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"><display-name>cxf</display-name> <!-- 配置cxf框架 cxf-servlet.xml --><servlet><servlet-name>cxf</servlet-name><servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class></servlet><servlet-mapping><servlet-name>cxf</servlet-name><!-- 这里配置只针对/cxf/的这样链接进行管理,因为如果也配置成/*这样的话,也是可以,这只是更加便于管理而已 --><url-pattern>/cxf/*</url-pattern></servlet-mapping>
</web-app>

(5)启动tomcat项目,测试CXF的配置是否成功

(6)配置Spring的配置文件中的beans.xml,专门进行bean的内容的管理(在项目的src下即可,这和Spring开发没什么不同)

主要是为了将WebService的类放入到Spring中进行管理

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd "><bean id="myWebService" class="com.hnu.scw.webservice.MyWebService"></bean>	 <!--这就是我的webservice类的路径-->	
</beans>			

(7)修改之前的cxf-servlet.xml中的内容

原因:因为现在我们的bean放入到了Spring中进行管理,所以,我们直接引用Spring中的bean即可

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"><import resource="classpath:META-INF/cxf/cxf.xml"/><import resource="classpath:META-INF/cxf/cxf-servlet.xml"/><!-- 加载提供的服务 ,注意看此时的implementor标签的写法,#表示的是引用Spring中的bean内容--><jaxws:endpoint id="helloService" address="/mywebservice" implementor="#myWebService"></jaxws:endpoint>
</beans>

(8)修改web.xml内容,将Spring放入到容器进行管理

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee           http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"><display-name>cxf</display-name><!-- 配置spring框架 beans.xml --><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:beans.xml</param-value></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!-- 配置cxf框架 cxf-servlet.xml --><servlet><servlet-name>cxf</servlet-name><servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class></servlet><servlet-mapping><servlet-name>cxf</servlet-name><!-- 这里配置只针对/cxf/的这样链接进行管理,因为如果也配置成/*这样的话,也是可以,这只是更加便于管理而已 --><url-pattern>/cxf/*</url-pattern></servlet-mapping>
</web-app>

(9)启动tomcat,进行测试是否整合成功

总结:通过上面的步骤,我们的整合已经成功了,但是大家可能发现有很多地方不是很好,比如我们的cxf-servlet.xml是放在WEB-INF目录下,那么我们应该也像配置Spring的配置文件一样,放在src下这样的话将会更加好,所以,我们进行下面的修改

 (10)修改cxf-servlet.xml的加载路径----------这样我们就可以把这个xml放到src目录下了

 <!-- 配置cxf框架 cxf-servlet.xml --><servlet><servlet-name>cxf</servlet-name><servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class><!-- 配置cxf-servlet.xml的寻找的位置 --><init-param><param-name>config-location</param-name><param-value>classpath:cxf-servlet.xml</param-value></init-param></servlet><servlet-mapping><servlet-name>cxf</servlet-name><!-- 这里配置只针对/cxf/的这样链接进行管理,因为如果也配置成/*这样的话,也是可以,这只是更加便于管理而已 --><url-pattern>/cxf/*</url-pattern></servlet-mapping>

--------------------------------------------------------------------------------------------

项目整体结构如下:

------------------------------------------------------------------------------------------------

十一:项目实践

前提内容:这是一个比较经典的物流供应项目,网上可以找到源码的。只不过,既然我们学得是WebService,那么肯定就要进行相应的改造的,所以,针对里面的一个物流查询模块,来设计成为一个能够让其他系统都能调用的功能(这样,情景引入的问题是不是就解决了)。

描述:针对项目中的,物流查询模块改造成一个WebService服务,方便其他的模块或者系统进行相应的使用,实现一种跨平台的功能。

步骤:

环境:eclipse + maven + mysql (其他的编辑器什么的都行,这个完全根据自身习惯即可,没有要求)

(1)导入项目内容--------这个不多说,就是导入maven项目,然后把相应的数据库内容在本地生成即可(都在我的百度云里面了)

(2)查看原始内容(重点关注我标识的部分,也就是我们要进行改造的类)

 

我们就改造下面这个方法:这个方法的功能就是,通过物流的ID,来查询到它的物流信息

提示:大家稍微看一下这个类,基本了解是干嘛的就可以了哈~~

改造其类为WebService类步骤(重点来了):

(1)将需要修改为WebService的类,添加注解 @WebService进行标识

(2)添加操作对应的DAO类的额外bean依赖

        //给WebService使用@WebMethod(exclude=true)public void setExportDao(ExportDao exportDao) {this.exportDao = exportDao;}

分析:

1:添加@WebMethod(exclude=true)的作用:防止给调用者看到这个方法,因为这个方法只是给spring来进行注入bean依赖的;

2:大家可能注意到一个问题了,在spring开发中,

我们一般是这样。

但是,千万注意一下,这个也是要的,而为什么又多了一个set注入,是因为,这是专门用户webservice注入的,所以,一定要区分开原因,所以这两者都是需要存在的。也就是下面的这样的代码:

//给spring service使用dao@ResourceExportDao exportDao;//给WebService使用@WebMethod(exclude=true)public void setExportDao(ExportDao exportDao) {this.exportDao = exportDao;}

(3)将其他不进行提供webservice调用的方法进行注解屏蔽,而只保留webservice能够调用的方法。如下所示:

@WebMethod(exclude=true)public List<Export> find(Map paraMap) {return exportDao.find(paraMap);}//WebService调用public Export get(String id) {return exportDao.get(id);}

(4)添加cxf-servlet.xml文件

目录:

cxf-servlet.xml添加的内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"><import resource="classpath:META-INF/cxf/cxf.xml"/><import resource="classpath:META-INF/cxf/cxf-servlet.xml"/><!-- 发布WebService 参数:访问地址address,实现类 implementor --><bean id="exportService" class="cn.itcast.jk.service.impl.ExportServiceImpl"><property name="exportDao" ref="exportDaoImpl"/></bean><jaxws:endpoint address="/ExportServiceImpl" implementor="#exportService"/>
</beans>

分析:现在再回头看一下第(2)步中,额外添加的set注入,是不是就明白原因了呢?这上面的知识都是我上面讲过的,所以,不懂的就回头再去看看吧。

(5)修改web.xml,添加对cxf-servlet.xml的加载

<!-- 3.webService CXF --><servlet><servlet-name>cxf</servlet-name><servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class><init-param><param-name>config-location</param-name><param-value>classpath:cxf-servlet.xml</param-value></init-param></servlet><servlet-mapping><servlet-name>cxf</servlet-name><url-pattern>/cxf/*</url-pattern></servlet-mapping>

(6)在pom.xml中添加对CXF框架的依赖

<!-- 整合CXF WebService框架 --><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-frontend-jaxws</artifactId><version>3.0.2</version></dependency><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-transports-http</artifactId><version>3.0.2</version></dependency>

分析:通过上面的步骤,基本上就改造完成了,那么下面就来进行实际的使用:(这里通过ajax的形式来进行,也是我们开发中用的相对较多的方式)

(7)ajax来调用webservice类的形式

具体的内容:大家就看代码中:src\main\webapp\WEB-INF\pages\cargo\export目录下的ajaxExport.jsp页面内容吧

(8)进行测试。(当然,这个最好是在整合完成CXF和Spring,即改造完webservice类的时候就测试一下比较好)

针对这个项目的话,我把最初的项目源码和改造后的代码以及数据库内容,两个版本的都放入了百度云,而且把该博文中相关的代码都放入了这里面,供大家进行下载。

链接:https://pan.baidu.com/s/1_exUqQeg3h2OwGFhDa2dmg          密码:60fq


http://chatgpt.dhexx.cn/article/WO4D1KXp.shtml

相关文章

最详细的idea创建webservice教程

最详细的idea创建webservice教程 创建服务端 File->New Project 点击next&#xff0c;会自动生成demo将要发布的类加上WebService&#xff0c;方法加上WebMethod&#xff0c;设置服务发布address WebService() public class HelloWorld {WebMethodpublic String sayHello…

WebService简单入门

1. JAX-WS发布WebService 创建web工程 创建simple包&#xff0c;和server、client两个子包。正常情况下server和client应该是两个项目&#xff0c;这里我们只是演示效果&#xff0c;所以简化写到一个项目中&#xff1a; 1.1 创建服务类Server package simple.server;import ja…

WebService教程实例

一、准备工作 1、Myeclipse 2014 2、jdk8.0 二、创建服务端 1、创建【Web Service Project】&#xff0c;命名为【TheService】。 2、创建【Class】类&#xff0c;命名为【ServiceHello】&#xff0c;位于【com.hyan.service】包下。 3、编写供客户端调用的方法&#xff0c;即编…

Java小白翻身 - webservice教程2

来一个HelloWorld&#xff0c;SpringBoot发布WebService可简单啦。 1、搭建项目2、配置pom.xml3、建services服务包4、登陆接口类5、登陆接口实现类6、创建CXF配置类7、Parameter 0 of method errorPageCustomizer in ErrorMvcAutoConfiguration 异常解决8、访问webservice9、…

idea2021创建webservice教程

一、创建服务端 1、创建一个新的java工程 2、工程项目右键添加框架依赖 3、选择webservices 4、点击确定完成创建。创建后项目会添加相关依赖。以及测试服务类。 5、代码介绍 // 添加WebService注解 WebService() public class HelloWorld {// 方法添加WebMethod注解W…

WebService教程

最近在学习WebService&#xff0c;今天尝试用Eclipse的插件生成JAX-WS WebService&#xff0c;结果遇到了不少的问题啊&#xff0c;调试了大半天终于把程序跑通了。现在把步骤和问题记录一下&#xff0c;也为了以后遇到相同的问题时能够及时解决。首先利用Eclipse生成WebServic…

WebService入门教程(服务端发布WebService)

本篇内容过多&#xff0c;时间紧迫的朋友可以通过目录快速筛选自己想要看的内容&#xff0c;本人接触webservice也没多久&#xff0c;也处于学习阶段&#xff0c;如果有错误请指正&#xff0c;如果已经是大神请略过这篇文章&#xff0c;这篇文章不涉及webservice的底层原理&…

WebService最详细教程

WebService相关概念 基础概念 WebService是一种跨编程语言和跨操作系统平台的远程调用技术,就是说服务端程序采用java编写&#xff0c;客户端程序则可以采用其他编程语言编写&#xff0c;反之亦然&#xff01;跨操作系统平台则是指服务端程序和客户端程序可以在不同的操作系统…

webSerivce简明使用教程

茫茫人海千千万万&#xff0c;感谢这一秒你看到这里。希望我的文章对你的有所帮助&#xff01; 愿你在未来的日子&#xff0c;保持热爱&#xff0c;奔赴山海&#xff01; &#x1f440; 前言 因为前段时间&#xff0c;需要使用到webService来调用公司的其他系统api接口&#x…

WebService详细讲解

1 学习目标2 webservice 基本概念 2.1 什么是web服务2.2 简介2.3 术语 2.3.1 webservice开发规范2.3.2 SOAP 协议2.3.3 wsdl说明书2.3.4 UDDI2.4 应用场景2.5 优缺点 2.5.1 优点&#xff1a;2.5.2 缺点&#xff1a;2.6 面向服务架构SOA3 ApacheCXF 框架介绍 3.1…

11步教你入门webservice

新建立一个javaWeb项目&#xff0c;一个java类&#xff0c;如图&#xff1a; 1.具体很简单 首先要创建一个web工程 2、接下来我们就要将项目中的TestService的这个类生成WebService服务端&#xff0c;选择new Web Service&#xff0c;如图&#xff1a; 3 4.Next,选择jav…

php 实现分页功能(class封装了功能)

前言 分页是一个很常见的功能&#xff0c;我这里提供了分类类(class)&#xff0c;用于前端页面中的四个按钮&#xff1a; 首页下一页上一页尾页 上面的演示非常不直观&#xff0c;但足可以证明这个类可以完成分页功能。 完整的代码 附有非常详细的注释&#xff0c;但需要有…

PHP分页技术详解

直接上代码&#xff0c;注释很详细了。 <?php /** * php分页技术详解 * author jahng */header("Content-type: text/html; charsetUTF-8");echo<link rel"stylesheet" type"text/css" href"css.css" media"all" /&g…

PHP的分页处理

HTML页面&#xff1a; <div class"page"> {$data->render()|raw} </div> 控制器页面&#xff1a; $data ArticleInfo:: where(cate_id, $this->cid)->whereLike(title,%.$get.%)->paginate([ query>[cid>$this->cid], l…

php分页

这是学生信息管理每三条一页> <?phpfunction news($pageNum 1, $pageSize 3){$array array();$mysqlnew mysql();$rs "select * from user limit " . (($pageNum - 1) * $pageSize) . "," . $pageSize;$r $mysql->query($rs);while ($obj…

PHP-分页

1.6 分页 1.6.1 分析 -- 1、获取当前页码的数据 页码 SQL语句 1 select * from products limit 0,10 2 select * from products limit 10,10 3 select * from products limit 20,10 结论&#xff1a; $pageno&#xff1a;页码 $startno:起始位置 $pagesize10:页面大小…

PHP分页查询

1、创建Page.php类&#xff0c;代码如下&#xff1a; <?php /*** 分页模板类*/ class Page {private $cur_page;//当前页private $total;//总条数private $page_size 10;//每页显示的条数private $total_page;//总页数private $first_page;//首页显示名称private $pre_pa…

全功能PHP分页条

网上可以找到的ASP、PHP分页条很多。我也不能免俗&#xff0c;发表一个献献丑。唯一聊以自慰的是这个分页条能生成的显示样式还是很多的&#xff0c;相信能满足大部分人的需要。另一个特点就是使用特别简单&#xff0c;一般传递两个参数即可使用。文档里有使用样例和效果图。发…

php原生分页

自己写一个原生php分页&#xff1a; <?php $linkMySQL_connect(localhost,用户名,密码); mysql_select_db(数据库名称,$link); mysql_query(set names utf8); $resultmysql_query("select * from 表名"); $count mysql_num_rows($result); $Page_size10; …

如何用php实现分页效果

分页效果在网页中是常见的,可是怎样才能实现分页呢,今天做了两种方法来实现一下分页的效果 首先,我们需要准备在数据库里面准备一个表,并且插入数据,这些都是必需的前提工作了,不多说,如图所示(库名为jereh,表名为n_content): 步骤分析: 我们需要分页的话,需要用…