Таким образом, я смог условно сериализовать пропущенные объекты, которые соответствуют пользовательским критериям, с Джексоном по указанной ссылке ссылка: https://www.baeldung.com/jackson-serialize-field-custom-criteria
ПРИМЕЧАНИЕ: я смог сделать это без фильтра.
Итак, что я делаю в основном, проверяя для атрибута, и если он не был установлен, я пропускаю возврат всего объекта. так что я получаю (основываясь на учебном примере):
HTTP: 200
PATH: /users
RESPONSE:
[
{
"name":"john"
},
{
"name":"adam",
"address":{
"city":"ny",
"country":"usa"
}
}
]
Но если мы подошли к делу, чтобы вернуть единственного пользователя, который скрыт, мы столкнемся с этим:
HTTP: 200
PATH: /users/tom
RESPONSE: /**empty response**/
В этом конкретном случае я хочу вернуть HTTP-ответ с кодом ошибки 404, а не 200, как ведет себя Джексон. при отладке Джексон выполняет сериализацию после контроллера, поэтому я не мог его перехватить.
Я думал о реализации перехватчиков, которые могли бы перехватывать устройство записи ответов Джексона, а затем, если оно пустое, возвращать код ошибки 404.
... У меня нет идей и нет опыта. : /
Кто-нибудь знает, как это сделать?
РЕДАКТИРОВАТЬ :: 20200323
после ответа @Tomoki_Sato, я нашел решение. Попробовав его ответ, он не сработал первым. После исследования проблема была связана с несовпадением типов.
В моем контроллере я всегда возвращаю ResponseEntity<?>
, который не реализует класс Hideable
.
Так что мое решение было таким, поддерживающим ResponseEntity<<? implements Hideable>>
&& <? implements Hideable>
ответы:
@RestControllerAdvice
public class MyResponseBodyAdvice implements ResponseBodyAdvice<Hideable> {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
//if returnType is <? implements hideable>
if (Hideable.class.isAssignableFrom(returnType.getParameterType()) && MappingJackson2HttpMessageConverter.class.isAssignableFrom(converterType)) {
return true;
}
//if returnType is ResponseEntity<<? implements hideable>>
List<Type> actualTypeArguments = Lists.newArrayList(((ParameterizedType) returnType.getGenericParameterType()).getActualTypeArguments());
if (actualTypeArguments.isEmpty()) {
return false;
}
try {
Class<?> responseClass = Class.forName(actualTypeArguments.get(0).getTypeName());
return Hideable.class.isAssignableFrom(responseClass) && MappingJackson2HttpMessageConverter.class.isAssignableFrom(converterType);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return false;
}
@Override
public Hideable beforeBodyWrite(
Hideable hideable, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
ServerHttpResponse response
) {
if (hideable == null || hideable.isRemoved()) {
response.setStatusCode(HttpStatus.NOT_FOUND);
return null;
}
return hideable;
}
}
Говоря об эффективности, я не проверял ее, и я считаю, что мы должны протестировать ее на многих типах, таких как ResponseEntity<List<? implements Hideable>>
, ResponseEntity<Set<? implements Hideable>>
... .
В теории я считаю, что @RestControllerAdvice
здесь не вмешивается, и сериализатор JSON играет ведущую роль в преобразовании ответа ... я не знаю.
Я надеюсь, что это помогает кому-то еще:)