用Spring Boot启动一个Java REST API

470 阅读2分钟

在本教程中,我将向你展示如何用Spring Boot创建一个安全的REST API和本地图像。你将看到如何运行一个安全的、受OAuth 2.0保护的、允许JWT认证的Java REST API。然后,我将与Micronaut、Quarkus和Helidon比较其性能。

本教程也可作为截屏提供。

先决条件:

一些步骤后面的括号表示我在视频中使用的IntelliJ Live模板。你可以在mraible/idea-live-templates找到模板的定义。

目录

用GraalVM安装JDK

使用SDKMAN用GraalVM安装Java 17

sdk install java 22.1.0.r17-grl

生成一个OAuth 2.0访问令牌

  1. 安装Okta CLI并运行okta register ,以注册一个新账户。如果你已经有一个账户,运行okta login

  2. 运行okta apps create spa 。设置oidcdebugger 作为应用程序名称,然后按回车键

  3. 在重定向URI中使用https://oidcdebugger.com/debug ,并将注销重定向URI设置为https://oidcdebugger.com

  4. 导航到OpenID Connect调试器网站

    1. 填入你的客户ID

    2. 在授权URI中使用/oauth2/default/v1/authorize

    3. 为响应类型选择代码,并使用PKCE

    4. 点击发送请求,继续

  5. 在终端窗口将访问令牌设置为TOKEN 环境变量。

    TOKEN=eyJraWQiOiJYa2pXdjMzTDRBYU1ZSzNGM...
    

启动一个Spring Boot Java REST API

  1. 创建一个支持OAuth 2.0的Spring Boot应用。

    https start.spring.io/starter.zip \
      bootVersion==2.6.7 \
      dependencies==web,oauth2-resource-server,native \
      packageName==com.okta.rest \
      name==spring-boot \
      type==maven-project \
      baseDir==spring-boot | tar -xzvf -
    
  2. 修改pom.xml ,使用tomcat-embed-programmatic ,而不是默认的Tomcat。

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.apache.tomcat.embed</groupId>
                <artifactId>tomcat-embed-core</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.apache.tomcat.embed</groupId>
                <artifactId>tomcat-embed-websocket</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.tomcat.experimental</groupId>
        <artifactId>tomcat-embed-programmatic</artifactId>
        <version>${tomcat.version}</version>
    </dependency>
    
  3. 添加一个HelloController 类,返回用户的信息。[sb-hello]

    package com.okta.rest.controller;
    
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.security.Principal;
    
    @RestController
    public class HelloController {
    
        @GetMapping("/hello")
        public String hello(Principal principal) {
            return "Hello, " + principal.getName() + "!";
        }
    }
    
  4. 通过添加发行者到application.properties ,将该应用配置为OAuth 2.0资源服务器。

    spring.security.oauth2.resourceserver.jwt.issuer-uri=/oauth2/default
    
  5. 添加一个SecurityConfiguration 类来配置JWT认证-[securityconfig]

    package com.okta.rest;
    
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
    
    @EnableWebSecurity
    public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                .authorizeRequests(request -> request.anyRequest().authenticated())
                .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
        }
    }
    

使用HTTPie运行和测试你的Spring Boot REST API

  1. 从你的IDE或使用终端启动你的应用程序。

    ./mvnw spring-boot:run
    
  2. 用访问令牌测试你的API。

    http :8080/hello Authorization:"Bearer $TOKEN"
    

构建一个本地Spring Boot应用程序

  1. 使用native profile将您的Spring Boot应用编译为本地可执行文件。

    ./mvnw package -Pnative
    
    要构建本地应用程序和Docker容器,请使用Spring Boot Maven插件和./mvnw spring-boot:build-image
  2. 启动你的Spring Boot应用。

    ./target/demo
    
  3. 用HTTPie和一个访问令牌来测试它。

    http :8080/hello Authorization:"Bearer $TOKEN"
    

启动时间比较

在记录数字之前,我通过运行每个图像三次来比较各框架的启动时间。然后,我又将每个应用运行了五次,并对结果进行了平均。我在一台配备固态硬盘、2.4 GHz 8核英特尔酷睿i9处理器和64GB内存的2019年MacBook Pro上收集这些数字。

内存使用情况比较

我使用下面的命令测试了每个应用程序的内存使用情况(以兆字节为单位)。我在启动应用程序后立即运行了它,在一个认证请求后,以及在五个认证请求后。

ps -o pid,rss,command | grep --color <executable> | awk '{$2=int($2/1024)"M";}{ print;}'