Backend Development 8 min read

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.

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

2. Practical Cases

2.1 Dynamic Configuration of URLs

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

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

Configuration file:

<code>pack:
  api:
    baseUrl: /api</code>

Resulting request URL is /api/{id} .

2.2 Using SpEL Expressions

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

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

2.3 Defining Common Logic via Interfaces

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

<code>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);
  }
}</code>

Implementation example:

<code>@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)));
  }
}</code>

2.4 Exception Handling with @ExceptionHandler

Interfaces can also define default exception handling methods.

<code>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()));
  }
}</code>

Test endpoint that triggers an exception:

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

2.5 Data Binding with @InitBinder

Custom converters can be registered to modify incoming data.

<code>@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;
        }
      });
    }
  }
}</code>

Using the converter:

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

3. Additional Demonstrations

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

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

login 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.