[英]Check if any field is null
I'm wondering if there is a shorter version for checking if any field of my ProfileDto is blank.我想知道是否有更短的版本来检查我的 ProfileDto 的任何字段是否为空。
Upon searching the internet, I only found questions about how to check if a field is null or if all fields are null which is something totally different.在互联网上搜索时,我只发现了有关如何检查一个字段是否为空或所有字段是否为空的问题,这是完全不同的。
For context, if blank, it should take the respective field of the user object (which is just a call to the database).对于上下文,如果为空,它应该采用用户对象的相应字段(这只是对数据库的调用)。 If notBlank, then it should take the ProfileDto field
如果不是空白,那么它应该取 ProfileDto 字段
private void setEmptyFieldsForUpdatedUser(User user, ProfileDto profileDto) {
String newFirstName = profileDto.getFirstName();
String newLastName = profileDto.getLastName();
String newEmailAdres = profileDto.getEmail();
String oldPassword = profileDto.getPassword();
String newPassword = profileDto.getNewPassword();
if (newFirstName == null) {
profileDto.setFirstName(user.getFirstName());
}
if (newLastName == null) {
profileDto.setLastName(user.getLastName());
}
if (newEmailAdres == null) {
profileDto.setEmail(user.getEmail());
}
}
This ProfileDto gives a JSON object.这个 ProfileDto 给出了一个 JSON 对象。 Which can have null-values.
可以有空值。 If it is null, I want to set the value with the previous user field which is in my database.
如果它为空,我想用我数据库中的前一个用户字段设置该值。
My database user has the following properties:我的数据库用户具有以下属性:
firstname: dj
lastname : test
email : dj@mail.com
password : qwerty
Input example:输入示例:
{
"firstName": "freeman",
"lastName": null,
"email": null
"password": null,
"newPassword" : null
}
My output should become:我的输出应该变成:
{
"firstName": "freeman",
"lastName": "test",
"email": "dj@mail.com",
"password": "qwerty"
}
Obviously, we can see that if I have 20 more variables that I need a lot of if's so I was wondering if there was a better way.显然,我们可以看到,如果我有 20 个以上的变量,我需要很多 if,所以我想知道是否有更好的方法。
As OP doesn't want to use reflection, another solution using jackson-databind dependency to do this with JSON:由于 OP 不想使用反射,另一种解决方案使用 jackson-databind 依赖项来对 JSON 执行此操作:
Firstm we convert the class instances into a JsonTree
.首先,我们将类实例转换为
JsonTree
。 After that, we iterate over the fields of ProfileDto
JSON, which also includes the null values and replace the null values with what we can find in the JSON for the User
.之后,我们遍历
ProfileDto
JSON 的字段,其中还包含空值,并将空值替换为我们可以在User
的 JSON 中找到的值。 We check that the user JSON has the field as to not cause exceptions.我们检查用户 JSON 是否具有不会导致异常的字段。 Finally, we convert the
JsonTree
back into an instance of ProfileDto
:最后,我们将
JsonTree
转换回ProfileDto
的实例:
ObjectMapper mapper = new ObjectMapper();
JsonNode userTree = mapper.valueToTree(user);
JsonNode dtoTree = mapper.valueToTree(dto);
Iterator<Entry<String, JsonNode>> fields = dtoTree.fields();
while (fields.hasNext()) {
Entry<String, JsonNode> e = fields.next();
if (e.getValue().isNull() && userTree.has(e.getKey())) {
((ObjectNode) dtoTree).put(e.getKey(), userTree.get(e.getKey()).asText());
}
}
dto = mapper.treeToValue(dtoTree, ProfileDto.class);
I used following maven dependency:我使用了以下 Maven 依赖项:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.3</version>
</dependency>
A possible solution includes reflection.一个可能的解决方案包括反思。 That way you can check all fields by just iterating them.
这样你就可以通过迭代来检查所有字段。 This solution however requires that both classes have the same field names, or at least that those in the DTO are present in the user class
但是,此解决方案要求两个类具有相同的字段名称,或者至少 DTO 中的字段名称存在于用户类中
User user = new User();
user.setFirstName("dj");
user.setLastName("test");
user.setEmail("dj@mail.com");
user.setPassword("qwerty");
ProfileDto dto = new ProfileDto();
dto.setFirstName("test");
System.out.println(user);
System.out.println(dto);
System.out.println();
for (Field f : dto.getClass().getDeclaredFields()) {
if (f.get(dto) == null) {
try {
f.set(dto, user.getClass().getDeclaredField(f.getName()).get(user));
} catch (NoSuchFieldException e) {
System.out.println("Field missing: " + f.getName());
}
}
}
System.out.println(user);
System.out.println(dto);
You can use the isBlank() method from the StringUtils class to check if a string is empty or contains only whitespace.您可以使用 StringUtils 类中的 isBlank() 方法来检查字符串是否为空或仅包含空格。
private void setEmptyFieldsForUpdatedUser(User user, ProfileDto profileDto) {
String newFirstName = profileDto.getFirstName();
String newLastName = profileDto.getLastName();
String newEmailAdres = profileDto.getEmail();
if (StringUtils.isBlank(newFirstName)) {
profileDto.setFirstName(user.getFirstName());
}
if (StringUtils.isBlank(newLastName)) {
profileDto.setLastName(user.getLastName());
}
if (StringUtils.isBlank(newEmailAdres)) {
profileDto.setEmail(user.getEmail());
}
}
This will check if any of the strings are empty or contain only whitespace, and if so, it will set the value of the corresponding field in the ProfileDto object to the value from the User object.这将检查是否有任何字符串为空或仅包含空格,如果是,它将 ProfileDto 对象中相应字段的值设置为 User 对象的值。
In case the number of variables increases, then to avoid checking explicitly for every variable, you can use the Map
class to store the fields of the ProfileDto object and the corresponding setter methods for each field.如果变量的数量增加,那么为了避免显式检查每个变量,您可以使用
Map
类来存储 ProfileDto 对象的字段以及每个字段的相应设置方法。 Then you can just iterate over the Map and use the StringUtils.isBlank() method to check if a field is blank.然后您可以遍历 Map 并使用 StringUtils.isBlank() 方法检查字段是否为空。 If it is blank, you can use the setter method to set the corresponding field of the user object.
如果为空,可以使用setter方法设置用户对象对应的字段。
private void setEmptyFieldsForUpdatedUser(User user, ProfileDto profileDto) {
Map<String, BiConsumer<ProfileDto, String>> setters = new HashMap<>();
setters.put("firstName", ProfileDto::setFirstName);
setters.put("lastName", ProfileDto::setLastName);
setters.put("email", ProfileDto::setEmail);
for (Map.Entry<String, BiConsumer<ProfileDto, String>> entry : setters.entrySet()) {
String fieldName = entry.getKey();
BiConsumer<ProfileDto, String> setter = entry.getValue();
try {
Method getter = ProfileDto.class.getMethod("get" + StringUtils.capitalize(fieldName));
String fieldValue = (String) getter.invoke(profileDto);
if (StringUtils.isBlank(fieldValue)) {
Method userGetter = User.class.getMethod("get" + StringUtils.capitalize(fieldName));
String userValue = (String) userGetter.invoke(user);
setter.accept(profileDto, userValue);
}
} catch (Exception e) {
}
}
}
I guess it's not possible to check if any field is empty without using reflection (which is not very elegant).我想如果不使用反射(这不是很优雅)就不可能检查任何字段是否为空。
To make your code shorter and more readable I recommend you to use Objects.requireNonNullElse()
:为了使您的代码更短且更具可读性,我建议您使用
Objects.requireNonNullElse()
:
profileDto.setFirstName(Objects.requireNonNullElse(profileDto.getFirstName(), user.getFirstName()));
If you hava java 9 or later you can minimize your code a bit with the following如果你有 java 9 或更高版本,你可以使用以下代码来最小化你的代码
Optional.ofNullable(profileDto.getFirstName()).or(() -> Optional.ofNullable(user.getFirstName())).ifPresent(profileDto::setFirstName);
//...same for each field
This way这条路
You could go with ternary expression, and just do it all in one line.您可以使用三元表达式,并在一行中完成所有操作。 (StringUtils class comes from apache commons)
(StringUtils 类来自 apache commons)
String newFirstName = StringUtils.isBlank(profileDto.getFirstName()) ? user.getFirstName() : profileDto.getFirstName();
String newLastName = StringUtils.isBlank(profileDto.getLastName()) ? user.getLastName() : profileDto.getLastName();
String newEmailAdres = StringUtils.isBlank(profileDto.getEmail()) ? user.getEmail() : profileDto.getEmail();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.