Avoid Common Spring Boot Mistakes and Write Cleaner Backend Code
This article highlights common pitfalls in Spring Boot development—such as exposing sensitive data, neglecting records, field injection, using RestTemplate, bloated controllers, and poor exception handling—and provides concise, code‑driven solutions to write cleaner, more secure, and maintainable backend applications.
1. Introduction
Spring Boot is a lightweight framework built on Spring that simplifies application development by providing sensible defaults and ready‑to‑use tools, allowing developers to focus on business logic rather than extensive XML configuration.
2. Common Mistakes
2.1 Exposing Sensitive Data
Returning entity objects directly from controllers can unintentionally expose fields such as passwords, even when @JsonIgnore is used. The proper approach is to use DTOs or Java records.
@RestController
@RequestMapping("/users")
public class UserController {
@Resource
private UserRepository userRepository;
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return userRepository.findById(id).orElseThrow();
}
}Use a DTO/record to transfer only the required data:
public record UserDTO(Long id, String name, String email) {}2.2 Not Using Records
When using Java 14+ for immutable POJOs, prefer records over classic classes.
public class UserResponse {
private final String username;
private final Integer age;
public UserResponse(String username, Integer age) {
this.username = username;
this.age = age;
}
// getters, setters
}With a record the same can be expressed in a single line:
public record UserResponse(String username, Integer age) {}2.3 Field Injection with @Autowired/@Resource
Using @Autowired or @Resource on fields is unnecessary and hinders testability. Constructor injection is preferred.
@Service
public class UserService {
@Resource
private UserRepository userRepository;
}Correct constructor injection:
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}2.4 Using RestTemplate
RestTemplate is blocking and in maintenance mode. WebClient provides a non‑blocking, reactive alternative.
@Service
public class PaymentService {
private final WebClient webClient;
public PaymentService(WebClient.Builder webClientBuilder) {
this.webClient = webClientBuilder.baseUrl("https://www.payment.com/api").build();
}
public Mono<PaymentResponse> processPayment(PaymentRequest request) {
return webClient.post()
.uri("/pay")
.bodyValue(request)
.retrieve()
.bodyToMono(PaymentResponse.class);
}
}Official recommendation:
2.5 Bloated Controllers
Putting business logic directly in controllers makes the code hard to maintain. Controllers should delegate to services.
@RestController
@RequestMapping("/users")
public class UserController {
@Resource
private UserRepository userRepository;
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return userRepository.findById(id).orElseThrow();
}
}Correct separation:
@Service
public class UserService {
private final UserRepository userRepository;
public User getUser(Long id) {
return userRepository.findById(id).orElseThrow();
}
}
// Controller calls UserService2.6 Ignoring Proper Exception Handling
Returning generic RuntimeException hides the real problem. Define custom exceptions and handle them globally.
@ResponseStatus(HttpStatus.NOT_FOUND)
public class UserNotFoundException extends RuntimeException {
public UserNotFoundException(String message) {
super(message);
}
} @RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<String> handleNotFound(UserNotFoundException ex) {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body("User not found, " + ex.getMessage());
}
}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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.