java – PUT和POST失敗的未知屬性Spring不同的行為
我正在使用Spring Data Rest儲存庫編寫Spring Boot應用程式,如果請求主體包含具有未知屬性的JSON,我想拒絕對資源的訪問.簡化實體和倉庫的定義:
@Entity public class Person{ @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; private String firstName; private String lastName; /* getters and setters */ } @RepositoryRestResource(collectionResourceRel = "people", path = "people") public interface PersonRepository extends CrudRepository<Person, Long> {}
我使用傑克遜的反序列化功能來禁止JSON中的未知屬性.
@Bean public Jackson2ObjectMapperBuilder objectMapperBuilder(){ Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); builder.failOnUnknownProperties(true); return builder; }
當我傳送POST請求時,一切都按預期工作.當我使用有效的欄位時,我得到正確的響應:
curl -i -x POST -H "Content-Type:application/json" -d '{"firstName": "Frodo", "lastName": "Baggins"}' http://localhost:8080/people { "firstName": "Frodo", "lastName": "Baggins", "_links": {...} }
當我傳送未知欄位的JSON應用程式丟擲預期的錯誤:
curl -i -x POST -H "Content-Type:application/json" -d '{"unknown": "POST value", "firstName": "Frodo", "lastName": "Baggins"}' http://localhost:8080/people com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "unknown" (class Person), not marked as ignorable (2 known properties: "lastName", "firstName")
使用有效的JSON時,PUT方法也會返回正確的響應.但是當我傳送未知欄位的PUT請求時,我期望Spring丟擲錯誤,但是Spring更新資料庫中的物件並返回它:
curl -i -x PUT -H "Content-Type:application/json" -d '{"unknown": "PUT value", "firstName": "Bilbo", "lastName": "Baggins"}' http://localhost:8080/people/1 { "firstName": "Bilbo", "lastName": "Baggins", "_links": {...} }
僅當資料庫中沒有給定id的物件時,才會丟擲該錯誤:
curl -i -x PUT -H "Content-Type:application/json" -d '{"unknown": "PUT value", "firstName": "Gandalf", "lastName": "Baggins"}' http://localhost:8080/people/100 com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "unknown" (class Person), not marked as ignorable (2 known properties: "lastName", "firstName")
Spring Data Rest中是否有預期的行為或錯誤?不管什麼樣的請求方式,將JSON傳遞給應用程式時,如何將錯誤傳遞給應用程式?
我通過修改ofollow,noindex" target="_blank">http://spring.io/guides/gs/accessing-data-rest/ 來重現這種行為,我所做的唯一的改變是Jackson2ObjectMapperBuilder,這個專案中沒有其他控制器或儲存庫.
我認為你所觀察到的行為是設計的.當您釋出POST時,您正在建立資源,所以JSON被反序列化為您的實體型別,而且Jackson正在執行此任務.
在春季資料休息中,PUT的工作方式不同.有趣的部分在PersistentEntityResourceHandlerMethodArgumentResolver.readPutForUpdate中處理.
json被讀入一個JsonNode,實體是從資料儲存中讀取的,然後在DomainObjectReader.doMerge中執行遍歷json欄位.它將json應用於實體,並將其儲存在控制器實現中.它還會丟棄永續性實體中不存在的所有欄位:
if (!mappedProperties.hasPersistentPropertyForField(fieldName)) { i.remove(); continue; }
這是我從閱讀程式碼中的理解.我想你可以認為這是一個bug.您可以嘗試在spring data rest`s jira–REST" rel="nofollow,noindex" target="_blank">https://jira.spring.io/browse/DATAREST 上報告.據我所知,沒有辦法自定義此行為.
http://stackoverflow.com/questions/34545997/put-and-post-fail-on-unknown-properties-spring-different-behavior