stuart.tokyo

Spring Boot

Notes on building Java backends with Spring Boot framework.

Initializing a Spring Boot Project in VS Code

Getting started by generating a Gradled-based project.

  • initialization
  • backend

Getting Started

VS Code Extension - Spring Initializr

  1. Open VS Code extensions ( Cmd + Shift + X ) and install Spring Initializr Java Support.
  2. Open Command Palette ( Cmd + Shift + P ) and select Spring Initializr: Create a Gradle Project.

Upon launching, Spring Initializr will ask a sequence of questions. These notes will use the following configuration:

PromptSelectionNotes
Spring Boot Version4.1.1Spring Boot platform and managed dependency versions.
LanguageJavaSource language used by application.
Group IDご自由にBase Java package, such as com.example. Should be lowercase
Artifact ID同上Human-readable project and generated folder name. Such as demo, resulting in com.example.demo.
Package name同上Auto-fills to combo of above two (i.e. com.example.demo). Not sure why this is here.
PackagingJARCreates an executable JAR containing the application and embedded web server.
Java Version21Java language and runtime level used by the project.

Select Dependencies

Select the following dependencies when the picker displays.

DependencyRole
Spring Boot Dev ToolsModule that "enhances the developer experience" with auto restarts, etc.
Spring WebSpring MVC, REST controller support, JSON handling, and the embedded web server.
LombokGenerates getters, setters, constructors, and builders during compilation.
ValidationAdds "Bean" validation annotations like NotNull, NotBlank, and Size.

After dependency selection, VS Code will prompt to select the folder into which it will generate the folder (named after the Artifact ID).

Spring Boot's Gradle plugin manages versions for dependencies within the build.gradle file at the root of the project. Upon project initialization, the file should look like the below. Expect to add to this as features are implemented later.

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-validation'
	implementation 'org.springframework.boot:spring-boot-starter-webmvc'
	compileOnly 'org.projectlombok:lombok'
	developmentOnly 'org.springframework.boot:spring-boot-devtools'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-validation-test'
	testImplementation 'org.springframework.boot:spring-boot-starter-webmvc-test'
	testCompileOnly 'org.projectlombok:lombok'
	testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
	testAnnotationProcessor 'org.projectlombok:lombok'
}
This is a good time to install the Tasks extension (Extension ID: actboy168.tasks) to make it easier to launch the backend. Create a tasks.json within the .vscode directory containing the launch and end commands for a gradle project. Expand this tip for a JSON containing commands for MacOS and Windows.
{
  "version": "2.0.0",
 
  // Configure the backend port here
  "options": {
    "cwd": "${workspaceFolder}",
    "env": {
      "SERVER_PORT": "8080"
    }
  },
 
  "tasks": [
    {
      "label": "$(debug-start) Start Backend",
      "type": "process",
 
      "osx": {
        "command": "./gradlew",
        "args": ["bootRun"]
      },
 
      "windows": {
        "command": "cmd.exe",
        "args": ["/d", "/c", "gradlew.bat", "bootRun"]
      },
 
      "problemMatcher": [],
      "presentation": {
        "panel": "dedicated"
      }
    },
    {
      "label": "$(debug-stop) Stop Backend",
      "type": "process",
 
      "osx": {
        "command": "/bin/zsh",
        "args": [
          "-c",
          "pids=$(lsof -nP -tiTCP:\"$SERVER_PORT\" -sTCP:LISTEN); if [ -n \"$pids\" ]; then printf '%s\\n' \"$pids\" | xargs kill -TERM; echo \"Backend on port $SERVER_PORT stopped\"; else echo \"Backend is not running on port $SERVER_PORT\"; fi"
        ]
      },
 
      "windows": {
        "command": "powershell.exe",
        "args": [
          "-NoProfile",
          "-NonInteractive",
          "-Command",
          "$port = [int]$env:SERVER_PORT; $connections = Get-NetTCPConnection -LocalPort $port -State Listen -ErrorAction SilentlyContinue; if ($connections) { $processIds = $connections.OwningProcess | Sort-Object -Unique; $processIds | ForEach-Object { Stop-Process -Id $_ -ErrorAction SilentlyContinue }; Write-Host \"Backend on port $port stopped\" } else { Write-Host \"Backend is not running on port $port\" }"
        ]
      },
 
      "problemMatcher": [],
      "presentation": {
        "reveal": "always",
        "panel": "shared"
      }
    }
  ]
}

Building a REST Controller and Endpoints

Making a thing you can ping

  • rest-controller
  • backend
  • why-have-tags

Getting Started

The general project structure will eventually look like the following.

src/main/java/com/example/demo/
|-- DemoApplication.java
|-- controller/
|   `-- DemoController.java
|-- service/
|   `-- DemoService.java
|-- repository/
|   `-- DemoRepository.java
|-- model/
|   `-- Demo.java
|-- dto/
|-- exception/
`-- config/

src/main/resources/
`-- application.properties

Required Imports

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;