我尝试使用Spring Boot创建应用程序【REST API开发】

创建项目

Project: Maven

Language: Java

SpringBoot: 3.0.12

Group: simple_spring_restapi

Artifact: simple_spring_restapi

Name : simple_spring_restapi

Description: Demo project for Spring Boot

Package name: simple_spring_restapi

依赖

    • Spring Boot DevTools

 

    Spring Web

创建一个Docker容器

创建.devcontainer文件夹、devcontainer.json文件和docker-compose.yml文件。

{
  "name": "workspace",
  "dockerComposeFile": "docker-compose.yml",
  "service": "workspace",
  "workspaceFolder": "/home/vscode/workspace",
  "remoteUser": "vscode",
  "shutdownAction": "stopCompose",
  "customizations": {
    "vscode": {
      "extensions": [
        "vscjava.vscode-java-pack",
        "vscjava.vscode-spring-initializr",
        "vscjava.vscode-gradle"
      ]
    }
  }
}

创建docker/workspace文件和Dockerfile。

# イメージのベースとなるイメージを指定
FROM ubuntu:22.04

# イメージのベースとなるイメージを指定(Mac用)
# FROM arm64v8/alpine:latest

# イメージに追加するファイルを指定
ARG USERNAME=vscode
ARG USER_GROUP_NAME=workspace
ARG USER_UID=1000
ARG USER_GID=1000

ARG PKG="git vim curl unzip zip"

# イメージの起動時に実行するコマンドを指定
SHELL [ "/bin/bash","-c" ]

RUN apt-get update \
    && apt-get install -y ${PKG} \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/* \
    && grouapp --gid ${USER_GID} ${USER_GROUP_NAME} \
    && useradd --uid ${USER_UID} --shell /bin/bash --gid ${USER_GID} -m{USERNAME} \
    && echo %${USER_GROUP_NAME} ALL=\(ALL\) NOPASSWORD:ALL > /etc/sudoers.d/${USER_GROUP_NAME} \
    && chmod 0440 /etc/sudoers.d/${USER_GROUP_NAME}

## JAVAの環境構築
ARG JAVA _VARSION=18.0.2-amzn
ARG GRADLE_VARSION=7.5

RUN su ${USERNAME} --command \
    'curl -s "https//get.sdkman.io" | bash \
    && source "${HOME}/.sdkman/bin/sdkman-init.sh" \
    && sdk install java "${JAVA_VARSION}" \
    && sdk install gradle "${GRADLE_VARSION}"'

编辑docker-compose.yml

version: '3.9'

services:
  workspace:
    container_name: ${PROJECT_NAME:default}-workspace
    build:
      context: ./docker/workspace
      args:
        USERNAME: ${USERNAME:-vscode}
        USER_GROUP_NAME: ${USER_GROUP_NAME:-workspace}
        USER_UID: ${USER_UID:-1000}
        USER_GID: ${USER_GID:-1000}
    tty: true
    volumes:
      - ../:/home/${USERNAME:-vscode}/workspace:cached
    ports:
      - '8080:8080'

在.devcontainer中创建.env文件。


PROJECT_NAME=simple-spring-restapi

USERNAME=vscode
USER_GROUP_NAME=workspace
USER_UID=1000
USER_UID=1000

进行Docker Compose.yml文件的构建

docker compose.yml build

创建控制器

创建一个名为 “src/main/java/simple_spring_restapi” 的文件夹,并在其中创建一个名为 “controllers” 的文件夹和一个名为 “TodoController.java” 的文件。

package simple_spring_restapi.controller;

import java.net.URI;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import jakarta.validation.Valid;
import simple_spring_restapi.models.TodoItem;
import simple_spring_restapi.services.TodoService;

@RequestMapping(path = TodoController.BASE_URL)
@RestController
public class TodoController {
    public static final String BASE_URL = "/api/v1/todos";
    @Autowired
    private TodoService _todoService;

    @GetMapping(path = "")
    public ResponseEntity<List<TodoItem>> getTodoItems() {
        List<TodoItem> todoItems = _todoService.getTodoItems();
        return ResponseEntity.ok(todoItems);
    }

    @GetMapping(path = "/{id}")
    public ResponseEntity<TodoItem> getTodoItems(@PathVariable int id) {
        TodoItem found = _todoService.getTodoItemById(id);
        return ResponseEntity.ok(found);
    }

    @PostMapping(path="")
    public ResponseEntity<todoItem> creteTodoItems(@Valid @RequestBody TodoItem newTodoItem) {
        TodoItem saveTodoItem = _todoService.saveTodoItem(newTodoItem);
        URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}");
             .bulidAndExpand(saveTodoItem.getId()).toUri();
        return ResponseEntity.created(location).body(newTodoItem);
    }

    @PutMapping(path = "/{id}")
    public ResponseEntity<?> updateTodoItems(@RequestBody TodoItem newTodoItem, @PathVariable int id) {
        _todoService.updateTodoItems(id, newTodoItem);
        return ResponseEntity.noContent().build();
    }

    @DeleteMapping(path = "/{id}")
    public ResponseEntity<?> removeTodoItems(@PathVariable int id) {
        _todoService.deleteTodoItem(id);
        return ResponseEntity.noContent().build();
    }

}

在构建.gradle文件中添加implementation ‘org.springdoc:springdoc-openapi-ui:1.6.9’,使得可以使用swagger-ui。

//省略
dependencies {
//省略
	implementation 'org.springdoc:springdoc-openapi-ui:1.6.9'
}

在`src/main/java/simple_spring_restapi`目录下创建一个名为`models`的文件夹和一个名为`TodoItem.java`的文件。

package simple_spring_restapi.models;

import jakarta.persistence.Column;
import jakarta.annotation.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.validation.constraints.NotBlank;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "todos", schema = "business")
public class TodoItem {
    @Id
    @GeneratedValue(strategy = GenerationType.Auto)
    @Column(name = "id", nullable = false)
    private int id;
    @NotBlank(message = "Title must not be blank.")
    @Column(name = "id", nullable = false)
    private String title;

}

将④资源/application.properties更改为application.yaml。


spring:
  jpa:
    database: POSTGRESQL
    hibernate:
      ddl-auto: update
      show-sql: true
    properties:
      hibernate:
        hbm2dll: create_namespaces:true

  datasource:
    url: jdbc:postgresql://${POSTGRES_HOST:-postgres}:${POSTGRES_PORT:5432}/ ${POSTGRES_DB:-dev}
    username: ${POSTGRES_USER:-postgres}
    password: ${POSTGRES_PASSWORD:-postgres}
    driver-class-name: org.postgresql.Driver

在src/main/java/javnautas.fakeapius创建business文件夹、service文件夹和FakeApiService.java文件。



在`src/main/java/javnautas.fakeapius/appv1.dto`目录下创建名为`FakeApiController.java`的文件。

⑦ 使用SpringDoc OpenAPI Starter WebMVC UI,可以为Spring Boot应用程序生成RESTful API的OpenAPI文档。

// 省略
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0'
// 省略

打开 Swagger UI,导入 fake-api 的定义,并生成 API 文档的 HTML 格式。

在instructure文件夹中创建一个entities文件夹,并创建一个名为ProductoEntity.java的文件。

SpringDoc OpenAPI Starter WebMVC UI 是一个用于生成 Spring Boot 应用程序的 RESTful API 的 OpenAPI 文档的 Spring Boot Starter。

创建服务

将以下内容用中文本地化语言进行改写:
在src/main/java/simple_spring_restapi目录下创建一个services文件夹并添加TodoServices.java文件。

在src/main/java/simple_spring_restapi/services目录下创建TodoServiceImplWithoutRepo.java文件。

添加错误处理程序

在src/main/java/simple_spring_restapi中创建errors文件夹和NotFoundException.java文件

在`src/main/java/simple_spring_restapi/errors`目录下创建`BadRequestException.java`文件。

在src/main/java/simple_spring_restapi/errors目录下创建RestResponseEntityExceptionHandler.java文件。

在src/main/java/simple_spring_restapi/errors中创建一个名为ErrorResponse.java的文件。

请在src/main/java/simple_spring_restapi/errors中创建一个名为HttpException.java的文件。

增加模型验证

在build.gradle文件中增加以下代码,以启用模型验证功能:
implementation ‘org.springframework.boot:spring-boot-starter-validation:2.7.3′
compileOnly’org.projectlombok:lombok:1.18.24’

//省略
dependencies {
//省略
implementation 'org.springframework.boot:spring-boot-starter-validation:2.7.3'
	compileOnly 'org.projectlombok:lombok:1.18.24'
}

添加数据访问层

在.devcontainer文件夹、devcontainer.json文件和docker-compose.yml文件中进行添加操作

version: '3.9'

services:
  workspace:
    container_name: ${PROJECT_NAME:default}-workspace
    build:
      context: ./docker/workspace
      args:
        USERNAME: ${USERNAME:-vscode}
        USER_GROUP_NAME: ${USER_GROUP_NAME:-workspace}
        USER_UID: ${USER_UID:-1000}
        USER_GID: ${USER_GID:-1000}
    tty: true
    volumes:
      - ../:/home/${USERNAME:-vscode}/workspace:cached
    ports:
      - '8080:8080'

  postgres:
    container_name: ${PROJECT_NAME:default}-postgres
    image: postgres:14.2
    environment:
      POSTGRES_USER: ${POSTGRES_USER:-postgres}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres}
      POSTGRES_DB: ${POSTGRES_DB:-dev}
    volumes:
      - ./data/db:/var/lib/postgresql/data
    ports:
      - ${POSTGRES_PORT:-5432}:5432
    restart: always

  pgadmin4:
    container_name: ${PROJECT_NAME:default}-pgadmin4
    restart: always
    image: dpage/pgadmin4
    environment:
      PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL:-pgadmin4@pgadmin.com}
      PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD:-password}
    volumes:
      - ./pgadmin:/var/lib/pgadmin
    ports:
      - 8080:80
    depends_on:
      - postgres

编辑.env文件

PROJECT_NAME=simple-spring-restapi

# workspace
USERNAME=vscode
USER_GROUP_NAME=workspace
USER_UID=1000
USER_UID=1000

# postgres
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DB=dev

# pgadmin4
PGADMIN_DEFAULT_EMAIL=pgadmin4@pgadmin.com
PGADMIN_DEFAULT_PASSWORD=password

编辑resources/application.properties

将application.properties更改为application.yml

spring:
  jpa:
    database: POSTGRESQL
    hibernate:
      ddl-auto: update
      show-sql: true
    properties:
      hibernate:
        hbm2dll: create_namespaces:true

  datasource:
    url: jdbc:postgresql://${POSTGRES_HOST:-postgres}:${POSTGRES_PORT:5432}/ ${POSTGRES_DB:-dev}
    username: ${POSTGRES_USER:-postgres}
    password: ${POSTGRES_PASSWORD:-postgres}
    driver-class-name: org.postgresql.Driver

将代码添加到build.gradle文件中。

//省略
dependencies {
//省略
implementation 'org.springframework.boot:spring-boot-starter-data-jpa:2.7.3'
implementation 'org.postgresql:postgresql:42.5.0'
}

编辑TodoItem.java。

package simple_spring_restapi.models;

import jakarta.persistence.Column;
import jakarta.annotation.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.validation.constraints.NotBlank;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "todos", schema = "business")
public class TodoItem {
    @Id
    @GeneratedValue(strategy = GenerationType.Auto)
    @Column(name = "id", nullable = false)
    private int id;
    @NotBlank(message = "Title must not be blank.")
    @Column(name = "id", nullable = false)
    private String title;

}

创建 “repositories” 文件夹和 “TodoRepositories.java” 文件。

package simple_spring_restapi.repositories;

import org.springframework.stereotype.Repository;

import com.juniordevmind.simplespringrestapi.models.TodoItem;

@Repository
public interface TodoRepositories extends JpaRepository<TodoItem, Integer> {

}

创建一个名为 TodoServiceImpl.java 的文件,路径为 src/main/java/simple_spring_restapi/services/。

package simple_spring_restapi.services;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.webjars.NotFoundException;

import com.juniordevmind.simplespringrestapi.models.TodoItem;

import simple_spring_restapi.repositories.TodoRepositories;

@Service
public class TodoServiceImpl implements TodoService {

    @Autowired
    private TodoRepository _todoRepository;

    @Override
    public TodoItem getTodoItemsById(int id) {
        return _findTodoItemById(id);
    }

    @Override
    public List<TodoItem> getTodoItems() {
        return _todoRepository.findAll();
    }

    @Override
    public Todo removeTodoItemById(int id) {
        _todoRepository.deleteById(id);
    }

    @Override
    public TodoItem saveTodoItem(TodoItem todoItem) {
        return _todoRepository.save(todoItem);
    }

    @Override
    public TodoItem updateTodoItem(int id, TodoItem todoItem) {
        return _todoRepository.save(todoItem);
    }

    private TodoItem _findTodoItemById(int id) throws NotFoundException {
        Optional<TodoItem> found = _todoRepository.findById(id);
        if (!found.isPresent()) {
            throw new NotFoundException("The todo item is not available");
        }
        return found.get();
    }
}

请参考下方网站

【Spring Boot】REST API开发 – 使用Docker和vscode搭建Java开发环境 #1
【Spring Boot】REST API开发 – 生成Spring Boot项目 #2
【Spring Boot】REST API开发 – 启动控制器 #2.5

【Spring Boot】REST API 开发 – 添加模型验证 #6
【Spring Boot】REST API 开发 – 添加数据访问层 #7

广告
将在 10 秒后关闭
bannerAds