• Spring Boot Actuator构建RESTful We服务


    Spring Boot Actuator是Spring Boot的一个子项目。它在你的应用程序中增加了几个生产级的服务,而你只需做很少的工作。在本指南中,你将建立一个应用程序,然后看看如何添加这些服务。

    What You Will build

    本指南将带领您使用Spring Boot Actuator创建一个"Hello, world "RESTful Web服务。你将建立一个接受以下HTTP GET请求的服务。

    $ curl http://localhost:9000/hello-world
    

    它响应的是以下JSON。

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

    还有许多功能添加到你的应用程序中,以便在生产(或其他)环境中管理服务。你所构建的服务的业务功能与Building a RESTful Web Service]中的相同。你不需要使用那个指南来利用这个指南,尽管比较一下结果可能很有趣。

    What You Need

    • 大约15分钟
    • 你喜欢的文本编辑器或IDE
    • JDK 1.8 以上
    • Graddle 4+ 或 Maven 3.2+
    • 你也可以直接将代码导入进你的IDE
      • Spring Tool Suite (STS)
      • InteelliJ IDEA

    How to complete this guide

    正如Spring大多数指南一样,你可以从头开始并且完成每一个步骤或者你可以绕开你已经熟悉的基本设置。无论哪种方式,你最终都是完成代码。

    为了从头开始,移步到Starting with Spring Initializr

    为了跳过基础,做如下步骤:

    • 下载并解压这篇指南的原仓库,或者使用GIt克隆git clone https://github.com/spring-guides/gs-actuator-service.git
    • 进入(cd)gs-actuator-service/initial
    • 移步到Create a Representation Class

    当你完成以后,你可以再次检查你的gs-actuator-service/complete的代码。

    Starting with Spring Initializr

    你可以使用预初始化项目点击Generate来下载ZIP文件。这一项目被配置为适合本篇指南。

    为了手动初始化项目:

    1. 浏览https://start.spring.io/。这个服务拉取了你的应用所有需要的依赖并且已经为了做了多数配置。
    2. 选择Gradle或Maven与你想使用的语言。本文假设你选择Java。
    3. 点击Dependencies选择Spring WebSpring Boot Actuator
    4. 点击Generate
    5. 下载ZIP文件,这是一个为你的选择配置好的网络应用文件。

    如果你的IDE整合了Spring Initializr,你可以从你的IDE完成此步骤

    你也可以从GitHub中fork此项目使用你的IDE或者编辑器打开。

    Run the Empty Service

    Spring Initializr创建了一个空的应用程序,你可以用它来入门。下面的例子(来自初始目录中的src/main/java/com/example/actuatorservice/ActuatorServiceApplication)展示了Spring Initializr创建的类。

    package com.example.actuatorservice;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class ActuatorServiceApplication {
    
      public static void main(String[] args) {
        SpringApplication.run(ActuatorServiceApplication.class, args);
      }
    
    }
    

    @SpringBootApplication注解根据你的classpath和其他东西的内容,提供了一系列的默认值(如嵌入式servlet容器)。它还开启了Spring MVC的@EnableWebMvc注解,激活了Web端点。

    在这个应用程序中没有定义端点,但有足够的东西来启动东西,并看到Actuator的一些功能。SpringApplication.run()命令知道如何启动Web应用程序。你所需要做的就是运行下面的命令。

    $ ./gradlew clean build && java -jar build/libs/gs-actuator-service-0.1.0.jar
    

    你还没有写任何代码,那么发生了什么?要想知道答案,请等待服务器启动,打开另一个终端,并尝试以下命令(显示其输出)。

    $ curl localhost:8080
    {"timestamp":1384788106983,"error":"Not Found","status":404,"message":""}
    

    前面命令的输出表明,服务器正在运行,但你还没有定义任何业务端点。你看到的不是默认的容器生成的HTML错误响应,而是一个来自Actuator /error端点的通用JSON响应。你可以从服务器启动时的控制台日志中看到哪些端点是开箱即用的。你可以尝试这些端点中的几个,包括/health端点。下面的例子显示了如何做到这一点。

    $ curl localhost:8080/actuator/health
    {"status":"UP"}
    

    状态是UP,所以执行器(actuator)服务正在运行。

    更多细节请参见Spring Boot的Actuator Project

    Create a Representation Class

    首先,你需要考虑一下你的API会是什么样子。

    你想处理对/hello-world的GET请求,可以选择使用一个名称查询参数。在响应这样的请求时,你想送回JSON,代表一个问候语,它看起来像下面的内容。

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

    id字段是问候语的唯一标识符,content包含问候语的文本表述。

    为了给问候表示法建模,创建一个表示法类。下面的列表(来自src/main/java/com/example/actuatorservice/Greeting.java)显示了问候类。

    package com.example.actuatorservice;
    
    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;
      }
    
    }
    

    现在,你需要创建端点控制器,为表示类提供服务。

    Create a Resource Controller

    在Spring中,REST端点就是Spring MVC控制器。下面的Spring MVC控制器(来自src/main/java/com/example/actuatorservice/HelloWorldController.java)处理对/hello-world端点的GET请求并返回Greeting资源。

    package com.example.actuatorservice;
    
    import java.util.concurrent.atomic.AtomicLong;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    @Controller
    public class HelloWorldController {
    
      private static final String template = "Hello, %s!";
      private final AtomicLong counter = new AtomicLong();
    
      @GetMapping("/hello-world")
      @ResponseBody
      public Greeting sayHello(@RequestParam(name="name", required=false, defaultValue="Stranger") String name) {
        return new Greeting(counter.incrementAndGet(), String.format(template, name));
      }
    
    }
    

    面向人的控制器和REST端点控制器的关键区别在于如何创建响应。端点控制器不是依靠视图(如JSP)来渲染HTML中的模型数据,而是返回数据,直接写入响应的主体。

    @ResponseBody注解告诉Spring MVC不要将模型渲染到视图中,而是将返回的对象写入响应体中。它通过使用Spring的一个消息转换器来做到这一点。因为Jackson 2在classpath中,MappingJackson2HttpMessageConverter将处理Greeting对象到JSON的转换,如果请求头的Accept指定JSON应该被返回。

    你怎么知道Jackson 2在classpath上?运行mvn dependency:tree./gradlew dependencies,你会得到一个包括Jackson 2.x的详细依赖树。你也可以看到它来自/spring-boot-starter-json,它本身被spring-boot-starter-web导入。

    Run the Application

    你可以从一个自定义的主类或直接从一个配置类中运行应用程序。对于这个简单的例子,你可以使用SpringApplication辅助类。注意,这是Spring Initializr为你创建的应用类,你甚至不需要修改它就可以为这个简单的应用工作。下面的列表(来自src/main/java/com/example/actuatorservice/HelloWorldApplication.java)显示了这个应用类。

    package com.example.actuatorservice;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class HelloWorldApplication {
    
      public static void main(String[] args) {
        SpringApplication.run(HelloWorldApplication.class, args);
      }
    
    }
    

    在传统的Spring MVC应用中,你会添加@EnableWebMvc来开启关键行为,包括配置DispatcherServlet。但是Spring Boot在检测到classpath上的spring-webmvc时,会自动打开这个注解。这为你在接下来的步骤中建立一个控制器做了准备。

    @SpringBootApplication注解还引入了一个@ComponentScan注解,它告诉Spring扫描com.example.actuatorservice包中的那些控制器(以及任何其他注解的组件类)。

    Build an executable JAR

    你可以在命令行以Gradle或Maven运行应用程序。你也可以构建一个单一可执行的JAR包,其中包含所有必须的依赖、类以及资源并且运行。构建一个可执行jar可以易于传输、版本和部署服务作为应用,贯穿至整个开发周期,穿插于不同环境等等。

    如果你使用Gradle,你可以通过使用./gradlew bootRun来运行应用程序。或者说,你可以使用./gradlew build来构建JAR包,然后运行JAR包,如下命令:

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

    如果你使用Maven,你可以通过./mvnw spring-boot:run来运行应用程序。或者说,你可以使用./mvnw clean package来构建JAR包,通过如下命令执行JAR包。

    java -jar target/gs-actuator-service-0.1.0.jar
    

    此处步骤描述了创建一个可执行JAR包。你也可以构造一个经典的WAR文件

    一旦服务运行(因为你在终端中运行了spring-boot:run),你可以在单独的终端中运行以下命令来测试它。

    $ curl localhost:8080/hello-world
    {"id":1,"content":"Hello, Stranger!"}
    

    Switch to a Different Server Port

    Spring Boot Actuator的默认运行端口为8080。通过添加application.properties文件,你可以覆盖这一设置。下面的列表(来自src/main/resources/application.properties)显示了经过必要修改的该文件。

    server.port: 9000
    management.server.port: 9001
    management.server.address: 127.0.0.1
    

    通过在终端运行以下命令再次运行服务器。

    $ ./gradlew clean build && java -jar build/libs/gs-actuator-service-0.1.0.jar
    

    该服务现在在9000端口启动。

    你可以通过在终端运行以下命令来测试它是否在9000端口工作。

    $ curl localhost:8080/hello-world
    curl: (52) Empty reply from server
    $ curl localhost:9000/hello-world
    {"id":1,"content":"Hello, Stranger!"}
    $ curl localhost:9001/actuator/health
    {"status":"UP"}
    

    Test Your Application

    为了检查你的应用程序是否工作,你应该为你的应用程序编写单元和集成测试。src/test/java/com/example/actuatorservice/HelloWorldApplicationTests.java中的测试类可以确保

    • 你的控制器是有反应的。
    • 你的管理端点是有反应的。

    请注意,这些测试在一个随机的端口上启动应用程序。下面的列出显示了测试类。

    package com.example.actuatorservice;
    
    import java.util.Map;
    
    import org.junit.jupiter.api.Test;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.boot.test.web.client.TestRestTemplate;
    import org.springframework.boot.web.server.LocalServerPort;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.test.context.TestPropertySource;
    
    import static org.assertj.core.api.BDDAssertions.then;
    
    /**
     * Basic integration tests for service demo application.
     *
     * @author Dave Syer
     */
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
    @TestPropertySource(properties = {"management.port=0"})
    public class HelloWorldApplicationTests {
    
      @LocalServerPort
      private int port;
    
      @Value("${local.management.port}")
      private int mgt;
    
      @Autowired
      private TestRestTemplate testRestTemplate;
    
      @Test
      public void shouldReturn200WhenSendingRequestToController() throws Exception {
        @SuppressWarnings("rawtypes")
        ResponseEntity<Map> entity = this.testRestTemplate.getForEntity(
            "http://localhost:" + this.port + "/hello-world", Map.class);
    
        then(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
      }
    
      @Test
      public void shouldReturn200WhenSendingRequestToManagementEndpoint() throws Exception {
        @SuppressWarnings("rawtypes")
        ResponseEntity<Map> entity = this.testRestTemplate.getForEntity(
            "http://localhost:" + this.mgt + "/actuator", Map.class);
        then(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
      }
    
    }
    
  • 相关阅读:
    题目:有一对兔子,从出生第三个月起每个月都生一对兔子,小兔子长到第三个月后,每个月又生一对兔子,假如兔子都不死,问M个月时兔子的数量,M为键盘读入的正整数。(请用java语言作答)
    无聊游戏随笔--学院篇
    Java数组冒泡,选择,插入三种常用排序法及自带的快速排序法
    js写年月日三级下拉列表框
    查询避免Unknown column ‘xxx’ in ‘where clause’
    MyEclipse运行web程序报错,先检查这几点!
    Servlet开发之中线程安全问题
    取消Eclipse等号、分号、空格代码自动补全
    try/catch、finally语句的执行顺序测试
    02-MySQL双机热备的搭建
  • 原文地址:https://www.cnblogs.com/geekfx/p/16220483.html
Copyright © 2020-2023  润新知