web(World Wide Web)即全球广域网,也称为万维网,它是一种基于超文本和HTTP的、全球性的、动态交互的、跨平台的分布式图形信息系统。是建立在Internet上的一种网络服务,为浏览者在Internet上查找和浏览信息提供了图形化的、易于访问的直观界面,其中的文档及超级链接将Internet上的信息节点组织成一个互为关联的网状结构。
服务(service)既然是服务必然是谁服务谁,在网络中一般指 服务的调用者(请求|客户端)服务的提供者(响应|服务端)。
Web服务是通过万维网( WWW )超文本传输协议( HTTP )进行通信的客户端和服务器应用程序。 如万维网联盟(W3C)所述,Web服务提供了在各种平台和框架上运行的软件应用程序之间进行互操作的标准方法。
Web服务可以看作是按需的代码 。 就像我们调用函数和方法一样,Web服务可以看作是使用某种协议和某些协议通过Internet调用函数或方法。
Web服务是一种函数或方法,可以通过将HTTP请求发送到带有参数的URL来调用该函数或方法,然后该服务将结果作为响应返回。
Web服务的最大优点是它与平台无关。
考虑上图,我们可以看到用Java编写的应用程序可以通过Web服务与PHP和.net平台进行交互。 因此,它是完全独立于平台的。 PHP公开的Web服务可以被任何平台使用,无论是Java,.net还是PHP。 Web服务的这种功能使其变得如此流行。 因此,Web服务是一种独立于语言的通信方式。
协议?
请求行
请求头
请求体
响应状态行:响应码 响应状态
响应头
响应体:浏览器解析前的页面文件
约束?
规范?
都有什么标签?
如何引入Schema约束?
跨平台跨语言的远程调用技术,适用于不同系统不同语言的数据交互数据传输
Web Service 可以适用于应用程序集成、软件重用、跨防火墙通信等需求。不同的 业务要求不同。
具体如下:
(1) 跨防火墙通信
(2) 应用系统集成 (3) 软件和数据重用 简单来说,如果一个功能,需要被多个系统使用可以使用webservice开发一个服务 端接口,供不同的客户端应用。主要应用在企业内部系统之间的接口调用、面向公网的 webservice服务。
优点:
a) 异构平台的互通性 理论上, Web Service 最大的优势是提供了异构平台的无缝街接技术手段。由于不同的 用户使用不同的硬件平台,不同的操作平台,不同的操作系统,不同的软件,不同的协 议通信,这就产生了互相通信的需求。 Web Service 使任何两个应用程序,只要能读写 XML,那么就能互相通信。
b) 更广泛的软件复用(例如手机淘宝可以复用已有淘宝的业务逻辑.) 软件的复用技术通过组合已有模块来搭建应用程序,能大幅度提高软件的生产效率和质 量。用户只要获得了描述 Web Service 的 WSDL 文件,就可以方便地生成客户端代理, 并通过代理访问 Web Service 。
c) 成本低、可读性强、应用范围广 Web Service 可用基于 XML 的 SOAP 来表示数据和调用请求。并且通过 HTTP 协议传输 XML 格式的数据
d) 迅捷的软件发行方式 (每个web Service称为一个生产者.不同的生产者可以相互协同合作完成整个应用) Web Service 将彻底地改变软件的发行方式。软件供应商可以把软件分解成若Web Service 模块构成的系统,直接在 Web 上发布。
e) 最重要的一点 客户端与服务端可能是用不同的语言开发的,但是,通过webservice提供服务接口,客 户端与服务端之前可以传递对象。
缺点: 由于soap是基于xml传输,本身使用xml传输会传输一些无关内容从而影响效率,随着 soap协议的完善,soap协议增加了许多内容,这样就导致了使用soap去完成简单的数据 传输而携带的信息更多效率再受影响;
Web Service作为web跨平台访问的标准技术,很多公司都限定要求使用Web Service, 但如果是简单的接口可以直接使用http传输自定义数据格式,开发更快捷。
WebServer响应是:HTLM + XML
所以XML解析得看看!
Web Service描述语言WSDL(SebService Definition Language)就是用 机器能阅读的语言 方式提供的一个正式描述文档而基于XML(标准通用标记语言下的一个子集)的语言, 用于描述Web Service及其函数、参数和返回值。因为是基于XML的,所以WSDL既是机器可阅读的,又是人可阅读的。
wsdl说明书,
1) 通过wsdl说明书,就可以描述webservice服务端对外发布的服务;
2) wsdl说明书是一个基于xml文件,通过xml语言描述整个服务;
3) 在wsdl说明中,描述了: 对外发布的服务名称(类) 接口方法名称(方法) 接口参数(方法参数) 服务返回的数据类型(方法返回值)
SOAP = 在HTTP的基础上+XML数据
SOAP即简单对象访问协议(Simple Object Access Protocol),它是用于交换 XML(标准通用标记语言下的一个子集)编码信息的轻量级协议。
SOAP作为一个基于XML语言的协议用于有网上传输数据,SOAP可以运行在任何其他传输协议上。
SOAP的组成 :
是服务接口类+Service后缀,Service是自动追加的。如图:
Web 服务提供商又如何将自己开发的 Web 服务公布到因特网上, 这就需要使用到 UDDI 了,UDDI的话,是一个跨产业,跨平台的开放性架构,可以帮助 Web 服务提供商在互联网上发布 Web 服务的信息。 UDDI 是一种目录服务,企业可以通过 UDDI 来注册和搜索 Web 服务。 简单来时候话,UDDI 就是一个目录,只不过在这个目录中存放的是一些关于 Web 服务 的信息而已。 并且 UDDI 通过SOAP 进行通讯,构建于 . Net 之上。 UDDI 即 Universal Description,Discovery andIntegration,也就是通用的描述,发现 以及整合。 UDDI 的目的是为电子商务建立标准;UDDI是一套基于Web的、分布式的、为 WebService提供的、信息注册中心的实现标准规范,同时也包含一组使企业能将自身提 供的Web Service注册,以使别的企业能够发现的访问协议的实现标准。
SOA(Service-OrientedArchitecture)面向服务架构是一种思想,它将应用程序的不同功 能单元通过中立的契约(独立于硬件平台、操作系统和编程语言)联系起来,使得各种 形式的功能单元更好的集成。目前来说,WebService 是SOA 的一种较好的实现方 WebService 采用HTTP 作为传输协议,SOAP(Simple Object Access Protocol)作为传 输消息的格式。但WebService 并不是完全符合SOA 的概念,因为SOAP 协议是 WebService 的特有协议,并未符合SOA 的传输协议透明化的要求。SOAP 是一种应用协 议,早期应用于RPC 的实现,传输协议可以依赖于HTTP、SMTP 等。
SOA 的产生共经历了如下过程:
通常采用SOA的系统叫做服务总线(BUS),结构如下图所示:
*前面都是概念理论,下面是代码实践部分。*
JAXB = Java Api for Xml Binding
JAXB是Java Architecture for XML Binding的缩写,提供了一个快捷的方式将Java对象与XML进行转换。
JAXB可以实现POJO对象和XML之间相互转换,Unmarshaller类可以将XML数据反序列化为Java的POJO对象,并可在解组时有选择的验证XML数据;Marshaller类是将Java的POJO对象序列化为XML数据的过程。
package com.wind.jaxb;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;
/**
* JAXB 示例Demo
*
* @author Wind
*/
public class JaxbTest {
public static void myMarshaller() throws JAXBException {
JAXBContext jaxbContext = JAXBContext.newInstance(Book.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // 格式化
marshaller.setProperty(Marshaller.JAXB_ENCODING, "utf-8"); // 设置编码
marshaller.marshal(new Book(11, "斗罗大陆", 33.8), System.out);
}
public static void myUnMarshaller() throws JAXBException {
String xmlString = "斗罗大陆 11 33.8 ";
JAXBContext jaxbContext = JAXBContext.newInstance(Book.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Book book = (Book) unmarshaller.unmarshal(new StringReader(xmlString));
System.out.println(book);
}
public static void main(String[] args) throws JAXBException {
myMarshaller();
System.out.println();
System.out.println("---------------------------------");
myUnMarshaller();
}
}
服务端开发完后客户端如何编码调用?全手写麻烦否?
D:\DevSoft\ApacheCXF\apache-cxf-3.4.4\bin>wsdl2java http://localhost:8001/cxf/server?wsdl
package com.wind.test;
import com.wind.cxf.HelloWorld;
import com.wind.cxf.HelloWorldImplService;
/**
* 测试 根据WSDL地质生成的Java客户端代码
*
* @author Wind
*/
public class WsdlToJavaTest {
public static void main(String[] args) {
HelloWorld helloWorld = new HelloWorldImplService().getHelloWorldImplPort();
String result = helloWorld.sayHello("张无忌", 18);
System.out.println(result); // CXF sayHello:寮犳棤蹇� 18 ???为什么会乱码
// 对上面生成的Java客户端代码调用 中文乱码的解决办法:
// 生成时添加编码设置:D:\DevSoft\ApacheCXF\apache-cxf-3.4.4\bin>wsdl2java -encoding utf-8 http://localhost:8001/cxf/server?wsdl
}
}
IDEA中打单独文件的jar包,太麻烦了 放弃了~
使用Eclipse打jar包:
1)选中要打成jar包的.java文件
2)右键 —> 导出(Export) —> Java–JAR file —> 一直Next
Axis(Apache eXtensible Interation System)阿帕奇可扩展交互系统,是一款开源的WebService运行引擎,本质上就是一个SOAP引擎,提供创建服务器端、客户端和网关SOAP操作的基本框架。
Axis分为1.x系列和2.x系列,两个系列 体系结构和上用上有较大区别,相对而言 Axis1.x更加稳定,文档也比较齐全。
XFire是下一代的Java SOAP框架,XFire提供了非常方便的API,使用这些API可以开发面向服务(SOA)的程序。它支持各种标准,性能优良(基于低内存的STAX模型)。
Apache CXF = Celtix + XFire
Apache CXF的前身叫Apache CeltiXfire,现在已经正式更名为Apache CXF,简称为CXF。CXF继承了Celtix和XFire两大开源项目的精华,提供了对JAX-WS全面的支持,并且提供了多种Binding、DataBinding、Transport以及各种Format的支持,并且可以根据实际项目的需要,采用代码优先(Code First)或者WSDL优先(WSDL First)来轻松地实现WebService的发布和使用。Apache CXF已经是一个正式的Apache顶级项目。
package com.wind.cxf;
import javax.jws.WebService;
/**
* 对外暴漏的接口
*
* @author Wind
* @date 2021-10-28 02:25:34
*/
@WebService
public interface HelloWorld {
/**
* 测试方法 sayHello
*
* @param name 姓名
* @param age 年龄
* @return
*/
String sayHello(String name, int age);
}
package com.wind.cxf;
/**
* 接口实现类
*
* @author Wind
* @date 2021-10-28 02:25:56
*/
public class HelloWorldImpl implements HelloWorld {
@Override
public String sayHello(String name, int age) {
System.out.println("sss");
return "CXF\tsayHello:" + name + "\t" + age;
}
}
package com.wind.cxf;
import org.apache.cxf.endpoint.Server;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
/**
* WebService服务启动类
*
* @author Wind
* @date 2021-10-28 02:24:51
*/
public class MainServer {
public static void main(String[] args) {
JaxWsServerFactoryBean factoryBean = new JaxWsServerFactoryBean();
factoryBean.setAddress("http://localhost:8001/cxf/server");
factoryBean.setServiceClass(HelloWorldImpl.class);
Server server = factoryBean.create();
server.start();
}
}
package com.wind.cxf;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
/**
* 编写测试代码ClientTest调用对外暴漏的服务(JaxWsProxyFactoryBean)
*
* @author Wind
* @date 2021-10-28 02:24:01
*/
public class ClientTest {
public static void main(String[] args) {
JaxWsProxyFactoryBean factoryBean = new JaxWsProxyFactoryBean();
factoryBean.setAddress("http://localhost:8001/cxf/server");
factoryBean.setServiceClass(HelloWorld.class);
HelloWorld helloWorld = (HelloWorld) factoryBean.create();
String result = helloWorld.sayHello("张三", 23);
System.out.println("*************" + result);
}
}
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.windgroupId>
<artifactId>01_jaxws_serverartifactId>
<version>1.0-SNAPSHOTversion>
<name>01_jaxws_servername>
<url>http://www.example.comurl>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<maven.compiler.source>1.7maven.compiler.source>
<maven.compiler.target>1.7maven.compiler.target>
properties>
<dependencies>
<dependency>
<groupId>org.apache.cxfgroupId>
<artifactId>cxf-rt-frontend-jaxwsartifactId>
<version>3.0.1version>
dependency>
<dependency>
<groupId>org.apache.cxfgroupId>
<artifactId>cxf-rt-transports-http-jettyartifactId>
<version>3.0.1version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-log4j12artifactId>
<version>1.7.12version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.10version>
<scope>testscope>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>3.2version>
<configuration>
<source>1.8source>
<target>1.8target>
<encoding>UTF-8encoding>
<showWarnings>trueshowWarnings>
configuration>
plugin>
plugins>
build>
project>
package com.wind.service;
import javax.jws.WebService;
/**
* WebService 接口
*
* @author Wind
* @date 2021-10-29 18:07:18
*/
@WebService
public interface UserService {
/**
* 示例Demo
*
* @param name 姓名
* @return
*/
String sayHi(String name);
}
package com.wind.service.impl;
import com.wind.service.UserService;
/**
* WebService 接口实现类
*
* @author Wind
* @date 2021-10-29 18:10:43
*/
public class UserServiceImpl implements UserService {
@Override
public String sayHi(String name) {
return name + "Say Hello";
}
}
package com.wind.publish;
import com.wind.service.impl.UserServiceImpl;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
/**
* 服务端 发布服务
*
* @author Windy
* @date 2021-10-29 18:16:15
*/
public class Server {
public static void main(String[] args) {
// 服务工厂
JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
// 设置服务地址
factory.setAddress("http://localhost:8000/user");
// 设置服务类
factory.setServiceBean(new UserServiceImpl());
// 发布服务
factory.create();
// 提示
System.out.println("服务端启动");
}
}
与服务端项目依赖一致
也与服务端接口一致
package com.wind.service;
import javax.jws.WebService;
/**
* WebService 接口
*
* @author Wind
* @date 2021-10-29 18:07:18
*/
@WebService
public interface UserService {
/**
* 示例Demo
*
* @param name 姓名
* @return
*/
String sayHi(String name);
}
package com.wind.test;
import com.wind.service.UserService;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
/**
* 客户端 远程服务调用
*
* @author Windy
* @date 2021-10-29 18:58:21
*/
public class Client {
public static void main(String[] args) {
// 服务端接口访问地址:http://localhost:8000/user?wsdl
// 1. 创建cxf代理工程对象
JaxWsProxyFactoryBean factoryBean = new JaxWsProxyFactoryBean();
// 2. 设置远程访问服务端地址
factoryBean.setAddress("http://localhost:8000/user"); // 传接口地址或者接口wsdl文档地址都可以
// 3. 设置接口类型
factoryBean.setServiceClass(UserService.class);
// 4. 对接口生成代理对象
UserService userService = factoryBean.create(UserService.class);
// 代理对象类型:【Java代理分为:1、静态代理 2、动态代理(jdk接口代理{Proxy@}、CGLB子类代理{CGLB@})】
System.out.println(userService); // org.apache.cxf.jaxws.JaxWsClientProxy@2e222612
// 5. 远程访问
String result = userService.sayHi("王昭君");
System.out.println(result);
}
}
# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=info, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:\axis.log # 日志生成目录
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
package com.wind.publish;
import com.wind.service.impl.UserServiceImpl;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
/**
* 服务端 发布服务
*
* @author Windy
* @date 2021-10-29 18:16:15
*/
public class Server {
public static void main(String[] args) {
// 1. 服务工厂
JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
// 2. 设置服务地址
factory.setAddress("http://localhost:8000/user");
// 3. 设置服务类
factory.setServiceBean(new UserServiceImpl());
// 添加日志输入、输出拦截器,观察SOAP请求、SOAP响应内容
factory.getInInterceptors().add(new LoggingInInterceptor());
factory.getOutInterceptors().add(new LoggingOutInterceptor());
// 4. 发布服务
factory.create();
// 提示
System.out.println("服务端启动");
}
}
2021-10-29 19:44:39,278 27370 [tp1297502382-22] INFO serServiceImplPort.UserService - Inbound Message
----------------------------
ID: 1
Address: http://localhost:8000/user
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml; charset=UTF-8
Headers: {Accept=[*/*], Cache-Control=[no-cache], connection=[keep-alive], Content-Length=[191], content-type=[text/xml; charset=UTF-8], Host=[localhost:8000], Pragma=[no-cache], SOAPAction=[""], User-Agent=[Apache CXF 3.0.1]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHi xmlns:ns2="http://service.wind.com/"><arg0>王昭君arg0>ns2:sayHi>soap:Body>soap:Envelope>
--------------------------------------
2021-10-29 19:44:39,440 27532 [tp1297502382-22] INFO serServiceImplPort.UserService - Outbound Message
---------------------------
ID: 1
Response-Code: 200
Encoding: UTF-8
Content-Type: text/xml
Headers: {}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHiResponse xmlns:ns2="http://service.wind.com/"><return>王昭君 Say Helloreturn>ns2:sayHiResponse>soap:Body>soap:Envelope>
--------------------------------------
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.windgroupId>
<artifactId>03_jaxws_spring_serverartifactId>
<version>1.0-SNAPSHOTversion>
<packaging>warpackaging>
<name>03_jaxws_spring_server Maven Webappname>
<url>http://www.example.comurl>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<maven.compiler.source>1.7maven.compiler.source>
<maven.compiler.target>1.7maven.compiler.target>
properties>
<dependencies>
<dependency>
<groupId>org.apache.cxfgroupId>
<artifactId>cxf-rt-frontend-jaxwsartifactId>
<version>3.0.1version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>4.2.4.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webartifactId>
<version>4.2.4.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
<version>4.2.4.RELEASEversion>
dependency>
<dependency>
<groupId>org.apache.cxfgroupId>
<artifactId>cxf-rt-transports-httpartifactId>
<version>3.0.1version>
<scope>compilescope>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>3.2version>
<configuration>
<source>1.8source>
<target>1.8target>
<encoding>UTF-8encoding>
<showWarnings>trueshowWarnings>
configuration>
plugin>
<plugin>
<groupId>org.apache.tomcat.mavengroupId>
<artifactId>tomcat7-maven-pluginartifactId>
<version>2.2version>
<configuration>
<port>8080port>
<path>/path>
configuration>
plugin>
plugins>
build>
project>
DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Applicationdisplay-name>
<context-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:applicationContext.xmlparam-value>
context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
listener>
<servlet>
<servlet-name>cxfservletservlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>cxfservletservlet-name>
<url-pattern>/ws/*url-pattern>
servlet-mapping>
web-app>
同目录:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cxf="http://cxf.apache.org/core"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/core
http://cxf.apache.org/schemas/core.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd">
<jaxws:server address="/hello">
<jaxws:serviceBean>
<bean class="com.wind.service.impl.UserServiceImpl"/>
jaxws:serviceBean>
jaxws:server>
beans>
http://localhost:8080/ws/hello?wsdl
Java项目或者JavaWeb都可以
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cxf="http://cxf.apache.org/core"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/core
http://cxf.apache.org/schemas/core.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd">
<jaxws:client
id="helloService"
serviceClass="com.wind.service.UserService"
address="http://localhost:8080/ws/hello">
jaxws:client>
beans>
package com.wind.test;
import com.wind.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Client {
// 注入对象
@Resource
private UserService userService;
@Test
public void remote(){
// 查看接口的代理对象类型 class com.sun.proxy.$Proxy45
System.out.println(userService.getClass());
// 远程访问服务端方法
System.out.println(userService.sayHi("吕奉先"));
}
}
基于Http应用层,传递的可以是xml数据也可以是json数据,默认请求时xml数据
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.windgroupId>
<artifactId>05_jaxrs_serverartifactId>
<version>1.0-SNAPSHOTversion>
<name>05_jaxrs_servername>
<url>http://www.example.comurl>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<maven.compiler.source>1.7maven.compiler.source>
<maven.compiler.target>1.7maven.compiler.target>
properties>
<dependencies>
<dependency>
<groupId>org.apache.cxfgroupId>
<artifactId>cxf-rt-frontend-jaxrsartifactId>
<version>3.0.1version>
dependency>
<dependency>
<groupId>org.apache.cxfgroupId>
<artifactId>cxf-rt-transports-http-jettyartifactId>
<version>3.0.1version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-log4j12artifactId>
<version>1.7.12version>
dependency>
<dependency>
<groupId>org.apache.cxfgroupId>
<artifactId>cxf-rt-rs-clientartifactId>
<version>3.0.1version>
dependency>
<dependency>
<groupId>org.apache.cxfgroupId>
<artifactId>cxf-rt-rs-extension-providersartifactId>
<version>3.0.1version>
dependency>
<dependency>
<groupId>org.codehaus.jettisongroupId>
<artifactId>jettisonartifactId>
<version>1.3.7version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.10version>
<scope>testscope>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>3.2version>
<configuration>
<source>1.8source>
<target>1.8target>
<encoding>UTF-8encoding>
<showWarnings>trueshowWarnings>
configuration>
plugin>
plugins>
build>
project>
User
package com.wind.entity;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.ArrayList;
import java.util.List;
/**
* 基于restful风格的webservice,客户端与服务端之间通讯可以传递xml数据、json数据
* @XmlRootElement 指定对象序列化为xml或json数据时根节点的名称
* xml:
*
*
*
*
*
* json:
* {"User": {"id":100, "username":"jack","city":"广州" }}
*
* @author Windy
*/
@XmlRootElement(name = "User")
public class User {
private Integer id;
private String username;
private String city;
private List<Car> cars = new ArrayList<Car>();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public List<Car> getCars() {
return cars;
}
public void setCars(List<Car> cars) {
this.cars = cars;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", city=" + city + ", cars=" + cars + "]";
}
}
Car
package com.wind.entity;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "Car")
public class Car {
private Integer id;
private String carName;
private Double price;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCarName() {
return carName;
}
public void setCarName(String carName) {
this.carName = carName;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
@Override
public String toString() {
return "Car [id=" + id + ", carName=" + carName + ", price=" + price + "]";
}
}
package com.wind.service;
import com.wind.entity.User;
import javax.ws.rs.*;
import java.util.List;
/**
* 服务接口类
*
* @author Wind
*/
@Path("/userService") // 访问当前服务接口对应的路径【类似于@ResquesMapping注解】
@Produces("*/*") // 服务器支持的返回的数据格式类型 【*/* 代表xml和json都可以,默认是xml】
public interface IUserService {
/**
* 表示处理的请求的类型,post 对应的是insert新增操作
*
* @param user
*/
@POST
@Path("/user") // 访问当前服务接口方法对应的路径。 【.../userService/user】
@Consumes({"application/xml", "application/json"}) // 服务器支持的请求的数据格式类型
void saveUser(User user);
/**
* 表示处理的请求的类型,put 对应的是update修改操作
*
* @param user
*/
@PUT
@Path("/user")
@Consumes({"application/xml", "application/json"})
void updateUser(User user);
/**
* 表示处理的请求的类型,get 对应的是查询修改操作
*
* @return
*/
@GET
@Path("/user")
@Produces({"application/xml", "application/json"}) // 服务器支持的返回的数据格式类型
List<User> findAllUsers();
/**
* 表示处理的请求的类型,get 对应的是查询修改操作
*
* @param id
* @return
*/
@GET
@Path("/user/{id}")
@Consumes("application/xml")
@Produces({"application/xml", "application/json"})
User finUserById(@PathParam("id") Integer id);
/**
* 表示处理的请求的类型,delete 对应的是删除操作
*
* @param id
*/
@DELETE
@Path("/user/{id}")
@Consumes({"application/xml", "application/json"})
void deleteUser(@PathParam("id") Integer id);
}
package com.wind.service.impl;
import com.wind.entity.Car;
import com.wind.entity.User;
import com.wind.service.IUserService;
import java.util.ArrayList;
import java.util.List;
/**
* 服务接口实现类
*
* @author Wind
*/
public class UserServiceImpl implements IUserService {
@Override
public void saveUser(User user) {
System.out.println("save user:" + user);
}
@Override
public void updateUser(User user) {
System.out.println("update user:" + user);
}
@Override
public List<User> findAllUsers() {
List<User> users = new ArrayList<User>();
User user1 = new User();
user1.setId(1);
user1.setUsername("小明");
user1.setCity("北京");
List<Car> carList1 = new ArrayList<Car>();
Car car1 = new Car();
car1.setId(101);
car1.setCarName("保时捷");
car1.setPrice(1000000d);
carList1.add(car1);
Car car2 = new Car();
car2.setId(102);
car2.setCarName("宝马");
car2.setPrice(400000d);
carList1.add(car2);
user1.setCars(carList1);
users.add(user1);
User user2 = new User();
user2.setId(2);
user2.setUsername("小丽");
user2.setCity("上海");
users.add(user2);
return users;
}
@Override
public User finUserById(Integer id) {
if (id == 1) {
User user1 = new User();
user1.setId(1);
user1.setUsername("小明");
user1.setCity("北京");
return user1;
}
return null;
}
@Override
public void deleteUser(Integer id) {
System.out.println("delete user id :" + id);
}
}
package com.wind.publish;
import com.wind.service.impl.UserServiceImpl;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
public class Server {
public static void main(String[] args) {
// 创建发布服务的工厂
JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean();
// 设置服务地址
factory.setAddress("http://localhost:8001/ws/"); // 按需调用服务最终地址是:http://localhost:8001/ws/接口的@Path/接口方法的@Path
// 设置服务类
factory.setServiceBean(new UserServiceImpl());
// 添加日志输入输出拦截器
factory.getInInterceptors().add(new LoggingInInterceptor());
factory.getOutInterceptors().add(new LoggingOutInterceptor());
// 发布服务
factory.create();
System.out.println("发布服务成功,端口8001");
}
}
Jax-rs相比于Jax-ws少了服务的接口
创建Java项目
复制服务端pom.xml依赖
package com.wind.test;
import com.wind.entity.User;
import org.apache.cxf.jaxrs.client.WebClient;
import org.junit.Test;
import javax.ws.rs.core.MediaType;
public class Client {
@Test
public void testSave() {
User user = new User();
user.setId(100);
user.setUsername("Jerry");
user.setCity("gz");
// 通过WebClient对象远程调用服务端
WebClient
.create("http://localhost:8001/ws/userService/user") // 指定服务端地址
.type(MediaType.APPLICATION_JSON) // 指定请求数据格式(xml、json)
.post(user); // 指定请求类型【.post()/put()/delete()/get()】
}
@Test
public void testGet() {
// 查询一个
User user =
WebClient
.create("http://localhost:8001/ws/userService/user/1")
.accept(MediaType.APPLICATION_JSON) // 指定响应数据格式
.get(User.class);
System.out.println(user);
}
}
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.windgroupId>
<artifactId>07_jaxrs_spring_serverartifactId>
<version>1.0-SNAPSHOTversion>
<packaging>warpackaging>
<name>07_jaxrs_spring_server Maven Webappname>
<url>http://www.example.comurl>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<maven.compiler.source>1.7maven.compiler.source>
<maven.compiler.target>1.7maven.compiler.target>
properties>
<dependencies>
<dependency>
<groupId>org.apache.cxfgroupId>
<artifactId>cxf-rt-frontend-jaxrsartifactId>
<version>3.0.1version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-log4j12artifactId>
<version>1.7.12version>
dependency>
<dependency>
<groupId>org.apache.cxfgroupId>
<artifactId>cxf-rt-rs-clientartifactId>
<version>3.0.1version>
dependency>
<dependency>
<groupId>org.apache.cxfgroupId>
<artifactId>cxf-rt-rs-extension-providersartifactId>
<version>3.0.1version>
dependency>
<dependency>
<groupId>org.codehaus.jettisongroupId>
<artifactId>jettisonartifactId>
<version>1.3.7version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>4.2.4.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webartifactId>
<version>4.2.4.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
<version>4.2.4.RELEASEversion>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>3.2version>
<configuration>
<source>1.8source>
<target>1.8target>
<encoding>UTF-8encoding>
<showWarnings>trueshowWarnings>
configuration>
plugin>
<plugin>
<groupId>org.apache.tomcat.mavengroupId>
<artifactId>tomcat7-maven-pluginartifactId>
<version>2.2version>
<configuration>
<port>8080port>
<path>/path>
configuration>
plugin>
plugins>
build>
project>
DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Applicationdisplay-name>
<context-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:applicationContext.xmlparam-value>
context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
listener>
<servlet>
<servlet-name>cxfservletservlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>cxfservletservlet-name>
<url-pattern>/ws/*url-pattern>
servlet-mapping>
web-app>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cxf="http://cxf.apache.org/core"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/core
http://cxf.apache.org/schemas/core.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd">
<jaxrs:server address="/userService">
<jaxrs:serviceBeans>
<bean class="com.wind.service.impl.UserServiceImpl"/>
jaxrs:serviceBeans>
jaxrs:server>
beans>
Java项目
复制服务端依赖
复制服务端实体
package com.wind.test;
import com.wind.entity.User;
import org.apache.cxf.jaxrs.client.WebClient;
import org.junit.Test;
import javax.ws.rs.core.MediaType;
public class Client {
@Test
public void testSave() {
User user = new User();
user.setId(100);
user.setUsername("Jerry");
user.setCity("gz");
// 通过WebClient对象远程调用服务端
WebClient
// 说明Url:http://IP地址:端口/web.xml配置的地址/applicationContext.xml配置的地址/接口@Path地址/接口中方法@Path地址
.create("http://localhost:8080/ws/userService/userService/user")
.type(MediaType.APPLICATION_JSON) // 指定请求的数据格式为json
.post(user);
}
@Test
public void testGet() {
// 查询一个
User user =
WebClient
.create("http://localhost:8080/ws/userService/userService/user/1")
.accept(MediaType.APPLICATION_JSON)
.get(User.class);
System.out.println(user);
}
}
除项目创建、依赖添加以及基本配置,平常代码:
服务端【JaxWsServerFactoryBean】:编写实体、编写接口、编写接口实现类
客户端【JaxWsProxyFactoryBean】 :编写实体、调用
它就是个这~
@WebService
@WebMethod
@WebResult
@WebParam
@XmlRootElement
@Path
@Produces
@Consumes
IDEA调用WebService?
IDEA生成WebService服务端代码?
监听请求?
jetty?