通过Spring构建RESTful Web Service

以下教程翻译自Spring官方网站(spring.io), 原文名(Building a RESTful Web Service), 原文引用地址请查看(http://spring.io/guides).

本教程将指引你通过Spring来快速构建一个RESTful Web Service的"hello world"工程.

目标:
构建的服务将从此地址接收HTTP GET请求

http://localhost:8080/greeting

回应将是JSON格式的问候语

{
    "id":1,
    "content":"Hello, World!"
}

可以在查询字符串中通过可选的name参数自定义问候语

http://localhost:8080/greeting?name=User

name参数的值覆盖了默认的值:"World",并反射到回应中:

{
    "id":1, 
    "content":"Hello, User!"
}

你需要:
大概15分钟时间
准备好你最喜欢的编辑器或IDE
JDK 1.8以上版本
Gradle 2.3+或Maven 3.0+
你也可以使用Spring Tool Suite(STS)直接从此网页导入代码

如何完成此教程
就和其他Spring起步教程一样, 你既可以从头开始构建整个项目, 或者跳过一些你已非常熟悉的基础部分. 不论怎样你都将编写代码以完成项目.

从头开始, 前往使用Gradle构建.

如果想要跳过一些基础部分, 按照下面的方式做:
下载并解压本教程源代码或使用Git工具:

git clone https://github.com/spring-guides/gs-rest-service.git
cd into gs-rest-service/initial
跳到创建资源表示class一节

创建一个资源表示class
现在你应该已经设置好了项目和构建系统, 可以开始创建web service了.

首先思考service是如何互动的.

service处理提交到/greeting的GET请求, 或许带有name参数的查询字符串(原文: Query String). GET请求应该返回JSON格式的问候响应. 看起来像这样:

{
    "id":1,
    "content":"Hello, World!"
}

对于每个问候id字段都是唯一的标识符, 而content字段则是表示问候的文本内容.

现在创建一个资源表示class为这个问候建模. 编写一个POJO类和相应字段, 构造器, 设置器等:

src/main/java/hello/Greeting.java
package hello;
public class Greeting {
    private final long id;
    private final String content;
    public Greeting(long id, String content) {
        this.id = id;
        this.content = content;
    }
    public long getId() {
        return id;
    }
    public String getContent() {
        return content;
    }
}

你马上就会看到Spring使用Jackson JSON库自动封送Greeting类型的实例到JSON中.

现在创建一个操作这些问候的资源控制器.
为了在Spring中达到建立RESTful web services服务, HTTP请求需由控制器处理. 可以轻易的使用@RestController注解标识出这些组件, 下面的GreetingController所处理的发送到/greeting的GET请求将返回一个Greeting的新实例:

src/main/java/hello/GreetingController.java
package hello;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GreetingController {
    private static final String template = "Hello, %s!";
    private final AtomicLong counter = new AtomicLong();

    @RequestMapping("/greeting")
    public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) {
        return new Greeting(counter.incrementAndGet(),
                            String.format(template, name));
    }
}

这个控制器简洁且简单, 但也并非表面上看起来那么简单, 我们一步一步来看看发生了些什么.

首先@RequestMapping注解确保对/greeting的HTTP请求确实被映射到了greeting()方法.

上面这个例子并未明确GET, PUT和POST等等这些提交方法, 因为默认情况下@RequestMapping映射所有的HTTP操作. 使用@RequestMapping(method=GET)可以缩小映射范围.

@RequestParam将查询字符串中的name参数的值绑定到greeting()方法的参数name上. 这个查询字符串参数是显式的标识为可选项(required=true by default), 如果没有指定此参数则默认值为"World".

在方法体中构建并返回了一个新的Greeting对象, id字段被初始化为从counter获得的, 下一个值, content字段则使用给定的name参数格式化为相应的问候语.

RESTful Web Service控制器和传统的MVC控制的的主要不同之处在于HTTP响应创建的方式. 与其依靠某种视图技术获得服务端的问候数据并最终经由HTML呈现, RESTful web service控制器直接填充并返回一个Greeting对象, 对象数据将以JSON格式直接写入HTTP响应中.

这段代码使用了最新的Spring 4中的@RestController注解, 这个注解标识了这个类下的所有方法均返回一个域对象(domain object)而非一个视图. 也相当于同时有@Controller和@ResponseBody两个注解的简写.

Greeting对象必须装换为JSON格式, 有了Spring的HTTP消息装换的支持就不用你手工编码完成装换了. 我们现在有Jackson 2在类路径下, Spring的MappingJacksonHttpMessageConverter将自动完成转换.

让程序开始运行

尽管也可以将程序打包为传统的WAR文件, 然后部署到某个外部的应用服务器上, 下面演示了一个更简便的创建应用程序的方法. 打包所有东西为一个可执行的JAR文件, 通过一个老式的java main()方法来启动. 一直以来, 你都使用Spring内嵌支持的Tomcat servlet容器作为HTTP运行时容器, 而非部署到某个外部实例去.

src/main/java/hello/Application.java
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

@SpringBootApplication注解可以方便的开启下列所有注解:

@Configuration 标记这个类包含应用程序上下文中的bean声明

@EnableAutoConfiguration 通知Spring Boot基于类路径, 其他bean和各种属性设置来添加bean.

通常你在Spring MVC应用程序中都会用到@EnableMvc注解, 但Spring Boot自动的在类路径下寻找spring-webmvc的类并自动注解为@EnableMvc. 这标志着此应用是Web应用程序, 且激活了多个关键行为, 如设置了DispatcherServlet.

@ComponentScan告诉Spring在hello这个包中寻找其他组件, 设置和服务, 允许找到控制器.

main()方法使用了Spring Boot的SpringApplication.run()方法启动整个应用程序. 你注意到没有一行XML了吗? web.xml也没有哦. 这个Web应用程序是100%有Java写成的, 你完全不必配置任何龟毛.

生成可执行的JAR
你可以通过Gradle或Maven在命令行来启动应用程序. 或者你也可以构建一个单独的可执行JAR文件, 文件里包含了所有必须的依赖, 类和资源. 这使得更易于传递, 版本控制和在应用程序的开发周期中跨越不同的环境来部署服务, 等等.

如果你使用Gradle, 你可以使用./gradlew bootRun来允许应用程序. 或者你也可以使用./gradlew build来构建新的JAR文件. 接着就可以运行这个JAR文件了.

java -jar build/libs/gs-rest-service-0.1.0.jar

如果你使用Maven, 则通过./mvnw spring-boot:run来启动程序. 或者使用./mvnw clean package来编译生成可执行的JAR文件. 接着就可以运行这个JAR文件了.

java -jar target/gs-rest-service-0.1.0.jar
上面的指导都将创建可执行的JAR文件. 当然你也可以生成传统的WAR文件

日志信息开始输出后用不了几分钟服务就将启动并开始运行了.

测试服务
现在, 服务以及启动了, 访问 http://localhost:8080/greeting, 你将看到:

{
    "id":1,
    "content":"Hello, World!"
}

提供一个查询字符串参数 http://localhost:8080/greeting?name=User. 注意content属性的值将从"Hello World!"变为"Hello, User!".

这个改变展示了@RequestParam注解对Greeting控制器所做的安排是预期的. name参数先被设置为默认的值"World", 之后也能被显式的指定参数而覆盖为查询字符串的值.

注意id字段同样有1变为了2. 这证明了你经由不同的请求但依然在和同一个GreetingController实例打交道, 而且counter字段也随着每次调用递增了.

摘要
恭喜! 你已经通过Spring实现了一个RESTful风格的web service应用.

This article are released with an ASLv2 license for the code, an Attribution NoDerivatives creative commons license for the writing.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,099评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,828评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,540评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,848评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,971评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,132评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,193评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,934评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,376评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,687评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,846评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,537评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,175评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,887评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,134评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,674评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,741评论 2 351

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,642评论 18 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,783评论 6 342
  • spring官方文档:http://docs.spring.io/spring/docs/current/spri...
    牛马风情阅读 1,653评论 0 3
  • 此篇翻译的是Spring Boot官方指南 Part III. 使用 Spring Boot (Using Spr...
    K天道酬勤阅读 6,726评论 0 21
  • 一般的腿上刺了个洞要几个星期才会好,要是大众的话要一年或者两年多才会好的,可是我刺上个的这个小动一个星期就好了,...
    董培炎阅读 302评论 1 1