Spring中使用@ModelAttribute时Building对象始终为空问题排查
Hey there! Let's break down why your Building object keeps coming up empty when using @ModelAttribute to accept JSON in a Spring POST request. The core issue is a mismatch between what the annotation is designed for and the request format you're sending—here's the full breakdown:
1. The Core Problem: @ModelAttribute Isn't Built for JSON
@ModelAttribute is intended to handle form-encoded data (the application/x-www-form-urlencoded content type, like data from HTML forms) or URL query parameters. It uses Spring's ServletRequestDataBinder to map key-value pairs from the request to your object fields.
JSON payloads use the application/json content type, which requires a completely different parsing mechanism. Spring relies on HttpMessageConverter implementations (like Jackson) to deserialize JSON into Java objects—and that's exactly what @RequestBody is made for. @ModelAttribute can't trigger this JSON parsing process, so your Building object stays empty.
2. Fixes to Get Your Data Binding Working
Option 1: Switch to @RequestBody (Recommended)
This is the simplest, most idiomatic solution. Just replace @ModelAttribute with @RequestBody in your controller method, and ensure your client sends the request with the Content-Type: application/json header.
Example controller code:
@PostMapping("/buildings") public ResponseEntity<Building> saveBuilding(@RequestBody Building building) { // Your JPA persistence logic here Building savedBuilding = buildingRepository.save(building); return ResponseEntity.ok(savedBuilding); }
Option 2: If You Must Use @ModelAttribute (Not Recommended)
Unless you have a specific edge case (like mixing form data and JSON, which is uncommon), skip this route. But if you need to proceed, you'd have to configure Spring to handle JSON parsing alongside form data—this involves customizing HttpMessageConverter beans or manually parsing the request body, which adds unnecessary complexity.
3. Quick Checks to Ensure Proper Binding
Even after switching to @RequestBody, double-check these common pitfalls:
- Your
Buildingclass has a no-argument constructor (Spring needs this to instantiate the object via reflection). - All fields you want to bind have corresponding getter/setter methods (or use Lombok's
@Dataannotation to auto-generate them). - The JSON keys in your request exactly match the field names in
Building(case-sensitive!). If they don't, use@JsonPropertyto map them, e.g.:@JsonProperty("building_name") private String name;
Wrap-Up
The root issue here is using the wrong tool for the job. @ModelAttribute isn't designed to handle JSON payloads—switching to @RequestBody will resolve the empty object problem immediately, as long as your Building class follows Spring's data binding rules.
内容的提问来源于stack exchange,提问作者Masood

