Java 8 从每个字段中删除字符串值,其中 "string" 值来自自定义对象
Java 8 to remove string value from each field where "string" value comes of the Custom Object
我经历了 link:Is it possible in Java to check if objects fields are null and then add default value to all those attributes? 并实施了与下面相同的解决方案 -
注意:我正在使用 Swagger/Open API 规范(使用 springdoc-openapi-ui) 并且在制作 POST 请求所有字符串字段的默认值为 "string" 我真的想将其设置为 null 或 space .
任何 quick 指针 ?
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;
}
您可以遍历 class 的字段并使用 MethodHandles
调用所需的 setter,当某些 getter return 您感兴趣的 string
(和字符串使用 equals
进行比较,而不是 ==
)。这甚至可以做成一个小型图书馆。这是一个开始:
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);
}
}
));
}
根据这些信息你可以提供一个public方法供用户调用,所以你需要提供你的DTO的实际实例,DTOclass,Class您想要 "default to" 的字段、要检查的相等性和实际 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);
}
我经历了 link:Is it possible in Java to check if objects fields are null and then add default value to all those attributes? 并实施了与下面相同的解决方案 -
注意:我正在使用 Swagger/Open API 规范(使用 springdoc-openapi-ui) 并且在制作 POST 请求所有字符串字段的默认值为 "string" 我真的想将其设置为 null 或 space .
任何 quick 指针 ?
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;
}
您可以遍历 class 的字段并使用 MethodHandles
调用所需的 setter,当某些 getter return 您感兴趣的 string
(和字符串使用 equals
进行比较,而不是 ==
)。这甚至可以做成一个小型图书馆。这是一个开始:
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);
}
}
));
}
根据这些信息你可以提供一个public方法供用户调用,所以你需要提供你的DTO的实际实例,DTOclass,Class您想要 "default to" 的字段、要检查的相等性和实际 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);
}