Project Context
Developing a recruitmant platform with Spring Boot 2.7 and MyBatis Plus. The registration module encounters server-side data reception failures despite functional business logic tests.
Symptom Description
Submitting the job seeker registration form triggers an HTTP 500 error. Server logs indicate validation failure: "Username field cannot be null" even though values were entered in the form.
Root Cause Analysis
With persistence and service layers already validated through unit tests, the problem likely resides in the controller's parameter binding or the frontend's data transmission mechanism. The investigation should proceed from the API layer outward.
Systematic Debugging Process
1. Persistence Layer Validation
Create isolated tests for MyBatis mapper operations:
// Test class structure
@SpringBootTest
@ExtendWith(SpringExtension.class)
public class JobSeekerMapperTest {
@Autowired
private JobSeekerMapper candidateMapper;
@Test
public void verifyInsertOperation() {
JobSeeker newCandidate = new JobSeeker();
newCandidate.setUsername("test_user_2023");
newCandidate.setPassword("encrypted_password");
newCandidate.setFullName("Test Candidate");
int result = candidateMapper.insertNewCandidate(newCandidate);
assertThat(result).isEqualTo(1);
}
}
Corresponding Mapper XML configuration:
<insert id="insertNewCandidate" useGeneratedKeys="true" keyProperty="id">
INSERT INTO job_seeker_profile
(username, password, full_name, gender, contact_phone, status)
VALUES
(#{username}, #{password}, #{fullName}, #{gender}, #{phone}, #{status})
</insert>
2. Service Layer Verification
Execute service method tests to confirm business logic handles candidate objects correctly before proceeding to controller analysis.
3. Controller Endpoint Inspection
Validate the registration endpoint signature and parameter annotations:
// Problematic implementation
@PostMapping("/register")
public ResponseEntity<String> handleRegistration(
@RequestParam("userAccount") String account, // Expects 'userAccount'
@RequestParam("userPassword") String password
) {
// Frontend actually sends 'username' and 'password'
return ResponseEntity.ok("Success");
}
// Corrected implementation
@PostMapping("/api/candidates/register")
public ResponseEntity<String> registerJobSeeker(
@RequestParam("username") String username,
@RequestParam("password") String password,
@RequestParam(value = "phone", required = false) String phoneNumber
) {
jobSeekerService.createAccount(username, password, phoneNumber);
return ResponseEntity.status(HttpStatus.CREATED).body("Registration successful");
}
4. Frontend Data Transmission Diagnosis
4.1 API Path Alignment
Confirm the form's action attribute matches the controller's mapping exactly, including context path and version prefixes.
4.2 HTTP Method Specification
Ensure the form uses POST method for data submission:
<!-- Incorrect -->
<form action="/api/candidates/register" method="get">
<!-- Correct -->
<form action="/api/candidates/register" method="POST">
4.3 Input Field Name Atttributes
Each form input must include a name attribute matching the controller's @RequestParam value:
<!-- Mismatched naming -->
<input type="text" id="accountInput"> <!-- Missing name attribute -->
<!-- Proper configuration -->
<input type="text" id="accountInput" name="username" required>
<input type="password" id="pwdInput" name="password" required>
4.4 Parameter Naming Convention Mismatches
When using @RequestBody with JSON, ensure property names match the DTO fields exactly:
// DTO class
public class RegistrationRequest {
private String username;
private String password;
// getters and setters
}
// Controller
@PostMapping("/api/candidates/register")
public ResponseEntity<?> registerWithJson(@RequestBody RegistrationRequest request) {
// Process request
}
// JavaScript fetch call must use matching keys
fetch('/api/candidates/register', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({username: 'john_doe', password: 'secret'})
});
4.5 Additional Failure Points
- CSRF protection blocking requests if token is missing
- Content-Type header mismatch between client and server
- Character encoding issues preventing parameter parsing
- Servlet filter intercepting and modifying the request
Enable debug logging for org.springframework.web to trace request parameter binding and identify where data transmission breaks down.