Skip to content
GitHub LinkedIn

Mastering Spring Controllers

Spring Controllers are central to building modern, robust web applications using Spring MVC. In this blog post, we'll explore 14 key aspects of Spring Controllers, each vital for a well-rounded understanding of handling HTTP requests and responses in Spring.


1. Basic Controller Declaration

Spring Controllers begin with the @Controller annotation, enabling them to handle HTTP requests.

@Controller
class MyController {
    @GetMapping("/greet")
    fun greet(model: Model): String {
        model.addAttribute("message", "Hello World")
        return "greet"
    }
}

Here, MyController maps HTTP GET requests to the greet method.


2. RESTful Web Services with [object Object]

@RestController simplifies creating RESTful services by combining @Controller and @ResponseBody.

@RestController
class HelloRestController {
    @GetMapping("/hello")
    fun sayHello(): String {
        return "Hello, World!"
    }
}

This controller returns a string directly as the response body.


3. Handling Request Parameters with [object Object]

Use @RequestParam to bind query parameters to method parameters.

@RestController
class ParameterController {
    @GetMapping("/welcome")
    fun welcomeUser(@RequestParam name: String): String {
        return "Welcome, $name!"
    }
}

@RequestParam binds the value of the query parameter name.


4. Extracting URI Variables with [object Object]

Path variables extract values from the URI.

@RestController
class VariableController {
    @GetMapping("/user/{id}")
    fun getUserById(@PathVariable id: Long): String {
        return "User ID: $id"
    }
}

@PathVariable annotation binds a URI template variable.


5. Form Data Handling using [object Object]

@ModelAttribute binds form data to domain objects.

@Controller
class FormController {
    @PostMapping("/submitForm")
    fun submitForm(@ModelAttribute userForm: UserForm, model: Model): String {
        model.addAttribute("user", userForm)
        return "formResult"
    }
}

Form submissions are handled and mapped to UserForm.


6. Exception Handling with [object Object]

Controllers can handle exceptions using @ExceptionHandler.

@RestControllerAdvice
class GlobalExceptionHandler {
    @ExceptionHandler(Exception::class)
    fun handleException(e: Exception): String {
        return e.message ?: "An error occurred"
    }
}

This example handles exceptions globally in your application.


7. Using [object Object] for JSON/XML Payloads

Handle HTTP POST requests with JSON or XML payloads using @RequestBody.

@RestController
class UserController {
    @PostMapping("/users")
    fun createUser(@RequestBody userDto: UserDto): String {
        return "User created with username: ${userDto.username}"
    }
}

@RequestBody binds the request body to a domain object.


8. Building Custom Responses

Spring provides multiple ways to customize responses, including status codes and headers.

8.1 Custom Response Status

Set HTTP status codes using @ResponseStatus.

@RestController
class CustomStatusController {
    @GetMapping("/customStatus")
    @ResponseStatus(HttpStatus.CREATED)
    fun customStatus(): String {
        return "Resource created successfully"
    }
}

This returns a 201 (Created) status code.

8.2 ResponseEntity

ResponseEntity offers control over responses, including headers and status codes.

@RestController
class ResponseEntityController {
    @GetMapping("/responseEntity")
    fun responseEntity(): ResponseEntity<String> {
        val headers = HttpHeaders().apply {
            set("Custom-Header", "value")
        }
        return ResponseEntity
            .status(HttpStatus.ACCEPTED)
            .headers(headers)
            .body("Response with custom headers and status")
    }
}

Builds a complete response with headers and status code.


9. Input Validation with [object Object]

Spring supports bean validation using the @Valid annotation.

@RestController
class ValidationController {
    @PostMapping("/validateUser")
    fun validateUser(@RequestBody @Valid userRequest: UserRequest): String {
        return "Validated user: ${userRequest.name}"
    }
}

@Valid triggers validation on the UserRequest object.


10. Global Error Handling with [object Object]

@ControllerAdvice handles exceptions across multiple controllers.

@ControllerAdvice
class GlobalExceptionHandler {
    @ExceptionHandler(Exception::class)
    fun handleAllExceptions(exception: Exception, request: HttpServletRequest): String {
        return "An error occurred: ${exception.message}"
    }
}

Handles all types of exceptions globally.


11. Content Negot

iation Content negotiation returns different representations of a resource.

@RestController
class ContentNegotiationController {
    @GetMapping(value = ["/content"], produces = [MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE])
    fun getContent(): MyResponse {
        return MyResponse("Data")
    }
}

produces attribute specifies the media type.


12. Asynchronous Controllers

Spring supports asynchronous processing in controllers.

@RestController
class AsyncController {
    @GetMapping("/async")
    fun getAsyncData(): DeferredResult<String> {
        val output = DeferredResult<String>()
        Thread { output.setResult("Async response") }.start()
        return output
    }
}

DeferredResult for handling long-running requests.


13. API Versioning

Manage different API versions for backward compatibility.

@RestController
class ApiVersioningController {
    @GetMapping("/api/v1/items")
    fun getItemsV1(): String {
        return "API Version 1 - Items"
    }

    @GetMapping("/api/v2/items")
    fun getItemsV2(): String {
        return "API Version 2 - Items"
    }
}

Different methods for different API versions.


14. File Upload and Download

Controllers can handle file uploads and downloads.

@RestController
class FileController {
    @PostMapping("/upload")
    fun handleFileUpload(@RequestParam("file") file: MultipartFile): String {
        return "File uploaded successfully"
    }
}

MultipartFile for handling file uploads.


Best Practices and Conclusion

Spring Controllers are a powerful part of the Spring MVC framework. Understanding these 14 aspects is crucial for building efficient, secure, and robust web applications. Remember to follow best practices, such as keeping controllers lightweight, using DTOs, and validating inputs. Stay updated with the latest Spring documentation and community best practices for the most effective use of Spring Controllers in your projects.


Happy coding with Spring! 🌿🌱