SpringBoot项目中@RequestBody绑定的POJO无法从application-dev.properties注入默认值的问题求助
Hey there! Let's break down why your current code isn't working, then walk through a couple of reliable ways to implement your requirement.
Why Your Current Code Fails
Your RequestObject is a plain Java object (POJO) used as a request body—Spring doesn't manage it as a bean. That means:
- The
@Value("${package.default}")annotation won't be processed by Spring, sodefault_idwill always benull. - Even if it were a bean, the line
private String id = default_idruns during object initialization (before Spring injects the@Valueproperty), soidwould still end up asnull.
Solution 1: Handle Default Value in Controller
This is the simplest approach—inject the default ID directly in your controller, then set it if the request's ID is blank.
Step 1: Inject Default ID in Controller
@RestController // Ensure your controller uses this annotation (not just @Controller) @RequestMapping("/your-base-path") public class YourController { // Inject the default ID from properties @Value("${package.default}") private String defaultId; private static final String PATH = "/your-endpoint"; @PostMapping(value = PATH, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<ResponseBean<ResponseObject>> postController( @Valid @RequestBody RequestObject request) throws Exception { // Set default ID if request's id is blank if (StringUtils.isBlank(request.getId())) { request.setId(defaultId); } return serviceClass.service(request); } }
Step 2: Simplify Your RequestObject
You can remove the @Value and default initialization from RequestObject now:
public class RequestObject { private String id; public String getId() { return id; } public void setId(String id) { this.id = id; } }
Solution 2: Use @ConfigurationProperties (Better for Scalability)
If you have multiple default properties or want to keep configuration organized, use @ConfigurationProperties to bind your properties into a dedicated config class.
Step 1: Create a Config Class
@Configuration @ConfigurationProperties(prefix = "package") public class AppConfig { private String defaultId; // Matches ${package.default} in properties // Getters and Setters public String getDefaultId() { return defaultId; } public void setDefaultId(String defaultId) { this.defaultId = defaultId; } }
Step 2: Inject Config in Controller/Service
@RestController @RequestMapping("/your-base-path") public class YourController { private final AppConfig appConfig; private final ServiceClass serviceClass; // Constructor injection (preferred over field injection) public YourController(AppConfig appConfig, ServiceClass serviceClass) { this.appConfig = appConfig; this.serviceClass = serviceClass; } @PostMapping(value = PATH, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<ResponseBean<ResponseObject>> postController( @Valid @RequestBody RequestObject request) throws Exception { if (StringUtils.isBlank(request.getId())) { request.setId(appConfig.getDefaultId()); } return serviceClass.service(request); } }
Solution 3: Custom Jackson Deserializer (Automatic Handling)
If you want the default value to be set automatically during JSON deserialization (so you don't have to handle it in every controller), create a custom Jackson deserializer.
Step 1: Create the Deserializer
@Component // Let Spring manage this so we can inject the default ID public class IdDeserializer extends JsonDeserializer<String> { private final String defaultId; public IdDeserializer(@Value("${package.default}") String defaultId) { this.defaultId = defaultId; } @Override public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { String id = p.getText(); return StringUtils.isBlank(id) ? defaultId : id; } }
Step 2: Apply Deserializer to RequestObject
public class RequestObject { @JsonDeserialize(using = IdDeserializer.class) private String id; // Getters and Setters public String getId() { return id; } public void setId(String id) { this.id = id; } }
Now, whenever the request body has a blank or missing id, Jackson will automatically use the default value from your properties—no need to handle it in the controller!
内容的提问来源于stack exchange,提问作者Ananya Verma

