在Spring Boot中,當使用@RequestBody注解來接收HTTP請求中的JSON數據并將其轉換為Java對象時,Spring默認會忽略額外的屬性。這意味著如果發送的JSON包含一些目標對象中沒有定義的屬性,Spring不會報錯,這些額外的屬性會被簡單地忽略。
例如,假設有一個Java對象User,如下所示:
private String name;private int age;// getters and setters
}
如果發送一個包含name和age以及額外屬性email的JSON到Spring Boot應用,Spring會正常地將name和age映射到User對象,而email屬性會被忽略:
{"name": "John","age": 30,"email": "john@example.com"
}
如果希望Spring在接收到包含未知屬性的JSON時拋出錯誤,可以使用以下幾種方法:
1. 使用@Validated和@JsonIgnoreProperties(ignoreUnknown = false)
可以通過自定義一個配置或者使用一個專門的類來處理JSON反序列化時的行為。例如,可以創建一個配置類來全局設置Jackson的屬性忽略行為:
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;@Configuration
public class JacksonConfig {@Beanpublic ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {return builder.createXmlMapper(false).build().setConfig(builder.createXmlMapper(false).build().getDeserializationConfig().with(builder.deserializationConfig().with(builder.deserializationConfig().with(org.codehaus.jackson.map.DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, true))));}
}
2. 使用@JsonIgnoreProperties注解
在控制器方法參數上使用@JsonIgnoreProperties(ignoreUnknown = false)
來強制要求所有未知屬性都拋出異常:
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;@RestController
public class UserController {@PostMapping("/users")public User createUser(@RequestBody @JsonIgnoreProperties(ignoreUnknown = false) User user) {// 處理用戶創建邏輯...return user;}
}
3. 使用自定義的轉換器或反序列化器
創建一個自定義的反序列化器,并在其中顯式地檢查未知屬性并拋出異常:
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import java.io.IOException;
import org.springframework.boot.jackson.JsonComponent;@JsonComponent
public class CustomUserDeserializer extends JsonDeserializer<User> {@Overridepublic User deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {JsonNode node = p.getCodec().readTree(p);if (!node.isObject()) {throw new IOException("Expected JSON object, but got " + node);} else {Iterator<Map.Entry<String, JsonNode>> fields = node.fields();User user = new User();while (fields.hasNext()) {Map.Entry<String, JsonNode> entry = fields.next();String fieldName = entry.getKey();if ("name".equals(fieldName) || "age".equals(fieldName)) { // 只允許這些字段存在,忽略其他所有字段。如果需要更復雜的行為,請根據需要調整此邏輯。// 設置user的屬性...例如: user.setName(entry.getValue().asText()); 等等。 確保處理所有可能的字段。 否則,拋出異常或忽略。 例如: 拋出 new RuntimeException("Unknown property: " + fieldName); 如果想要拋出異常。 否則,可以選擇忽略。