Rest API By JAX-RS 实现接口发布
原文地址:http://www.cnblogs.com/oopsguy/p/7503589.html
JAX-RS
我们在 JAX-RS 示例中使用相同的模型和 DAO,我们所需要做的只有更改 StormtroooperController
类的注解。
由于 JAX-RS 是一个 API 规范,您需要选择一个实现,在本示例中,我们将使用 Jersey 作为实现。虽然可以创建一个没有直接依赖于特定 JAX-RS 实现的 JAX-RS 应用程序,但这将使得示例更加啰嗦。
我选择 Jersey 有几个原因,主要是因为我可以不用绕圈子就可以轻松地获得简单的依赖注入,毕竟我们是把它在和 Spring 做对比。Apache Shiro 有一个示例,可在 Jersey、RestEasy 和 Apache CXF 上运行相同的代码,如果你感兴趣不妨看一看。
此示例与 Spring Boot 不同之处在于,它打包成 WAR,而 Spring Boot 是单个 JAR。此示例也可以打包进可执行的 jar 中,但此内容不在本文范围之内。
在 JAX-RS 中与 SpringBootApplication
相当的是一个 Application
类。Jersey 的 Application
子类 ResourceConfig
添加了一些便捷的实用方法。以下代码配置 classpath 扫描以检测我们的各个资源类,并将 DefaultStormtrooperDao
实例绑定到 StromtrooperDao
接口。
@ApplicationPath("/")
public class JaxrsApp extends ResourceConfig {
public JaxrsApp() {
// scan the resources package for our resources
packages(getClass().getPackage().getName() + ".resources");
// use @Inject to bind the StormtrooperDao
register(new AbstractBinder() {
@Override
protected void configure() {
bind(stormtrooperDao()).to(StormtrooperDao.class);
}
});
}
private StormtrooperDao stormtrooperDao() {
return new DefaultStormtrooperDao();
}
}
另外要指出的是,在上面的类中,@ApplicationPath
注解将这个类标记为一个 JAX-RS
应用程序并绑定到一个特定的 url 路径,这匹配了上面的 Spring 例子,我们只使用了根路径:/
。资源包中检测到的每个资源都将被追加到该基本路径。
JAX-RS 资源实现看起来非常类似于上述的 Spring 版本(重命名为 StormtroooperResource
,以符合命名约定):
@Path("/troopers")
@Produces("application/json")
public class StormtroooperResource {
@Inject
private StormtrooperDao trooperDao;
@Path("/{id}")
@GET
public Stormtrooper getTrooper(@PathParam("id") String id) throws NotFoundException {
Stormtrooper stormtrooper = trooperDao.getStormtrooper(id);
if (stormtrooper == null) {
throw new NotFoundException();
}
return stormtrooper;
}
@POST
public Stormtrooper createTrooper(Stormtrooper trooper) {
return trooperDao.addStormtrooper(trooper);
}
@Path("/{id}")
@POST
public Stormtrooper updateTrooper(@PathParam("id") String id,
Stormtrooper updatedTrooper) throws NotFoundException {
return trooperDao.updateStormtrooper(id, updatedTrooper);
}
@Path("/{id}")
@DELETE
public void deleteTrooper(@PathParam("id") String id) {
trooperDao.deleteStormtrooper(id);
}
@GET
public Collection<Stormtrooper> listTroopers() {
return trooperDao.listStormtroopers();
}
}
我们先来分解以下片段:
@Path("/troopers")
@Produces("application/json")
public class StormtroooperResource {
类似于上面的 Spring 示例,类级别上的 @Path
表示此类中的每个注解方法都将位于 /troopers
基本路径下。@Produces
注解定义了默认响应内容类型(除非被其他方法的注解所覆盖)。
与 Spring 示例不同,其中 @RequestMapping
注解定义了请求的路径、方法和其他属性,在 JAX-RS 资源中,每个属性都使用单独的注解。与上述类似,如果我们分解了 updateTrooper()
方法:
@Path("/{id}")
@POST
public Stormtrooper updateTrooper(@PathParam("id") String id,
Stormtrooper updatedTrooper) throws NotFoundException {
return trooperDao.updateStormtrooper(id, updatedTrooper);
}
我们看到 @Path("/{id}")
以及 @PathParam("id")
允许将路径的 id
部分转换为方法参数。与 Spring 示例不同的是,Stromtrooper
参数和返回值不需要额外的注解,由于此类上的 @Produces("application/json")
注解,它们将自动序列化/反序列化为 JSON。
运行 JAX-RS 示例
进入 Jersey 目录,使用 maven 命令:mvn jetty:run
运行此示例。
发出与上述相同的两个请求,我们可以发出 GET
请求列出所有 trooper:
$ curl http://localhost:8080/troopers
HTTP/1.1 200 OK
Content-Length: 3944
Content-Type: application/json
Date: Tue, 08 Nov 2016 21:57:55 GMT
Server: Jetty(9.3.12.v20160915)
[
{
"id": "FN-2187",
"planetOfOrigin": "Unknown",
"species": "Human",
"type": "Basic"
},
{
"id": "FN-0064",
"planetOfOrigin": "Naboo",
"species": "Nikto",
"type": "Sand"
},
{
"id": "FN-0069",
"planetOfOrigin": "Hoth",
"species": "Twi'lek",
"type": "Basic"
},
{
"id": "FN-0169",
"planetOfOrigin": "Felucia",
"species": "Kel Dor",
"type": "Jump"
},
...
或者 GET
一个特定的资源:
$ curl http://localhost:8080/troopers/FN-2187
HTTP/1.1 200 OK
Content-Length: 81
Content-Type: application/json
Date: Tue, 08 Nov 2016 22:00:02 GMT
Server: Jetty(9.3.12.v20160915)
{
"id": "FN-2187",
"planetOfOrigin": "Unknown",
"species": "Human",
"type": "Basic"
}
现在我们已经看到了基本相同的代码在 Spring 和 JAX-RS 应用程序中运行,只需更改注解即可。我更喜欢 JAX-RS 的注解,他们更简洁。既然如此,为什么要在两者选择呢?Jersey 和 RestEasy 都支持 Spring(以及 Guice 和 CDI/Weld)。让我们来创建一个结合了这两者的第三个例子。
JAX-RS 与 Spring 整合
针对此示例,我们需要三个类:Spring Boot 应用类、Jersey 配置类和我们的资源类。
我们的 SpringBootApp
和 StormtrooperResource
类与之前的版本相同,唯一的区别就是 Jersey 配置类:
@Component
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
// scan the resources package for our resources
packages(getClass().getPackage().getName() + ".resources");
}
}
该类与之前的示例有点类似。首先,您可能注意到了用于标记此类由 Spring 管理的 `@Configuration 注解。剩下的就是指示 Jersey 再次扫描资源包,其余的都是您的处理逻辑。
进入 spring-jaxrs
目录中,使用 mvn spring-boot:run
命令启动此示例。
Spring 与 JAX-RS 对照表
为了帮助您在 Spring 和 JAX-RS 的之间作出区分,这里给出了一份对照表。尽管不是很详尽,但它包含最常见的注解。
Spring Annotation | JAX-RS Annotation |
---|---|
@RequestMapping(path = "/troopers") | @Path("/troopers") |
@PostMapping | @POST |
@PutMapping | @PUT |
@GetMapping | @GET |
@DeleteMapping | @DELETE |
@ResponseBody | N/A |
@RequestBody | N/A |
@PathVariable("id") | @PathParam("id") |
@RequestParam("xyz") | @QueryParam("xyz") |
@RequestParam(value="xyz") | @FormParam("xyz") |
@RequestMapping(produces = {"application/json"}) | @Produces("application/json") |
@RequestMapping(consumes = {"application/json"}) | @Consumes("application/json") |
何时在 Spring 上使用 JAX-RS?
在我看来,它应该这样分解:
如果你已经是一个 Spring 用户,就使用 Spring 吧。如果你正在创建一个对象 JSON/XML REST 层,那么您选择的 DI 框架(如 Spring、Guice 等)支持 JAX-RS 资源可能是一个不错的选择。服务器端渲染页面并不是 JAX-RS 规范的一部分(虽然它是扩展支持的)。我曾在 Jersey 中使用了 Thymeleaf 视图,但我认这是 Spring MVC 该做的。
目前为止,我们还没有把 Spring Boot 应用程序与 WAR 打包的应用程序进行详细地对比。Dropwizard(使用嵌入式 Jetty 容器和 Jersey)可能是与 Spring Boot 应用程序最接近的。希望这篇文章能给你带来一些灵感,您可以做自己的对比。如果您有任何问题,欢迎 Twitter @briandemers!
示例代码
https://github.com/oktadeveloper/jaxrs-spring-blog-example
Rest API By JAX-RS 实现接口发布的更多相关文章
- WebService—CXF—实现接口发布和客户端调用
(一)接口发布的几种方式 定义接口: @WebService(targetNamespace="http://www.itfad.net/queryUser") public in ...
- swagger2接口发布demo
1.目的:使用Swagger2发布接口,ui可操作 2.项目结构 3. 代码 3.1 接口类qinfeng.zheng.api.controller.DemoController package q ...
- 详解Net Core Web Api项目与在NginX下发布
前言 本文将介绍Net Core的一些基础知识和如何NginX下发布Net Core的WebApi项目. 测试环境 操作系统:windows 10 开发工具:visual studio 2019 框架 ...
- .NET Core WEB API使用Swagger生成在线接口文档
1项目引用Swashbuckle.AspNetCore程序集和Microsoft.Extensions.PlatformAbstractions程序集 右击项目打开"管理NuGet程序包.. ...
- WebService—CXF整合Spring实现接口发布和调用过程
一.CXF整合Spring实现接口发布 发布过程如下: 1.引入jar包(基于maven管理) <!-- cxf --> <dependency> <groupId> ...
- 使用JDK自带功能,实现一个简单的Web Service接口发布
万事开头难,本篇文章的目的就是使用JDK自带的功能,实现一个最简单的Web Service接口的发布. 下图是项目的组成,主要有三个部分,一个接口(WS),一个接口的实现类(WSImp),还有一个接口 ...
- PHP服务器端API原理及示例讲解(接口开发)
http://www.jb51.net/article/136816.htm 下面小编就为大家分享一篇PHP服务器端API原理及示例讲解(接口开发),具有很好的参考价值,希望对大家有所帮助 相信大家都 ...
- 微信小程序语音识别服务搭建全过程解析(https api开放,支持新接口mp3录音、老接口silk录音)
silk v3(或新录音接口mp3)录音转olami语音识别和语义处理的api服务(ubuntu16.04服务器上实现) 重要的写在前面 重要事项一: 所有相关更新,我优先更新到我个人博客中,其它地方 ...
- 使用ASP.NET Web API Help Pages 创建在线接口文档
操作步骤 1.新建Web API项目 2.在项目Areas文件夹下找到以下文件,取消注释图中代码. 3.右键解决方案,属性,如图设置. 4.运行程序,点击右上角API 接口列表: 详情-无参数: 详情 ...
随机推荐
- configure.ac中AC_CHECK_LIB的问题
编译Linux程序时,使用configure.ac生成的configure程序,时常会出现AC_CHECK_LIB检查某个库失败 而相应库通常是存在的,只是依赖于其他的库,此时,需要乃至AC_CHEC ...
- [UML] 如何找参与者、找用例
如何找参与者 1.谁会来使用这个系统? 2.谁会来安装这个系统? 3.谁会来启动这个系统? 4.谁会来维护这个系统? 5.谁会来关闭这个系统? 6.哪些系统会来使用这个系统? 7.谁会从这个系统获取信 ...
- 使用scrapy爬取金庸小说目录和章节url
刚接触使用scrapy的时候,如果一开始就想实现特别复杂的配置,显然是不太现实的,用一些小的例子可以帮助自己理解各个模块. 今天的目标:爬取http://www.luoxia.com/shendiao ...
- 训练指南 UVA - 10917(最短路Dijkstra + 基础DP)
layout: post title: 训练指南 UVA - 10917(最短路Dijkstra + 基础DP) author: "luowentaoaa" catalog: tr ...
- 使用IIFE(立即执行函数)让变量私有化
今天去看了一个GITHUB上的开源项目,在客户端JS的脚本编写的时候,代码中多次使用了IIFE. 一开始我是懵逼的,不知道这种函数的意义何在,小菜鸟嘛. 后面我去研究了一番.发现了它的主要作用就是:让 ...
- ba resme
Resume Name: Zhou Heng Gender: Male Email : jackyzhouheng@gmail.com Self Assessment: I have more tha ...
- POJ 2763 Housewife Wind(树链剖分+树状数组)
[题目链接] http://poj.org/problem?id=2763 [题目大意] 在一棵树上,给出一些边的边长,有修改边的边长的操作, 询问每次从当前点到目标点的最短距离 [题解] 树链剖分之 ...
- Bootstrap-datetimepicker日期插件简单使用
写在前面: 日期组件有很多,这里简单的记录下bootstrap的一个日期插件datetimepicker,使用方法比较简单,基本上看一些就会了,但是还是记录下. 这个就不过多的说了,简单粗暴上代码 & ...
- pythonGUI编程用Canvas模拟画板
代码如下: from tkinter import * import webbrowser root = Tk() w = Canvas(root,width=400,height=200) w.pa ...
- SVN 文件删除及恢复
SVN 文件删除及恢复 在TortoiseSVN管理的项目中删除文件的方法: 1. 在客户端按delete删除(OS中删除,不通过SVN) ● 未提交之前一旦Update则被删 ...