Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Spring MVC request lifecycle: from servlet filter to response body

Last updated: 1 Oct 20265 min read
tutorial
IntermediateBy AITrove Editorial

A Spring MVC request passes through the Servlet filter chain before DispatcherServlet selects a handler, resolves arguments and writes the response. A controller is only one stage of that path.

Mark the rejection point

Security filters can reject a request before any controller runs. Inside MVC, handler mapping selects the controller method. Argument resolvers convert the path and body into Java values; validation can reject those values before the method is invoked. After the method returns, a message converter writes a representation that matches the negotiated media type.

Java
package in.aitrove.receipts;

import org.springframework.http.ResponseEntity;
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.RestController;

record ReceiptView(long id, String state) {}

@RestController
@RequestMapping("/api/receipts")
class ReceiptReadController {
    private final ReceiptReader receiptReader;

    ReceiptReadController(ReceiptReader receiptReader) {
        this.receiptReader = receiptReader;
    }

    @GetMapping("/{receiptId}")
    ResponseEntity<ReceiptView> read(@PathVariable long receiptId) {
        return receiptReader.find(receiptId)
            .map(ResponseEntity::ok)
            .orElseGet(() -> ResponseEntity.notFound().build());
    }
}

interface ReceiptReader {
    java.util.Optional<ReceiptView> find(long receiptId);
}

A nonnumeric path segment fails conversion before read is entered. An unknown numeric ID reaches the reader and returns 404 here. A missing JSON converter or an unacceptable requested media type can fail at a different stage. Record those cases separately in an HTTP test.

Keep costs attached to the responsible layer

Routing and argument conversion are normally bounded by request size and configured mappings. The database lookup dominates this example once the request reaches the reader. Bound body size before deserialization; a small controller method does not make a huge incoming body cheap.

Common Mistakes

  • Logging “controller failed” for a request rejected by a security filter.
  • Returning null for absence and hoping serialization creates a 404.
  • Assuming a unit test of read exercises routing, conversion or security.

Read next

Filters and interceptors, media type failures, and MockMvc boundaries.

spring
spring-boot
mvc-request-pipeline
Storage details