pengantar
Struktur operasi set dasar layanan web tipikal pada instance entitas (objek) adalah CRUD ( C reate, R ead, U pdate dan D elete). Metode HTTP POST, GET, PUT, dan DELETE sesuai dengan operasi ini di REST. Namun seringkali pengembang perlu mengubah sebagian objek yang sesuai dengan metode HTTP PATCH. Artinya adalah mengubah di sisi server hanya bidang objek yang diteruskan dalam permintaan. Ada berbagai alasan untuk ini:
sejumlah besar bidang pada intinya;
probabilitas tinggi untuk perubahan simultan dari objek yang sama di bawah beban tinggi, sebagai akibatnya tidak hanya bidang yang diubah akan ditimpa;
ketidakmungkinan atau kompleksitas yang lebih tinggi untuk mengubah bidang di beberapa atau semua objek dalam penyimpanan (pembaruan massal);
Ini dan, mungkin, alasan lain yang mendorong pengembang untuk mengimplementasikan tumpukan operasi untuk modifikasi objek sebagian.
Mari pertimbangkan opsi yang paling sering digunakan untuk menyelesaikan masalah pembaruan parsial.
Menggunakan pengontrol biasa dan DTO
Salah satu implementasi metode PATCH yang paling umum. Dalam pengontrol, objek yang masuk dideserialisasi menjadi DTO biasa, dan selanjutnya di sepanjang tumpukan lapisan aplikasi, dianggap bahwa semua bidang di DTO dengan nilai null tidak dapat diproses.
Keuntungan dari metode ini termasuk "keakraban" implementasinya.
- 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 ;
.
Format artikel ini tidak memungkinkan kita untuk melihat lebih dekat pada infrastruktur untuk membuat pembuat peta dan menunjukkan penggunaan pustaka dalam tumpukan aplikasi yang khas. Untuk kedepannya saya dapat menganalisa Partial Update Example secara lebih detail dan lebih memperhatikan gambaran implementasi internal perpustakaan.