本文最后更新于:2023-03-01T22:30:38+08:00
JAX-RS
简介
JAX-RS是Java API for RESTful Web
Service的缩写,它是在Java中实现RESTful API的通用标准,是一组由Java
EE提供的接口和注解。与传统的 servlet
模型相比,JAX-RS提供了一种可行的、更为简便、移植性更好的方式来在Java内实现RESTful服务。JAX-RS
提供的一些关键功能部件包括:
一组用于声明资源类及其所支持数据类型的注释
一组允许应用程序开发者访问运行时上下文的接口
用于集成定制内容处理程序的可扩展框架
与JDBC类似,JAX-RS只是定义了在Java中实现RESTful
API的一些标准,但是没有自己实现。具体的实现需要依赖于对应的来源,常见的JAX-RS的实现包括下面一些:
Apache CXF:是一个开源的Web服务框架
Jersey:由Sun提供的JAX-RS的参考实现框架,注意提出JAX-RS标准的也是Sun
RESTEasy:JBoss的实现
Restlet:由Jerome Louvel和Dave Pawson开发,是最早的REST框架
Apache
Wink:是一个处于Apache软件基金会孵化器中的项目,其服务模块实现了JAX-RS规范
规范内容
在JavaEE中包含了JAX-RS中主要使用的接口和注解,它们都位于在包javax.ws.rs.*
下。JAX-RS提供了一些标注将资源类或者POJO类封装为Web资源,常用的标注包括:
@Path
:标注资源类或方法的相对路径,如果标注在方法上,则表示具体的请求路径
@GET, @PUT, @POST, @DELETE
:标注方法使用的HTTP请求的类型,分别对应
4 种 HTTP 方法,分别用于检索、更新、创建和删除资源的操作。在RESTful
API中,请求方式+请求路径才能唯一定义一个API
@Produces
:标注返回的MIME媒体类型,可以使用枚举类来指定,也可以使用字符串同时指定多种返回类型
1 2 3 4 5 @Produces(MediaType.TEXT_PLAIN) @Produces(MediaType.APPLICATION_JSON) @Produces({"application/json", "application/xml"})
@Consumes
:标注可接受请求的MIME媒体类型,使用方式和@Produces相同,含义则正好相反
Param相关注解:标注方法的参数来自于HTTP请求的不同位置。在方法参数上标注对应注解之后,参数就能够获取到对应的值
@PathParam
:标识参数来自于URL的路径
@QueryParam
:标识参数来自于URL的查询参数
@HeaderParam
:标识参数来自于HTTP请求的头信息
@CookieParam
:标识参数来自于HTTP请求的Cookie
@FormParam
:获取Post请求中表单中的数据
@BeanParam
:获取请求参数中的数据,并用实体Bean进行封装
@Context
:用于解析上下文参数,通过该注解可以获得UriInfo、ServletConfig、ServletContext、HttpServletRequest、HttpServletResponse和HttpHeaders等信息
Jersey的使用
Jersey是JAX-RS的一种实现,下面简单介绍相关的使用方式。
首先需要创建一个JavaWeb项目,具体创建方式可以参考JavaWeb笔记(2)-Tomcat的使用
-
EverNorif 。创建好Web项目之后,在pom.xml
中引入如下依赖:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <dependency > <groupId > javax.ws.rs</groupId > <artifactId > javax.ws.rs-api</artifactId > <version > 2.1.1</version > </dependency > <dependency > <groupId > org.glassfish.jersey.containers</groupId > <artifactId > jersey-container-servlet</artifactId > <version > 2.34</version > </dependency > <dependency > <groupId > org.glassfish.jersey.core</groupId > <artifactId > jersey-server</artifactId > <version > 2.34</version > </dependency > <dependency > <groupId > org.glassfish.jersey.core</groupId > <artifactId > jersey-client</artifactId > <version > 2.34</version > </dependency > <dependency > <groupId > org.glassfish.jersey.inject</groupId > <artifactId > jersey-hk2</artifactId > <version > 2.34</version > </dependency >
之后在web.xml
中配置如下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <?xml version="1.0" encoding="UTF-8" ?> <web-app xmlns ="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version ="4.0" > <display-name > Archetype Created Web Application</display-name > <servlet > <servlet-name > jersey-serlvet</servlet-name > <servlet-class > org.glassfish.jersey.servlet.ServletContainer</servlet-class > <init-param > <param-name > jersey.config.server.provider.packages</param-name > <param-value > com.syh</param-value > </init-param > <load-on-startup > 1</load-on-startup > </servlet > <servlet-mapping > <servlet-name > jersey-serlvet</servlet-name > <url-pattern > /rest/*</url-pattern > </servlet-mapping > </web-app >
其中这里需要注意两个配置,第一个就是在servlet
标签中的init-param中的value,这里需要设置的我们对应类资源的包。另一个是在servlet-mapping
中的url-pattern
,后续访问时会使用到这个值。
配置完成之后,就可以写一个简单的资源类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package com.syh;import javax.ws.rs.*;@Path("/message") public class HelloWorld { @GET public String getMessage () { return "Hello World!" ; } @POST @Path("/{text}") public String postMessage (@PathParam("text") String text) { System.out.println("post..." ); System.out.println(text); return "success" ; } }
这表示我们现在有Message的资源,通过Get方法可以进行访问。启动Web项目之后,则可以访问如下的链接:http://localhost:8080/<context-path>/rest/message
,就会得到Hello
World信息。这里的/rest
就是在web.xml中的配置,/message
则是在资源类中Path
注解的值。同时也可以发送对应的post请求:http://localhost:8080/<context-path>/rest/message/<text>
,之后在控制台就会输出对应的text的内容
结合SpringBoot使用
在开发Web项目时,我们更多会使用SpringBoot。而在SpringBoot中结合使用JAX-RS,能帮助我们更方便的创建RESTful风格的API。在SpringBoot中引入Jersey的依赖要简单许多,可以直接通过starter进行引入:
1 2 3 4 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-jersey</artifactId > </dependency >
引入依赖之后,我们可以创建如下的资源类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package com.syh.resource;import org.springframework.stereotype.Component;import javax.ws.rs.GET;import javax.ws.rs.Path;import javax.ws.rs.Produces;import javax.ws.rs.QueryParam;import javax.ws.rs.core.MediaType;@Component @Path("message") public class MessageResource { @GET @Path("sayHello") @Produces(MediaType.APPLICATION_JSON) public String sayHello (@QueryParam("msg") String msg) { System.out.println("get hello: " + msg); return "success:" + msg; } }
其中message表示资源路径,sayHello表示访问路径。
为了在SpringBoot中使用Jersey,我们需要进行相关的配置。Springboot中对Jersey的配置有三种方式:第一种方式创建一个自定义的ResourceConfig;第二种方式,是返回一个ResourceConfig类型的@Bean,第三种方式,配置一组ResourceConfigCustomizer对象。这里我们使用第一种方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package com.syh.config;import com.syh.resource.MessageResource;import org.glassfish.jersey.server.ResourceConfig;import org.springframework.context.annotation.Configuration;import javax.ws.rs.ApplicationPath;@Configuration @ApplicationPath("resource") public class JerseyConfiguration extends ResourceConfig { public JerseyConfiguration () { register(MessageResource.class); } }
首先这个配置类继承了ResourceConfig
,并且使用@Configuration
进行标注。在这个类中我们需要完成资源类的注册,注册后的资源才能够进行访问。Springboot默认把Jersey的根路径映射在/*上;如果要更改默认的根路径设置,对于自定义的ResourceConfig方式来说,可以在类上面添加一个@ApplicationPath
注解即可。当然也可以在application.yaml中添加配置来改变项目的根路径:
1 2 3 spring: jersey: application-path: resource
至此我们就完成了Jersey在SpringBoot中的结合。启动项目之后,可以访问对应的资源,使用链接http://localhost:8080/resource/message/sayHello?msg=hahaha
,这样就能够访问到对应的资源,在控制台中也会打印出对应的提示信息。
参考文章
JAX-RS -
wikipedia
IBM
JAX-RS 入门
Jersey
(JAX-RS) 教程
SpringBoot2 整合
JAX-RS
Jersey框架入门学习