← Home
☕Java Developer Interview Questions — Fresher to 5 YOEJava Dev InterviewNEW
🌐

Spring MVC & REST APIs

Controllers, ResponseEntity, exception handling · 14 questions

1

What is the difference between @RestController and @Controller?

Must Know🌱 Fresher

@Controller is the traditional Spring MVC annotation — its methods normally return a view name (a template to render, e.g. Thymeleaf/JSP), and you need @ResponseBody on individual methods to instead return raw data. @RestController is @Controller + @ResponseBody combined at the class level — every method's return value is automatically serialized straight into the HTTP response body (typically as JSON), which is what virtually every REST API controller wants.

Spring MVC
2

What is the difference between @RequestMapping and @GetMapping/@PostMapping/etc.?

Must Know🌱 Fresher

@RequestMapping is the general-purpose mapping annotation — it can match any HTTP method, and you specify which one via an attribute (@RequestMapping(method = RequestMethod.GET)). @GetMapping, @PostMapping, @PutMapping, @DeleteMapping, and @PatchMapping are shorthand, method-specific composed annotations introduced later purely for readability — they're just @RequestMapping pre-set to one HTTP method.

Equivalent mappingsjava
@RequestMapping(value = "/users", method = RequestMethod.GET) // verbose form
@GetMapping("/users")                                          // equivalent, preferred
Spring MVC
3

What do @RequestBody and @ResponseBody do, and how does Spring convert JSON automatically?

Must Know🌱 Fresher

@RequestBody tells Spring to take the incoming HTTP request's body (typically JSON) and deserialize it into a Java object parameter. @ResponseBody tells Spring to take a method's return value and serialize it into the HTTP response body, instead of treating it as a view name to render.

Under the hood, this conversion is handled by HttpMessageConverter implementations — by default, Jackson (bundled in spring-boot-starter-web) handles JSON ↔ Java object conversion automatically, using reflection over your class's fields/getters, with no manual parsing code needed.

Spring MVCJackson
4

What is the difference between @PathVariable and @RequestParam?

Must Know🌱 Fresher

@PathVariable extracts a value from the URL path itself — used for identifying a specific resource (/users/42). @RequestParam extracts a value from the URL's query string — used for optional filters, pagination, or search terms (/users?page=2&size=20).

Both in one endpointjava
@GetMapping("/users/{id}/orders")
List<Order> getOrders(
    @PathVariable Long id,                          // /users/42/orders          -> id=42
    @RequestParam(defaultValue = "0") int page) {    // ?page=2                  -> page=2
    ...
}
Spring MVC
5

How do you implement global exception handling with @ControllerAdvice and @ExceptionHandler?

Must Know📊 Mid

@ExceptionHandler on a method marks it as the handler for a specific exception type thrown by a controller. Declared inside a controller, it only covers that one controller; declared inside a class annotated @ControllerAdvice (or @RestControllerAdvice, which adds implicit @ResponseBody), it applies globally across every controller in the application — a single place to turn exceptions into consistent, structured error responses.

🎯 Most-specific-match wins
Controller throws UserNotFoundException
       |
       v
@RestControllerAdvice scans its @ExceptionHandler methods:
  handle(UserNotFoundException e)  <- exact type match -- this one runs
  handle(RuntimeException e)       <- broader fallback -- skipped, more specific handler exists
Global exception handlerjava
@RestControllerAdvice
class GlobalExceptionHandler {
    @ExceptionHandler(UserNotFoundException.class)
    ResponseEntity<ErrorBody> handleNotFound(UserNotFoundException ex) {
        return ResponseEntity.status(404).body(new ErrorBody(ex.getMessage()));
    }
}
Spring MVCException Handling
6

What is ResponseEntity, and why use it instead of returning a plain object?

Important🌱 Fresher

Returning a plain object always responds with HTTP 200 and just that object as the body — you have no control over the status code or response headers. ResponseEntity<T> wraps the body together with an explicit status code and headers, which is essential for a well-behaved REST API (201 Created with a Location header after a POST, 404 when a resource isn't found, 204 No Content for a successful delete).

ResponseEntity for proper status codesjava
@GetMapping("/users/{id}")
ResponseEntity<User> getUser(@PathVariable Long id) {
    return userRepo.findById(id)
        .map(ResponseEntity::ok)                 // 200 + body
        .orElse(ResponseEntity.notFound().build()); // 404, no body
}
Spring MVCREST
7

How does Bean Validation (@Valid, @NotNull, @Size) work in a Spring Boot REST API?

Important📊 Mid

Annotate request DTO fields with Bean Validation constraints (@NotNull, @Size, @Email, @Min/@Max...), then add @Valid before the parameter in the controller method. Spring runs the validation automatically before the method body executes; if any constraint fails, it throws MethodArgumentNotValidException — which you'd typically catch in a @RestControllerAdvice to turn into a clean 400 response listing every failed field.

Request validationjava
record CreateUserRequest(@NotBlank String name, @Email String email, @Min(18) int age) {}

@PostMapping("/users")
ResponseEntity<User> create(@Valid @RequestBody CreateUserRequest req) {
    ... // never reached if validation fails -- exception thrown first
}
Spring MVCValidation
8

Why use DTOs instead of exposing JPA entities directly in REST responses?

Important📊 Mid
  • Decoupling — the API's public shape shouldn't be forced to change every time the database schema changes (adding a column to an entity would silently change the API response).
  • Security — entities often carry fields that should never be exposed (password hash, internal flags); a DTO explicitly controls exactly what's serialized.
  • Avoiding lazy-loading serialization traps — serializing a JPA entity with lazy-loaded relationships outside a transaction throws LazyInitializationException, or worse, silently triggers extra queries; DTOs are plain data, no such surprises.
  • Validation shape — request DTOs can have validation annotations tailored to the API contract, separate from entity-level constraints.
Spring MVCDTO
9

What is DispatcherServlet, and what is the request flow in Spring MVC?

Important📊 Mid
🚪 Spring MVC request flow
HTTP request
     |
     v
DispatcherServlet (the single front controller for ALL requests)
     |
     v
HandlerMapping   -- "which controller method handles this URL + verb?"
     |
     v
HandlerAdapter   -- invokes that controller method, resolves @RequestBody/@PathVariable args
     |
     v
Controller method runs, returns a value (or ResponseEntity)
     |
     v
HttpMessageConverter (e.g. Jackson) -- serializes the return value to JSON
     |
     v
HTTP response
Spring MVCDispatcherServlet
10

How do you configure CORS in a Spring Boot application?

Important📊 Mid

Two common approaches: annotate individual controllers/methods with @CrossOrigin, or define global CORS rules once via a WebMvcConfigurer bean — preferred for consistency across an entire API.

Global CORS configurationjava
@Configuration
class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
            .allowedOrigins("https://app.example.com")
            .allowedMethods("GET", "POST", "PUT", "DELETE")
            .allowCredentials(true);
    }
}
Spring MVCCORS
11

What is the difference between RestTemplate and WebClient?

Important📊 Mid
RestTemplateWebClient
ModelSynchronous, blockingReactive, non-blocking (built on Project Reactor)
Thread usageBlocks the calling thread until the response arrivesFrees the thread while waiting; can handle many concurrent calls with few threads
StatusIn maintenance mode — not being actively developed furtherThe recommended modern client, even in non-reactive (MVC) applications
WebClient, used synchronously when you don't need reactive end-to-endjava
WebClient client = WebClient.create("https://api.example.com");
User user = client.get().uri("/users/{id}", id)
    .retrieve()
    .bodyToMono(User.class)
    .block(); // blocks here -- fine in a plain MVC controller that isn't reactive itself

Even though RestTemplate still works and is common in older codebases, Spring's own documentation recommends WebClient for new code — including calling it synchronously with .block() when the surrounding application isn't fully reactive.

Spring MVCHTTP Client
12

What is the difference between a HandlerInterceptor and a Servlet Filter?

Advanced📊 Mid
Servlet FilterHandlerInterceptor
LayerServlet container level — runs before Spring MVC even sees the requestSpring MVC level — runs inside the DispatcherServlet's handling
Awareness of the target controllerNone — no idea which controller/method will handle itFull access — knows the exact handler method about to run
Typical useCross-cutting, framework-agnostic concerns: request logging, CORS, gzip compression, character encodingSpring-aware concerns: auth checks before a specific controller, adding request-scoped attributes for controllers
Spring MVCFilter
13

What is content negotiation in Spring MVC?

Optional📊 Mid

Content negotiation is how Spring MVC decides which representation (JSON, XML, etc.) to serialize a response into when multiple are supported — driven primarily by the request's Accept header (or a URL suffix/parameter in older configurations). If a client sends Accept: application/xml and an XML HttpMessageConverter is on the classpath, Spring returns XML instead of the default JSON, without any controller code needing to change.

Spring MVCContent Negotiation
14

What is ResponseStatusException, and how does it compare to @ControllerAdvice?

Optional📊 Mid

ResponseStatusException is a lightweight way to return a specific HTTP status (with an optional reason) by simply throwing it from a controller method — no separate exception class or @ControllerAdvice handler required.

Quick status responses without a custom exception classjava
@GetMapping("/users/{id}")
User getUser(@PathVariable Long id) {
    return userRepo.findById(id)
        .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "user not found"));
}

It's convenient for one-off cases, but doesn't scale well as an API grows — every error case is defined inline at the throw site instead of in one place, and the error response shape isn't easily made consistent across the whole API. A global @RestControllerAdvice with dedicated custom exception types is the better fit once an API has more than a couple of distinct error cases, since it keeps error-response formatting centralized and consistent.

Spring MVCException Handling