나는 링크를 통해 갔다 : Java에서 객체 필드가 null인지 확인한 다음 모든 속성에 기본값을 추가하는 것이 가능합니까? 아래와 같은 솔루션을 구현했습니다.
참고 : 나는 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
몇 가지 게터가 돌아올 때 필요한 세터 호출을, 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);
}
}
));
}
이 정보를 사용하여 사용자가 호출 할 공용 메서드를 제공 할 수 있습니다. 따라서 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);
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다