软件开发往往是这样:最开始的 90% 代码占用了开始的 90% 的开发时间;剩下10% 代码同样需要 90% 的开发时间。
在Spring
大行其道的今天,很多人对Java的RESTful规范JAX-RS
可能比较陌生甚至未曾听闻,当然这也是能被“理解”的,毕竟Spring似乎现在已是JavaEE
的事实标准。
现在有越来越多的公司希望能以简单而又贴合Web架构本身的方式公开Web API,因此REST变得越来越重要和流行。使用Ajax进行通信的富浏览器端也在朝这个目标不断迈进。这个架构原则提升了万维网的可伸缩性,无论何种应用都能从该原则中受益无穷。
其实关于JAX-RS
的资料并不算多,根据存在即合理原则我们需要承认它的重要性肯定比不上Spring,但是由于老外一般喜欢使用JavaEE规范技术,所以使得一些开源社区框架使用的均是基于JAX-RS
的实现,因此对它来个简单的了解还是很有必要的。
JAX-RS是JAVA EE6
引入的一个新技术,它的英文全称为Java API for RESTful Web Services
,它的核心概念是Resource,即面向资源。JavaEE 6于2019年12月份正式发布。
它被称为JAX-RS 1.0标准,它提供一套JSR311标准API:
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1.1</version>
</dependency>
这些注解和Spring MVC
的@RequestMapping、@RequestParam、@PathVariable...
何其相似,各位可以类比起来学习,本处不必一一展开。但是注意一点,SpringMVC在开发REST应用时,是不支持JSR311标准的。
它是JAX-RS 2.0版本,于2018年发布。它不仅定义了一套用于构建 RESTful 网络服务的 API,同时也通过增强客户端 API 功能简化了REST 客户端的构建过程。
<dependency>
<groupId>jakarta.ws.rs</groupId>
<artifactId>jakarta.ws.rs-api</artifactId>
<version>2.1.6</version>
</dependency>
规范API的向下兼容度还是非常好的,它在1.0规范的基础上对Client的构建做了增强,如提供了javax.ws.rs.client.ClientBuilder
、javax.ws.rs.client.WebTarget
等实用API。
每个JavaEE规范都应对应其落地产品的实现,就像JPA的实现落地实现有Hibernate
、TopLink
等。基于JAX-RS
实现的框架有Jersey、RESTEasy
,当然还有Apache CXF
。但是,因为Jersey是最早的实现(出现得比JSR311还早),是JSR311参考的主要对象,所以,可以说Jersey就是事实上的标准,就像Hibernate是JPA的事实标准一样~
值得一提的是:RESTEasy是由JBoss公司开发的,所以将用RESTEasy框架实现的应用部署到JBoss服务器上,可以实现很多额外的功能(但很显然,JBoss已经退出了历史舞台)。
Jersey是一个REST框架,既然是REST框架,那自然提供了REST服务相关的一切东西。因此在使用过程中,你可以同Spring MVC做对比,部署到Servlet容器上即可运行,形如这样:
@Path("/api/v1/user")
public class UserResource{
@GET
@Path("/{username}")
@Consumes({"application/json", "application/xml"})
@Produces("application/json")
public String getUser(@PathParam("username") String username){
...
}
}
作为服务端,它使用的库是:
1.x:
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.19.4</version>
</dependency>
2.x:
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.30.1</version>
</dependency>
1.x在2017年5月发布其最后一个版本1.19.4
后就已经寿终正寝了,因此不建议再使用。2.x从2013年发布迭代至今,是现在推荐的使用方式(可见它俩重叠开发了好几年)。
1.x和2.x版本互不兼容,核心API均出现了一定的差异性,举例如下:
com.sun.jersey.spi.container.servlet.ServletContainer
(sun公司)org.glassfish.jersey.servlet.ServletContainer
(glassfish公司)com.sun.jersey.config.property.packages
jersey.config.server.provider.packages
@WebServlet
来扫描jersey的资源说明:glassfish是一款web应用服务器,和tomcat一样,也是一款优秀的Servlet容器。它既是EJB容器也是WEB容器,由Sun公司开发(现Oracle赞助)。
以上大体介绍了jersey作为Server端技术的实施,接下来介绍其客户端API,这便是jersey-client
工程。Jersey的客户端API能够让我们非常方便的创建出REST的Web服务客户端,不管是客户端应用,还是用于测试的代码,都是非常容易和舒服的。
特别说明:本文讲解、实例使用的jersey-client
版本是1.x版本,1.x版本,1.x版本
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.19.4</version>
</dependency>
它的jar包依赖情况如下:
@Test
public void fun1() {
// 1、创建一个Client
DefaultClientConfig clientConfig = new DefaultClientConfig();
Client client = Client.create(clientConfig);
// 2、准备一个WebResource,等待发送请求(注意:http前缀不能省)
// WebResource webResource = client.resource( URI.create("www.baidu.com"));
WebResource resource = client.resource("http://www.baidu.com");
// 3、发送get/post请求获取资源
// String result = resource.get(String.class);
// System.out.println(result);
// 若你想获取响应详情,可以使用ClientResponse
ClientResponse response = resource.get(ClientResponse.class);
System.out.println(response.getStatus());
System.out.println(response.getHeaders());
System.out.println(response.getLocation());
System.out.println(response.getEntity(String.class));
}
运行程序,控制台打印:
200
{Server=[bfe], Content-Length=[2381], Date=[Sat, 14 Mar 2020 09:55:47 GMT], Content-Type=[text/html]}
null
<!DOCTYPE html> ... // 百度首页的html,略
说明:Client的构建属于昂贵资源,因此请重复使用它,它底层使用的
java.net.HttpURLConnection
进行请求发送的
在Java中,REST Client
实现方式有多种,比如JBoss RestEasy、 Sun Jersey、Dropwizard、Apache HTTPClient、OkHttp等等。很多人直接使用Apache Http Client
, 我并不推荐直接使用这个库,主要是因为这个库相对比较底层,需要自己处理的东西很多,,API也相对繁琐。
另外,对于JDK源生的URLConnection
和Apache HTTPClient
附上一个对比图:
总体上HttpClient比HttpURLConnection功能更加丰富且好用,但是更加占用内存和CPU资源,大家都知道!当然,若你在Spring环境下需要使用Rest Client,那就用RestTemplate
吧~
本文介绍了JAX-RS
标准JavaEE技术,并且对JSR 311/JSR 339等做了一个简单的科普,示例了jersey-client
的使用介绍。个人觉得过于国内程序员来说JAX-RS
技术(jersey的使用)不用太过于深究,浅尝辄止即可。