Einführung
Die Struktur einer typischen Web Services Basissatz Operationen an Instanzen von Entitäten (Objekte) ist CRUD ( C Reate, R ead, U pdate und D elete). Die HTTP-Methoden POST, GET, PUT und DELETE entsprechen diesen Operationen in REST. Oft muss der Entwickler jedoch das der HTTP PATCH-Methode entsprechende Objekt teilweise ändern. Die Bedeutung besteht darin, auf der Serverseite nur die Felder des Objekts zu ändern, die in der Anforderung übergeben wurden. Dafür gibt es verschiedene Gründe:
eine große Anzahl von Feldern im Wesentlichen;
hohe Wahrscheinlichkeit einer gleichzeitigen Änderung desselben Objekts unter hoher Last, wodurch nicht nur die geänderten Felder überschrieben werden;
Unmöglichkeit oder höhere Komplexität des Änderns von Feldern in mehreren oder allen Objekten im Speicher (Massenaktualisierung);
Diese und möglicherweise andere Gründe veranlassen den Entwickler, einen Stapel von Operationen zur teilweisen Objektmodifikation zu implementieren.
Betrachten wir die am häufigsten verwendeten Optionen zur Lösung des Problems der teilweisen Aktualisierung.
Verwendung eines regulären Controllers und DTO
Eine der häufigsten Implementierungen von PATCH-Methoden. In der Steuerung wird das eingehende Objekt in ein reguläres DTO deserialisiert, und weiter entlang des Stapels von Anwendungsschichten wird berücksichtigt, dass nicht alle Felder im DTO mit einem Nullwert verarbeitet werden können.
Zu den Vorteilen dieser Methode gehört die "Vertrautheit" der Implementierung.
- null
( null
).
DTO . , . ObjectMapper
(/ POJO, @JsonInclude(Include.NON_NULL) ) , MapStruct, .
Map<String, Object> POJO
Map<String, Object>
. JSON . , , ( IDE).
null
.
: , , , , runtime( ).
JSON Patch JSON Merge Patch
JSON Patch JSON Merge Patch . Java EE , : JsonPatch JsonMergePatch. , json-patch. Michael Scharhag REST: Partial updates with PATCH.
: , , , , , , .
, DTO , , , , etc.
Partial Update library
: DTO Map<String, Object>
" ".
ChangeLogger ChangeLoggerProducer.
ChangeLoggerProducer
"" POJO, ChangeLogger
, Map<String, Object>
.
POJO:
public class UserModel {
private String login;
private String firstName;
private String lastName;
private String birthDate;
private String email;
private String phoneNumber;
}
@ChangeLogger
public class UserDto extends UserModel {
}
"":
ChangeLoggerProducer<UserDto> producer = new ChangeLoggerProducer<>(UserDto.class);
UserDto user = producer.produceEntity();
user.setLogin("userlogin");
user.setPhoneNumber("+123(45)678-90-12");
Map<String, Object> changeLog = ((ChangeLogger) user).changelog();
/*
changeLog in JSON notation will contains:
{
"login": "userlogin",
"phoneNumber": "+123(45)678-90-12"
}
*/
"" : Set<String>
, Map<String, Object> changelog()
, , , . , , ChangeLogger
, Map<String, Object> changelog()
.
/ "" ChangeLoggerAnnotationIntrospector
. Annotation Introspector ObjectMapper
. "" , @ChangeLogger
Map<String, Object> changelog()
. ObjectMapper
ChangeLoggerAnnotationIntrospector
.
:
ObjectMapper mapper = new ObjectMapper.setAnnotationIntrospector(new ChangeLoggerAnnotationIntrospector());
ChangeLoggerProducer<UserDto> producer = new ChangeLoggerProducer<>(UserDto.class);
UserDto user = producer.produceEntity();
user.setLogin("userlogin");
user.setPhoneNumber("+123(45)678-90-12");
String result = mapper.writeValueAsString(user);
/*
result should be equal
"{\"login\": \"userlogin\",\"phoneNumber\": \"+123(45)678-90-12\"}"
*/
:
ObjectMapper mapper = new ObjectMapper.setAnnotationIntrospector(new ChangeLoggerAnnotationIntrospector());
String source = "{\"login\": \"userlogin\",\"phoneNumber\": \"+123(45)678-90-12\"}";
UserDto user = mapper.readValue(source, UserDto.class);
Map<String, Object> changeLog = ((ChangeLogger) user).changelog();
/*
changeLog in JSON notation will contains:
{
"login": "userlogin",
"phoneNumber": "+123(45)678-90-12"
}
*/
ObjectMapper
ChangeLoggerAnnotationIntrospector
JSON . DTO, Model, Entity "". Partial Update Example.
Partial Update library , . , runtime.
:
" ", DTO, Model, Entity;
Spring, / "" DTO ( ),
ChangeLoggerAnnotationIntrospector
ObjectMapper
;
SQL/HQL bulk update ;
.
Das Format dieses Artikels erlaubt es uns nicht, die Infrastruktur zum Erstellen von Mappern genauer zu betrachten und die Verwendung der Bibliothek in einem typischen Anwendungsstapel zu zeigen. In Zukunft kann ich das Teilaktualisierungsbeispiel genauer analysieren und der Beschreibung der internen Implementierung der Bibliothek mehr Aufmerksamkeit schenken.