webservice是开发中比较常用的技术。
由于企业中的开发平台,或平台下所有的系统,均可通过Web浏览器访问,那么就涉及到不同平台下的系统之间的交互协同工作。webservice为此提供了技术支持。
Web services 把 Web 应用程序提升到了另外一个层面:
Web Service所使用的是Internet上统一、开放的标准,如HTTP、XML、SOAP(简单对象访问协议)、WSDL等,所以Web Service可以在任何支持这些标准的环境(Windows,Linux)中使用。
这有助于大量异构程序和平台之间的互操作性,从而使存在的应用程序能够被广泛的用户访问。
从应用来说,Web Service是一件值得企业特别注意的事情。Web Service的应用范围目前包括两个方面:企业之间的应用、以及企业内部的应用。
企业之间的应用主要包括人们熟悉的企业间的电子商务(B2B)和企业与消费者之间的电子商务(B2C)。
Web Service在B2B的应用包括:以企业采购、物流和分销为内容的供应链;以及涉及到零售、B2C以及中间业务的支付系统。
而相对来说,企业内部的应用比企业之间的电子商务应用要成熟一些,并得到广泛的采用。最为普遍的应用是:采用中间件应用服务器软件作为工具将企业各项应用都进行改造和开发,开发目标是以Web为基础的应用,或者称为应用软件的网络化。目前企业内部这种网络应用还包括现在流行的ERP以及CRM等等。
常见的web服务:
webservice 即web服务,它是一种跨编程语言和跨操作系统平台的远程调用技术,适用于多个系统之间的调用,数据传递。
JAVA 中共有三种WebService 规范,分别是JAX-WS(JAX-RPC)(常用)、JAXM&SAAJ、JAX-RS(常用)。
webService三要素:soap、wsdl、uddi
JAVA 中共有三种WebService规范,分别是JAXM&SAAJ、JAX-WS(JAX-RPC)、JAX-RS。
JAX-WS(Java API For XML-WebService),JDK1.6 自带的版本为JAX-WS2.1,其底层支持为JAXB。JAX-WS(JSR 224)规范的API 位于javax.xml.ws.*包,其中大部分都是注解,提供API 操作Web 服务(通常在客户端使用的较多,由于客户端可以借助SDK 生成,因此这个包中的API 我们较少会直接使用)。
JAXM(JAVA API For XML Message)主要定义了包含了发送和接收消息所需的API,相当于Web 服务的服务器端,其API 位于javax.messaging.*包,它是JAVA EE 的可选包,因此你需要单独下载。SAAJ(SOAP With Attachment API For Java,JSR 67)是与JAXM 搭配使用的API,为构建SOAP 包和解析SOAP 包提供了重要的支持,支持附件传输,它在服务器端、客户端都需要使用。这里还要提到的是SAAJ 规范,其API 位于javax.xml.soap.*包。JAXM&SAAJ 与JAX-WS 都是基于SOAP 的Web 服务,相比之下JAXM&SAAJ暴漏了SOAP更多的底层细节,编码比较麻烦,而JAX-WS 更加抽象,隐藏了更多的细节,更加面向对象,实现起来你基本上不需要关心SOAP 的任何细节。那么如果你想控制SOAP 消息的更多细节,可以使用JAXM&SAAJ,目前版本为1.3。
JAX-RS 是JAVA 针对REST(RepresentationState Transfer)风格制定的一套Web 服务规范,由于推出的较晚,该规范(JSR 311,目前JAX-RS 的版本为1.0)并未随JDK1.6 一起发行,你需要到JCP 上单独下载JAX-RS 规范的接口,其API 位于javax.ws.rs.*包。这里的JAX-WS 和JAX-RS 规范我们采用Apache CXF 作为实现,CXF 是Objectweb Celtix和Codehaus XFire 合并而成。CXF 的核心是org.apache.cxf.Bus(总线),类似于Spring 的ApplicationContext,Bus 由BusFactory 创建,默认是SpringBusFactory 类,可见默认CXF是依赖于Spring 的,Bus 都有一个ID,默认的BUS 的ID 是cxf。你要注意的是Apache CXF2.2 的发行包中的jar 你如果直接全部放到lib 目录,那么你必须使用JDK1.6,否则会报JAX-WS 版本不一致的问题。对于JAXM&SAAJ 规范我们采用JDK 中自带的默认实现。
Web Service描述语言WSDL(SebService Definition Language)就是用机器能阅读的方式提供的一个正式描述文档而基于XML(标准通用标记语言下的一个子集)的语言,用于描述Web Service及其函数、参数和返回值。因为是基于XML的,所以WSDL既是机器可阅读的,又是人可阅读的。
wsdl说明书:
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注册,以使别的企业能够发现的访问协议的实现标准。
Web Service 可以适用于应用程序集成、软件重用、跨防火墙通信等需求。不同的
业务要求不同。具体如下:
简单来说,如果一个功能,需要被多个系统使用可以使用webservice开发一个服务端接口,供不同的客户端应用。主要应用在企业内部系统之间的接口调用、面向公网的webservice服务。
异构平台的互通性
理论上, Web Service 最大的优势是提供了异构平台的无缝街接技术手段。由于不同的用户使用不同的硬件平台,不同的操作平台,不同的操作系统,不同的软件,不同的协议通信,这就产生了互相通信的需求。 Web Service 使任何两个应用程序,只要能读写XML,那么就能互相通信。
更广泛的软件复用(例如手机淘宝可以复用已有淘宝的业务逻辑.)
软件的复用技术通过组合已有模块来搭建应用程序,能大幅度提高软件的生产效率和质量。用户只要获得了描述 Web Service 的 WSDL 文件,就可以方便地生成客户端代理,并通过代理访问 Web Service 。
成本低、可读性强、应用范围广
Web Service 可用基于 XML 的 SOAP 来表示数据和调用请求。并且通过 HTTP 协议传输XML 格式的数据
迅捷的软件发行方式
(每个web Service称为一个生产者.不同的生产者可以相互协同合作完成整个应用)Web Service 将彻底地改变软件的发行方式。软件供应商可以把软件分解成若Web Service 模块构成的系统,直接在 Web 上发布。
最重要的一点
客户端与服务端可能是用不同的语言开发的,但是,通过webservice提供服务接口,客户端与服务端之前可以传递对象。(基于soap协议)
由于soap是基于xml传输,本身使用xml传输会传输一些无关内容从而影响效率,随着soap协议的完善,soap协议增加了许多内容,这样就导致了使用soap去完成简单的数据传输而携带的信息更多效率再受影响;
Web Service作为web跨平台访问的标准技术,很多公司都限定要求使用Web Service,但如果是简单的接口可以直接使用http传输自定义数据格式,开发更快捷。
SOA(Service-OrientedArchitecture)面向服务架构是一种思想,它将应用程序的不同功能单元通过中立的契约(独立于硬件平台、操作系统和编程语言)联系起来,使得各种形式的功能单元更好的集成。目前来说,WebService 是SOA 的一种较好的实现方WebService 采用HTTP 作为传输协议,SOAP(Simple Object Access Protocol)作为传输消息的格式。但WebService 并不是完全符合SOA 的概念,因为SOAP 协议是WebService 的特有协议,并未符合SOA 的传输协议透明化的要求。SOAP 是一种应用协议,早期应用于RPC 的实现,传输协议可以依赖于HTTP、SMTP 等。
通常采用SOA 的系统叫做服务总线(BUS),结构如下图所示:
Apache CXF = Celtix + XFire,ApacheCXF 的前身叫 Apache CeltiXfire,现在已经正式更名为 Apache CXF 了,以下简称为 CXF。CXF 继承了 Celtix 和XFire 两大开源项目的精华,提供了对 JAX-WS 全面的支持,并且提供了多种 Binding 、DataBinding、Transport 以及各种 Format 的支持,并且可以根据实际项目的需要,采用代码优先
(Code First)或者 WSDL 优先(WSDL First)来轻松地实现 Web Services 的发布和使用。目前它仍只是 Apache 的一个孵化项目。
Apache CXF 是一个开源的 Services 框架,CXF 帮助您利用 Frontend 编程 API 来构建和开发 Services ,像 JAX-WS 。这些 Services 可以支持多种协议,比如:SOAP、XML/HTTP、RESTfulHTTP 或者 CORBA ,并且可以在多种传输协议上运行,比如:HTTP、JMS 或者 JBI,CXF 大大简化了 Services 的创建,同时它继承了 XFire 传统,一样可以天然地和 Spring 进行无缝集成。
CXF 包含了大量的功能特性,但是主要集中在以下几个方面:
项目的pom.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.itheimagroupId>
<artifactId>01_jaxws_serverartifactId>
<packaging>pompackaging>
<version>1.0-SNAPSHOTversion>
<modules>
<module>../03_jaxws_spring_servermodule>
modules>
<name>01_jaxws_servername>
<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>
<pluginManagement>
<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>
pluginManagement>
build>
project>
运行该函数发布服务
import com.itheima.service.impl.HelloServiceImpl;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
public class Server {
public static void main(String[] args) {
// 发布服务的工厂
JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
// 设置服务地址
factory.setAddress("http://localhost:8000/ws/hello");
// 设置服务类
factory.setServiceBean(new HelloServiceImpl());
// 添加日志输入、输出拦截器,观察soap请求、soap响应内容
factory.getInInterceptors().add(new LoggingInInterceptor());
factory.getOutInterceptors().add(new LoggingOutInterceptor());
// 发布服务
factory.create();
System.out.println("发布服务成功,端口8000.....");
}
}
写客户端之前要先明确:
创建项目:02_jaxws_client
与服务端项目依赖一致。
在服务端添加日志输入输出拦截器
查看soap请求、soap响应传输的xml数据
2018‐04‐10 10:52:30,439 72440 [tp2017085051‐18] INFO
serServiceImplPort.UserService ‐ Inbound Message
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
ID: 4
Address: http://192.168.95.62:8000/userService
Encoding: UTF‐8
Http‐Method: POST soap请求
Content‐Type: text/xml; charset=UTF‐8
Headers: {Accept=[*/*], Cache‐Control=[no‐cache], connection=[keepalive],
Content‐Length=[193], content‐type=[text/xml; charset=UTF‐8],
Host=[192.168.95.62: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:welcome xmlns:ns2="http://service.itcast.cn/"><arg0>请求数据arg0>
ns2:welcome>soap:Body>soap:Envelope>
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
2018‐04‐10 10:52:30,442 72443 [tp2017085051‐18] INFO
serServiceImplPort.UserService ‐ Outbound Message
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
ID: 4
Response‐Code: 200 soap响应
Encoding: UTF‐8
Content‐Type: text/xml
Headers: {}
Payload: <soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body>
<ns2:welcomeResponse xmlns:ns2="http://service.itcast.cn/"><return>响应数
据return>ns2:welcomeResponse>soap:Body>soap:Envelope>
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
pom.xml
<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>
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>
``
### 5.1.3 web.xml 配置CXFServlet
```xml
<web-app>
<display-name>Archetype Created Web Applicationdisplay-name>
<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>
<context-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:applicationContext.xmlparam-value>
context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
listener>
web-app>
Spring的配置文件applicationContext.xml
<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.itheima.service.impl.HelloServiceImpl">bean>
jaxws:serviceBean>
jaxws:server>
beans>
地址:http://localhost:8080/ws/hello?wdll
创建04_jaxws_spring_client项目
web.xml配置内容可以删除。服务实现也删除。
与服务端相同
<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.itheima.service.HelloService"
address="http://localhost:8080/ws/hello">
jaxws:client>
beans>
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Client {
// 注入对象
@Resource
private HelloService helloService;
@Test
public void remote(){
// 查看接口的代理对象类型
// class com.sun.proxy.$Proxy45
System.out.println(helloService.getClass());
// 远程访问服务端方法
System.out.println(helloService.sayHello("Jerry"));
}
}
一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制
REST(英文:Representational State Transfer,简称REST)描述了一个架构样式的网络系统,比如 web 应用程序。它首次出现在 2000 年 Roy Fielding 的博士论文中,他是HTTP 规范的主要编写者之一。在目前主流的三种Web服务交互方案中,REST相比于SOAP(Simple Object Access protocol,简单对象访问协议)以及XML-RPC更加简单明了,无论是对URL的处理还是对Payload的编码,REST都倾向于用更加简单轻量的方法设计和实现。值得注意的是REST并没有一个明确的标准,而更像是一种设计的风格。
所谓"资源",就是网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的实在。你可以用一个URI指向它,每种资源对应一个特定的URI。要获取这个资源,访问它的URI就可以,因此URI就成了每一个资源的地址或独一无二的识别符。所谓"上网",就是与互联网上一系列的"资源"互动,调用它的URI。
表现层,我们把"资源"具体呈现出来的形式,叫做它的"表现层"(Representation)。
比如,文本可以用txt格式表现,也可以用HTML格式、XML格式、JSON格式表现,甚至可以采用二进制格式;图片可以用JPG格式表现,也可以用PNG格式表现。
Restful 风格: http://bbs.csdn.net/topics/390908212
非resfull风格:http://bbs.csdn.net/topics?tid=390908212
严格地说,有些网址最后的".html"后缀名是不必要的,因为这个后缀名表示格式,属于"表现层"范畴,而URI应该只代表"资源"的位置。它的具体表现形式,应该在HTTP请求的头信息中用Accept和Content-Type字段指定,这两个字段才是对"表现层"的描述。
状态转化(State Transfer)
访问一个网站,就代表了客户端和服务器的一个互动过程。在这个过程中,势必涉及到数据和状态的变化。互联网通信协议HTTP协议,是一个无状态协议。这意味着,所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生"状态转化"(StateTransfer)。而这种转化是建立在表现层之上的,所以就是"表现层状态转化"。客户端用到的手段,只能是HTTP协议。具体来说,就是HTTP协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本
操作:
访问服务器资源,通过不同的http请求方式,服务器就知道对CRUD的哪个操作。JAX-RS 发布服务就是使用RESTFUL风格。
Restful编程风格
访问url地址更加简洁、更有层次感、更易于浏览器缓存。
举例
基于restful风格的url: https://miaosha.jd.com/#2357091
访问后台curd方法,url地址怎么写:
传统做法:
http://localhost:8080/prj/userAction?type=add
http://localhost:8080/prj/userAction?type=update
http://localhost:8080/prj/userAction?type=delete
基于restful风格的url:
http://localhost:8080/prj/userAction 系统一个地址对应后台的crud四个方法。
添加
http://localhost:8080/prj/userAction
请求方式:post
修改
http://localhost:8080/prj/userAction
请求方式:put
删除
http://localhost:8080/prj/userAction
请求方式:delete
@Path("/userService")
@Produces("*/*")
public interface IUserService {
@POST
@Path("/user")
@Consumes({ "application/xml", "application/json" })
public void saveUser(User user);
@PUT
@Path("/user")
@Consumes({ "application/xml", "application/json" })
public void updateUser(User user);
@GET
@Path("/user")
@Produces({ "application/xml", "application/json" })
public List<User> findAllUsers();
@GET
@Path("/user/{id}")
@Consumes("application/xml")
@Produces({ "application/xml", "application/json" })
public User finUserById(@PathParam("id") Integer id);
@DELETE
@Path("/user/{id}")
@Consumes({"application/xml", "application/json"})
public void deleteUser(@PathParam("id") Integer id);
}
基于restful风格的webservice,请求使用的是http协议,可以传递xml/json数据
pom.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">
<groupId>com.itheimagroupId>
<artifactId>05_jaxrs_serverartifactId>
<version>1.0-SNAPSHOTversion>
<modelVersion>4.0.0modelVersion>
<name>05_jaxrs_servername>
<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>
<pluginManagement>
<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>
pluginManagement>
build>
project>
User类
package com.itheima.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":"广州" }}
*
*/
@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.itheima.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 + "]";
}
}
Service接口
package com.itheima.service;
import com.itheima.entity.User;
import javax.ws.rs.*;
import java.util.List;
// 访问当前服务接口对应的路径
@Path("/userService")
@Produces("*/*") // 服务器支持的返回的数据格式类型
public interface IUserService {
// 表示处理的请求的类型,post 对应的是insert新增操作
@POST
// 访问当前服务接口方法对应的路径。 【.../userService/user】
@Path("/user")
// 服务器支持的请求的数据格式类型
@Consumes({"application/xml", "application/json" })
public void saveUser(User user);
// 表示处理的请求的类型,put 对应的是update修改操作
@PUT
@Path("/user")
@Consumes({ "application/xml", "application/json" })
public void updateUser(User user);
// 表示处理的请求的类型,get 对应的是查询修改操作
@GET
@Path("/user")
// 服务器支持的返回的数据格式类型
@Produces({ "application/xml", "application/json" })
public List<User> findAllUsers();
@GET
@Path("/user/{id}")
@Consumes("application/xml")
@Produces({ "application/xml", "application/json" })
public User finUserById(@PathParam("id") Integer id);
// 表示处理的请求的类型,delete 对应的是删除操作
@DELETE
@Path("/user/{id}")
@Consumes({"application/xml", "application/json"})
public void deleteUser(@PathParam("id") Integer id);
}
使用的注解分析
使用的注解:
Service实现类
package com.itheima.service;
import com.itheima.entity.Car;
import com.itheima.entity.User;
import java.util.ArrayList;
import java.util.List;
public class UserServiceImpl implements IUserService {
public void saveUser(User user) {
System.out.println("save user:" + user);
}
public void updateUser(User user) {
System.out.println("update user:" + user);
}
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;
}
public User finUserById(Integer id) {
if (id == 1) {
User user1 = new User();
user1.setId(1);
user1.setUsername("小明");
user1.setCity("北京");
return user1;
}
return null;
}
public void deleteUser(Integer id) {
System.out.println("delete user id :" + id);
}
}
public class Server {
public static void main(String[] args) {
// 创建发布服务的工厂
JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean();
// 设置服务地址
factory.setAddress("http://localhost:8001/ws/");
// 设置服务类
factory.setServiceBean(new UserServiceImpl());
// 添加日志输入输出拦截器
factory.getInInterceptors().add(new LoggingInInterceptor());
factory.getOutInterceptors().add(new LoggingOutInterceptor());
// 发布服务
factory.create();
System.out.println("发布服务成功,端口8001");
}
}
<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">
<groupId>com.itheimagroupId>
<artifactId>06_jaxrs_clientartifactId>
<version>1.0-SNAPSHOTversion>
<modelVersion>4.0.0modelVersion>
<name>06_jaxrs_clientname>
<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>
<pluginManagement>
<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>
pluginManagement>
build>
project>
WebClient
.create() 指定服务端地址
.type() 指定请求数据格式(xml、json)
.accept() 指定响应数据格式
.post()/put()/delete()/get() 指定请求类型
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) // 指定请求的数据格式为json
.post(user);
}
@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.itheimagroupId>
<artifactId>07_jaxrs_spring_serverartifactId>
<version>1.0-SNAPSHOTversion>
<modules>
<module>../08_jaxrs_spring_clientmodule>
modules>
<packaging>pompackaging>
<name>07_jaxrs_spring_server Maven Webappname>
<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>
<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.itheima.service.UserServiceImpl">bean>
jaxrs:serviceBeans>
jaxrs:server>
beans>
<web-app>
<display-name>Archetype Created Web Applicationdisplay-name>
<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>
<context-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:applicationContext.xmlparam-value>
context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
listener>
web-app>
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: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);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
所以,以后如果在开发中涉及多个系统之间的交互,webservice是不错的选择。使用service最大的好处是客户端与服务端语言的兼容性及交互时候可以传递对象。
内容梳理: