java - Java 8 从“字符串”值来自自定义对象的每个字段中删除字符串值
问题描述
我浏览了链接:Java 中是否可以检查对象字段是否为空,然后为所有这些属性添加默认值?并实施了与以下相同的解决方案 -
注意:我正在使用Swagger/Open API Specs(使用 springdoc-openapi-ui),并且在发出POST请求时,所有字符串字段的默认值都为“字符串”,我真的想将其设置为 null 或空格。
任何快速指针?
public static Object getObject(Object obj) {
for (Field f : obj.getClass().getFields()) {
f.setAccessible(true);
try {
if (f.get(obj) == "string") {
f.set(obj, null);
}
} catch (IllegalArgumentException | IllegalAccessException e) {
log.error("Error While Setting default values for String");
}
}
return obj;
}
REST 端点
@GetMapping(value = "/employees")
public ResponseEntity<PagedModel<EmployeeModel>> findEmployees(
EmployeeDto geoDto,
@Parameter(hidden=true) String sort,
@Parameter(hidden=true) String order,
@Parameter(hidden=true) Pageable pageRequest) {
EmployeeDto dto = (EmployeeDto) CommonsUtil.getObject(geoDto);
Page<CountryOut> response = countryService..............;
PagedModel<EmployeeModel> model = employeePagedAssembler.toModel(response, countryOutAssembler);
return new ResponseEntity<>(model, HttpStatus.OK);
}
解决方案
我猜你可以简单一点。如果您控制EmployeeDto
,例如:
@Accessors(chain = true)
@Getter
@Setter
@ToString
static class EmployeeDto {
private String firstname;
private String lastname;
private int age;
}
您可以迭代类的字段并使用MethodHandles
调用所需的设置器,当一些 getter 返回string
您感兴趣的(并且使用equals
, not比较字符串==
)。这甚至可以做成一个小图书馆。这是一个开始:
private static final Lookup LOOKUP = MethodHandles.lookup();
/**
* this computes all the know fields of some class (EmployeeDTO in your case) and their getter/setter
*/
private static final Map<Class<?>, Map<Entry<String, ? extends Class<?>>, Entry<MethodHandle, MethodHandle>>> ALL_KNOWN =
Map.of(
EmployeeDto.class, metadata(EmployeeDto.class)
);
private Map<String, Entry<MethodHandle, MethodHandle>> MAP;
/**
* For example this will hold : {"firstname", String.class} -> getter/setter to "firstname"
*/
private static Map<Entry<String, ? extends Class<?>>, Entry<MethodHandle, MethodHandle>> metadata(Class<?> cls) {
return Arrays.stream(cls.getDeclaredFields())
.map(x -> new SimpleEntry<>(x.getName(), x.getType()))
.collect(Collectors.toMap(
Function.identity(),
entry -> {
try {
return new SimpleEntry<>(
LOOKUP.findGetter(cls, entry.getKey(), entry.getValue()),
LOOKUP.findSetter(cls, entry.getKey(), entry.getValue()));
} catch (Throwable t) {
throw new RuntimeException(t);
}
}
));
}
有了这些信息,您可以为用户提供一个公共方法来调用,因此您需要提供 DTO 的实际实例、DTO 类、要“默认为”的字段的类、要检查的相等性和实际defaultValue
。
public static <T, R> T defaulter(T initial,
Class<T> dtoClass,
Class<R> fieldType,
R equality,
R defaultValue) throws Throwable {
Set<Entry<MethodHandle, MethodHandle>> all =
ALL_KNOWN.get(dtoClass)
.entrySet()
.stream()
.filter(x -> x.getKey().getValue() == fieldType)
.map(Entry::getValue)
.collect(Collectors.toSet());
for (Entry<MethodHandle, MethodHandle> getterAndSetter : all) {
R whatWeGot = (R) getterAndSetter.getKey().invoke(initial);
if (Objects.equals(whatWeGot, equality)) {
getterAndSetter.getValue().invoke(initial, defaultValue);
}
}
return initial;
}
这就是您的来电者可以这样称呼它的方式:
public static void main(String[] args) throws Throwable {
EmployeeDto employeeDto = new EmployeeDto()
.setFirstname("string")
.setLastname("string");
EmployeeDto withDefaults = defaulter(employeeDto, EmployeeDto.class, String.class, "string", "defaultValue");
System.out.println(withDefaults);
}
推荐阅读
- django - instance.save() 没有在 ListSerializer Django Rest Framework 中保存模型
- angular - 默认路由不可访问
- r - 根据构面的存在有条件地修改ggplot主题?
- android - Android 检查设备是否具有通知访问权限
- reactjs - 如何合并 React App 和 Express App 以部署在单个项目上?
- geometry - 具有有限 sympy 段的错误
- tensorflow - 如何在 MacOs 上使用 Spyder 在 Python 上为 SSE4.1 SSE4.2 AVX AVX2 FMA 运行 TensorFlow
- python-3.x - Zipfile / shutil.make_archive 在德语变音符号上抛出 EncodeError
- angular - Angular:如何在 Flask 上服务并路由到不同的端点/路径?
- c# - 如何在帖子上验证财产