在本指南中,我们将学习使用Java开发Rest API的所有标准JAX-RS注解。
Jersey Framework是JAX-RS的参考实现,它使用所有注解来构建Restful Web服务。
本指南涵盖了用于Rest API开发的所有标准JAX-RS注解。
@Path
注解的值是一个相对URI路径。在上面的示例中,Java类将托管在URI路径/helloworld中。这是@Path
注解的一个极其简单的用法。JAX-RS之所以如此有用,是因为您可以在URI中嵌入变量。
URI路径模板是URI语法中嵌入了变量的URI。这些变量在运行时被替换,以便资源响应基于替换的URI的请求。变量用大括号表示。例如,请查看以下@Path注解:
@Path("/users/{username}")
例如,如果用户输入他们的用户名为"Galileo",则Web服务将响应以下URL:
http://example.com/users/Galileo
为了获得用户名变量的值,可以在请求方法的方法参数上使用@PathParam
,例如:
示例:指定URI路径参数
@Path("/users/{username}")
public class UserResource {
@GET
@Produces("text/xml")
public String getUser(@PathParam("username") String userName) {
...
}
}
如果要求用户名只能由小写和大写数字字符组成,则可以声明一个特定的正则表达式,该表达式将覆盖默认正则表达式"[^/]+",例如:
@Path("users/{username: [a-zA-Z][a-zA-Z_0-9]*}")
在此类示例中,用户名变量将仅匹配以一个大写或小写字母开头、零个或多个字母数字字符以及下划线字符的用户名。如果用户名不匹配,则将出现404(未找到)响应。@Path
值可以以"/"开头,也可以不以"/"开头,这没有区别。同样,默认情况下,@Path
值可以以"/"结尾,也可以不以"/"结尾,这没有区别,因此以"/"结尾或不以"/"结尾的请求URL都将匹配。
@GET、@PUT、@POST、@DELETE等(HTTP方法)
带有@GET注解的方法注解响应HTTP get请求。
用于获取操作的@GET注解。
**示例:**从数据库中获取所有书籍。
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getAllBooks() {
List<Book> books = BookRepository.getAllBooks(); // queries database for all books
GenericEntity<List<Book>> list = new GenericEntity<List<Book>>(books) {};
return Response.ok(list).build();
}
注意,GenericEntity Package 器用于维护List as Book的泛型类型。
注解为**@POST**的方法响应POST方法请求。
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response saveBook(Book book) {
book = bookRepository.saveBook(book);
return Response.ok(book).build();
}
POST HTTP方法通常用于创建资源。此示例代码在数据库中持久化new book对象。
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response updateBook(Book book) {
book = bookRepository.updateBook(book);
return Response.ok(book).build();
}
注解为**@DELETE**的方法应删除资源。
@DELETE
@Path("{isbn}")
@Produces(MediaType.APPLICATION_JSON)
public Response deleteBook(@PathParam("isbn") String isbn) {
Book book = bookRepository.deleteBookByIsbn(isbn);
return Response.ok(book).build();
}
通常,资源或其id从URI变量传递给resource方法参数,如本例所示。
用**@OPTIONS**注解的方法响应HTTP选项请求。
@OPTIONS
public Response preflight() {
return Response.ok().header("Allow", true).build();
}
当客户端希望向不同的域发出复杂的HTTP请求时,选项方法用作请求。这样做是为了确定是否允许客户端发出请求。
HTTP**@HEAD**方法与HTTP GET方法相同,只是服务器不能在响应中使用正文。
@HEAD
public Response headsUp() {
return Response.ok().build();
}
@Produces
注解用于指定资源可以生成并发送回客户端的MIME媒体类型。@Produces
可以应用于类和方法级别。在本例中,Java方法将生成由MIME媒体类型"text/plain"标识的表示。
@Path("/myResource")
@Produces("text/plain")
public class SomeResource {
@GET
public String doGetAsPlainText() {
...
}
@GET
@Produces("text/html")
public String doGetAsHtml() {
...
}
}
doGetAsPlainText方法在类级别默认为@Produces
注解的MIME类型。
doGetAsHtml方法的@Produces
注解覆盖类级别的@Produces
设置,并指定该方法可以生成HTML而不是纯文本。
在同一@Produces声明中可以声明多个媒体类型,例如:使用多个输出MIME类型。
@GET
@Produces({"application/xml", "application/json"})
public String doGetAsXmlOrJson() {
...
}
如果媒体类型"application/xml"和"application/json"中的任何一种都可接受,则将调用doGetAsXmlOrJson方法。如果两者都可接受,则将选择前者,因为前者先出现。
服务器还可以为各个媒体类型指定质量因子。如果客户端可以同等地接受多个媒体类型,则会考虑这些质量因子。例如:
示例:服务器端内容协商
@GET
@Produces({"application/xml; qs=0.9", "application/json"})
public String doGetAsXmlOrJson() {
...
}
In the above sample, if client accepts both "application/xml" and "application/json" (equally), then a server always sends "application/json", since "application/xml" has a lower quality factor.
@Consumes
注解用于指定资源可以使用的表示形式的MIME媒体类型。示例:指定输入MIME类型
@POST
@Consumes("text/plain")
public void postClichedMessage(String message) {
// Store the message
}
在本例中,Java方法将使用MIME媒体类型"text/plain"标识的表示。注意,resource方法返回void。这意味着没有返回表示,并且将向客户端返回状态代码为204(无内容)的响应。@Consumes
可以应用于类和方法级别,并且在同一@Consumes
声明中可以声明多于一个媒体类型。
@PathParam
从请求URL的路径组件中提取与**@Path**中声明的路径匹配的路径参数。示例:
@Path("{userid}/")
public String getUser(@PathParam("userid") String userid) {
// return user object as json
}
@Path("/users/{username}")
public class UserResource {
@GET
@Produces("text/xml")
public String getUser(@PathParam("username") String userName) {
...
}
}
查询参数是与附加到URL中?
符号后面的键/值对关联的值。例如,在URL中:http://localhost:8080/api/books/search?keyword=Java&limit=10查询参数为关键字和限制,查询值为Java和10。
要检索这些值,请使用@QueryParam
注解并将查询参数的名称作为值传递给注解,然后在响应对URI resource/books/search的请求的resource方法中注解一个方法参数。
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("search")
public Response searchBook(@QueryParam("keyword") String keyword, @QueryParam("limit") int limit) {
List<Book> books = bookRepository.searchBook(keyword, limit);
return Response.ok(new GenericEntity<List<Book>>(books) {}).build();
}
在上面的代码片段中,keyword查询参数的值被赋给method参数keyword,limit查询参数的值被赋给limit方法参数。
@FormParam
稍有特殊,因为它从MIME媒体类型为"application/x-www-form-urlencoded"的请求表示中提取信息,并符合HTML表单指定的编码,如此处所述。此参数对于提取HTML表单POST的信息非常有用,例如,以下代码从POST的表单数据中提取名为"name"的表单参数。示例:处理POST的HTML表单
@POST
@Consumes("application/x-www-form-urlencoded")
public void post(@FormParam("name") String name) {
// Store the message
}
换句话说,你可能需要直接从正文中读取POST HTTP请求中发送的参数,而不是将其序列化为一个对象,这可以通过使用@FormParam
注解来完成。
@POST
@Produces(MediaType.APPLICATION_JSON)
public Response saveBookF(@FormParam("title") String title,
@FormParam("author") String author,
@FormParam("price") Float price) {
return Response.ok(bookRepository.saveBook(new Book(title, author, price))).build();
}
矩阵参数是一组用分号而不是"与"号分隔的查询参数。出现这种情况的原因可能是,这些值是从多选输入框中选择的,并且是通过GET请求而不是POST请求设置的。URL可能如下所示:
http://localhost:8080/api/books;author=atheedom;category=Java;language=english
注解@MatricParam用于从URI检索参数值并将其赋给方法参数。
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getBookBy(@MatrixParam("author") String author,
@MatrixParam("category") String category,
@MatrixParam("language") String language) {
return Response.ok(
new GenericEntity<List<Book>>(
bookRepository.getBookBy(author, category, language)) {}).build();
}
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getCart(@CookieParam("cartId") int cartId) {
return Response.ok().build();
}
@HeaderParam
注解用于将HTTP请求头值注入到资源方法参数中,您可以将其视为使用@Context
注解注入HttpServletRequest or HttpHeaders
示例的快捷方式。
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getReferrer(@HeaderParam("referer") String referrer) {
return Response.ok(referrer).build();
}
提供程序用于通过改变运行时的行为来扩展和定制JAX-RS,以实现一组目标。
提供程序有三种类型:
实体提供者这种类型的提供者控制数据表示(例如JSON和XML)的Map,上下文提供者这种类型的提供者控制资源可以使用@Context注解异常提供者访问的上下文这种类型的提供者控制Java异常到JAX-RS响应示例的Map。它们唯一的共同点是必须使用@提供程序注解并遵循构造函数声明的正确规则。
@ApplicationPath注解让我们从@ApplicationPath注解树的顶部开始:
@ApplicationPath("/api")
public class RESTConfig extends Application {}
这是你开始定义资源的URI的地方。这里我们说我们所有的资源都可以在根目录**/api**中找到。URL应该看起来像这样:
http://localhost:8080/webcontext/api/
其中webcontext是应用程序的名称。
当使用servlet部署JAX-RS应用程序时,ServletConfig、ServletContext、HttpServletRequest和HttpServletResponse都可以使用@Context。
JAX-RS提供了@Context
注解,用于在REST风格的服务中注入各种资源。一些最常用的注入组件是HTTP头、HTTP URI相关信息。以下是一个完整列表(没有特定顺序)
HTTP标头HTTP URI详细信息安全上下文资源上下文请求配置应用程序提供程序
示例:
@Path("testinject")
public class InjectURIDetails{
//localhost:8080/<root-context>/testinject/httpheaders
@GET
@Path("httpheaders")
public void test(@Context HttpHeaders headers){
System.out.println("ALL headers -- "+ headers.getRequestHeaders().toString());
System.out.println("'Accept' header -- "+ headers.getHeaderString("Accept"));
System.out.println("'TestCookie' value -- "+ headers.getCookies().get("TestCookie").getValue());
}
}
public class TodoResource {
@Context
UriInfo uriInfo;
@Context
Request request;
String id;
public TodoResource(UriInfo uriInfo, Request request, String id) {
this.uriInfo = uriInfo;
this.request = request;
this.id = id;
}
}
这篇文章解释了所有的标准JAX-RS注解。
了解有关Jersey Rest Developer Guide上Jersey Rest框架的更多信息。
本文的所有代码都可以在Github上找到,这是一个基于Maven的项目,因此应该很容易导入和运行。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://www.javaguides.net/2018/06/guide-to-standard-jax-rs-annotations.html
内容来源于网络,如有侵权,请联系作者删除!