0.1 我们要做的事情

我们将构建任何浏览器都可以访问的经典的 “Hello World!”程序,包括传统的 Web 和 RESTful 服务两种运行方式。你甚至可以告诉它你的名字,它会以更友好的方式回应。

0.2 我们需要什么

(1)集成开发环境
比较流行的Java集成开发环境(IDE)包括IntelliJ IDEASpring ToolsVisual Studio CodeEclipse等。我们选择使用IntelliJ IDEA。

(2)JDK
我们推荐使用Adopt OpenJDK版本 11 (不要用 JDK 8了,太古老了,有的新代码会直接导致 JDK 8 JVM 崩溃)。

0.3 创建一个新的工程

本节我们用两种不同的方法创建新工程,一种是使用官方的工具Spring Initializr,另外一种是使用IntelliJ IDEA内置的插件。

0.3.1 使用Spring Initializr创建工程

访问 https://start.spring.io 使用Spring Initializr创建 Web 项目。如下图所示,Project类型选择Maven、语言选择Java,Spring Boot选择最新非SNAPSHOP版本,在 “依赖项(Dependencies)” 对话框中搜索并添加 “Spring Web” 依赖项。
image.png
点击 “GENERATE” 按钮,下载zip,然后将其解压缩到计算机上的文件夹中。

0.3.2 使用IntelliJ IDEA创建工程

使用IntelliJ IDEA的时候,可以直接在软件的欢迎页点击 Create New Projecr直接创建工程。
image.png
在左边点击Spring Initializr(可以看到它实际上调用也是https://start.spring.io),右边的 Project SDK 选择 JDK 11(关于JDK 11的安装请阅读本知识库中关于基础开发环境准备的内容):
image.png
下一步
image.png
再下一步在依赖界面选中Spring Web
截屏2021-05-30 下午6.49.07.png
输入期望的项目名称和目录位置
截屏2021-05-30 下午6.50.50.png
软件会提示要创建目录
截屏2021-05-30 下午6.51.23.png

现在在左侧可以看到生成的项目中的文件
image.png

0.3.3 说明

使用Spring Initializr创建的项目包含 Spring Boot,该框架使Spring可以在你的应用程序中运行,但不需要太多代码或配置。

0.4 实现传统Web功能

0.4.1 增加需要的代码

在IDE中打开项目并找到src/main/java/com.example.demo目录中的 DemoApplication.java 文件,通过添加下面代码中显示的额外方法和注解来更改文件的内容。尽管你可以复制并粘贴代码,但最好还是花点儿时间自己键入这些代码,尽管这样会多花一些时间,但它非常有助于你理解这些代码。
(1)import需要的类

  1. import org.springframework.web.bind.annotation.GetMapping;
  2. import org.springframework.web.bind.annotation.RequestParam;
  3. import org.springframework.web.bind.annotation.RestController;

(2)为DemoApplication类增加@RestController注解

  1. @SpringBootApplication
  2. +@RestController
  3. public class DemoApplication {

(3)为DemoApplication类增加方法

  1. @GetMapping("/hello")
  2. public String hello(@RequestParam(value = "name", defaultValue = "World") String name) {
  3. return String.format("Hello %s!", name);
  4. }

我们添加的 hello() 方法接受一个叫 name 的字符串参数,在代码中把这个参数和 “Hello“ 组合在一起。这意味着如果你在请求中将姓名设置为 “David“,那么响应的结果将是 “Hello David”。

main()方法使用Spring Boot的SpringApplication.run()方法启动应用程序。你是否注意到没有一行XML? 也没有web.xml文件。这个网络应用程序是100% 纯Java,你不必处理配置任何管道或基础设施。

0.4.2 几个注解的说明

以 @开头的是Spring的注解,下面是代码中注解的说明:

  • @SpringBootApplication 是添加以下所有内容的便利注释:

    • @Configuration
      将类标记为应用程序上下文的bean定义源
    • @EnableAutoConfiguration
      告诉Spring Boot根据类路径设置、其他bean和各种属性设置开始添加bean. 例如, 若 spring-webmvc 在类路径上,此注释将应用程序标记为web应用程序并激活关键行为, 如设置 DispatcherServlet
    • @ComponentScan
      告诉Spring在com/example包中寻找其他组件、配置和服务,让它找到控制器.
  • @RestController
    告诉Spring此代码描述了应在Web上提供的访问点。

  • @GetMapping(“/hello”)
    告诉Spring使用 hello()方法应答发到地址http://localhost:8080/hello的请求。
  • @RequestParam
    告诉Spring在请求中期待一个名为name的值,但是如果没有这个值就使用单词 “World”做默认值。

    0.4.3 运行并访问

    尽管可以在命令行 (或终端)的用命令来构建和运行应用程序,但更方便的做法是在IntelliJ IDEA中直接运行:点击右边顶部的运行图标:
    image.png
    您应该会看到一些看起来与此非常相似的输出:
    image.png
    这里的最后几行告诉我们Spring已经开始运行,使用Spring Boot的嵌入式Apache Tomcat服务器充当web服务器,正在侦听localhost的8080端口。打开浏览器,在顶部的地址栏输入 http://localhost:8080/hello,你将得到类似下面这样的友好的响应:
    image.png
    在URL地址后加上 ?name=David
    image.png

    0.5 创建RESTful Web服务

    我们创建的服务将处理来自地址/greetingGET 请求(查询字符串中的 name 参数是可选的)。GET 请求应返回 200 OK,在表示问候语的正文中使用JSON进行响应,它应该类似于以下输出:
    1. {
    2. "id": 1,
    3. "content": "Hello, World!"
    4. }
    id 字段是问候语的唯一标识符,content 是问候的文本内容。

    0.5.1 创建数据类

    我们创建一个资源表示类来对问候语进行建模。 为此设计一个带有字段和构造函数的普通Java对象。

在左边的demo文件夹上按鼠标右键新建一个名为Greeting的Java类
image.png
下面是这个类的完整代码:

  1. package com.example.demo;
  2. public class Greeting {
  3. private final long id;
  4. private final String content;
  5. public Greeting(long id, String content) {
  6. this.id = id;
  7. this.content = content;
  8. }
  9. public long getId() {
  10. return id;
  11. }
  12. public String getContent() {
  13. return content;
  14. }
  15. }

0.5.2 创建控制器类

在Spring构建RESTful Web服务的方法中,HTTP请求由由 @RestController 注解定义的控制器来处理。下面是具体的代码,期中 GreetingController 处理/greetingGET请求,返回Greeting类的一个新实例。

  1. package com.example.demo;
  2. import java.util.concurrent.atomic.AtomicLong;
  3. import org.springframework.web.bind.annotation.GetMapping;
  4. import org.springframework.web.bind.annotation.RequestParam;
  5. import org.springframework.web.bind.annotation.RestController;
  6. @RestController
  7. public class GreetingController {
  8. private static final String template = "Hello, %s!";
  9. private final AtomicLong counter = new AtomicLong();
  10. @GetMapping("/greeting")
  11. public Greeting greeting(@RequestParam(value = "name", defaultValue = "World") String name) {
  12. return new Greeting(counter.incrementAndGet(), String.format(template, name));
  13. }
  14. }

代码中使用了Spring的 @RestController 注解,它将类标记为控制器,其中每个方法返回域对象而不是视图。它是包含 @Controller@ResponseBody 两个注解的速记。

传统的MVC控制器和这里RESTful Web服务控制器之间的关键区别是HTTP响应正文的创建方式。RESTful Web服务控制器不是依靠视图技术将问候语数据在服务器端呈现为HTML,它填充并返回Greeting对象. 对象数据将以JSON格式直接写入HTTP响应中。

@RequestParam 绑定查询字符串参数name的值给 greeting() 方法的name参数。如果请求中没有name参数,就会使用defaultValue 定义的默认值“World”。

方法的主体创建并返回一个有idcontent属性的新 Greeting 对象,期中id基于counter的下一个值,content则使用greeting的模板来格式化给定的 name

(Web Starter中自动包含了Jackson JSON)。

Greeting对象必须转换为JSON。这里感谢Spring的HTTP消息转换器的支持,我们无需手动进行此转换,因为 Jackson JSON 在类路径上,Spring的 [MappingJackson2HttpMessageConverter](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/http/converter/json/MappingJackson2HttpMessageConverter.html)自动使用 Jackson JSON 库自动把Greeting类的实例封装转为为JSON对象。

0.5.3 重新启动并访问

点击集成开发环境右上角重新启动应用程序的图标
image.png
image.png
在浏览器中访问地址http://localhost:8080/greeting,可以得到如下的结果:

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

把访问地址改成http://localhost:8080/greeting?name=David,得到如下的结果:

  1. {"id":2,"content":"Hello, David!"}

这一变化表明安排在GreetingController中的 @RequestParam 按预期工作了。name参数参数的默认值World可以通过查询字符串显式地覆盖。

还请注意id属性已从1变为2。这证明你工作在跨多个请求的GreetingController同一实例,并且其他的counter字段将按预期在每次调用上递增。

0.6 总结

本章教程简明地展示了使用Spring Boot是实现传统 Web 功能和 RESTful 服务的方法。后续的教程我们将不再讨论各种与传统Web功能有关的设计开发,所有的开发工作最终都以与前端完全分离的 RESTful 服务形式予以展现。常见的Thymeleaf、JSP等技术均不在我们的讨论范围之内

有关前端开发教程,请阅读《Ant Design Pro实战应用手把手教程》。

版权说明:本文由北京朗思云网科技股份有限公司原创,向互联网开放全部内容但保留所有权力。