Master Spring Boot 3 Controllers: Real‑World Cases & Advanced Techniques

Explore a comprehensive Spring Boot 3 tutorial featuring 122 real‑world controller examples—from basic @RestController setup and dynamic URL configuration to advanced SpEL usage, interface default methods, exception handling, data binding, and custom endpoints—complete with code snippets and test results.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Master Spring Boot 3 Controllers: Real‑World Cases & Advanced Techniques

1. Introduction

Spring Boot 3.4.2 is used throughout this tutorial. In Spring Boot development, the Controller interface is a core component of the MVC architecture. It defines routing entry points with annotations such as @RestController and @Controller, mapping HTTP requests to methods and decoupling business logic from request paths.

Parameters can be extracted via @RequestParam or @PathVariable, and request bodies (JSON, XML, etc.) are handled with @RequestBody. Responses are typically JSON or view redirects, efficiently linking front‑end and back‑end data flows.

@RestController
@RequestMapping("/api")
public class UserController {
  @GetMapping("/users/{id}")
  public ResponseEntity<User> query(@PathVariable Long id) {
    // business logic
    return ResponseEntity.ok(userService.findById(id));
  }
  // ...
}

2. Practical Cases

2.1 Dynamic Configuration of URLs

Request URLs can be externalized in configuration files and referenced with ${...} placeholders.

@RestController
@RequestMapping("${pack.api.baseUrl}")
public class ApiController {
  @GetMapping("/{id}")
  public ResponseEntity<String> queryById(@PathVariable Long id) {
    return ResponseEntity.ok("查询 - " + id);
  }
}

Configuration file:

pack:
  api:
    baseUrl: /api

Resulting request URL is /api/{id}.

2.2 Using SpEL Expressions

SpEL can combine configuration values with bean methods to build dynamic paths.

@RestController
@RequestMapping("#{'${pack.api.baseUrl}' + @apiController.getPath()}")
public class ApiController {
  public String getPath() { return "/users"; }
}

2.3 Defining Common Logic via Interfaces

Common CRUD operations can be declared in a generic interface and reused across modules.

public interface BaseController<T> {
  @PostMapping("")
  default ResponseEntity<T> create(@RequestBody T entity) {
    return ResponseEntity.ok(entity);
  }

  @GetMapping("/{id}")
  default ResponseEntity<T> queryById(@PathVariable Long id) {
    return ResponseEntity.ok(null);
  }
}

Implementation example:

@RestController
@RequestMapping("/users")
public class UserController implements BaseController<User> {
  @Override
  public ResponseEntity<User> create(User t) {
    return ResponseEntity.ok(t);
  }

  @Override
  public ResponseEntity<User> queryById(Long id) {
    return ResponseEntity.ok(new User(id, "Name - " + id, new Random().nextInt(100)));
  }
}

2.4 Exception Handling with @ExceptionHandler

Interfaces can also define default exception handling methods.

public interface BaseController<T> {
  // ...
  @ExceptionHandler(Exception.class)
  default ResponseEntity<Map<String, Object>> error(Exception e) {
    return ResponseEntity.ok(Map.of("code", -1, "error", "接口异常: " + e.getMessage()));
  }
}

Test endpoint that triggers an exception:

@GetMapping("/calc")
public ResponseEntity<Integer> calc() {
  System.err.println(1 / 0);
  return ResponseEntity.ok(8888);
}

2.5 Data Binding with @InitBinder

Custom converters can be registered to modify incoming data.

@RequestMapping("/api")
public interface BaseController<T> {
  @InitBinder
  default void init(WebDataBinder binder) {
    ConversionService cs = binder.getConversionService();
    if (cs instanceof ConfigurableConversionService ccs) {
      ccs.addConverter(new Converter<String, Integer>() {
        public Integer convert(String source) {
          if (source == null) return null;
          return Integer.parseInt(source) + 1;
        }
      });
    }
  }
}

Using the converter:

@GetMapping("/convert")
public ResponseEntity<Integer> convert(Integer source) {
  return ResponseEntity.ok(source);
}

3. Additional Demonstrations

Custom endpoints, list retrieval, and other advanced features are also shown, each accompanied by test screenshots.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaBackend DevelopmentSpring BootREST APIController
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.