Это мой первый вопрос в stackoverflow, поэтому, пожалуйста, будьте осторожны:)
Существует конечная точка GET, которая будет преобразована в POST. Его необходимо расширить, чтобы принять параметр запроса filterKeys
, который будет содержать данные в кодировке JSON. Этот подход не очень распространен, но он используется некоторыми большими API. Рабочий подход заключается в том, чтобы сопоставить параметр запроса со строкой и затем десериализовать в объект Java с помощью объекта Jackson ObjectMapper в методе контроллера. Есть ли способ применить эту десериализацию Джексона где-нибудь в фоновом режиме, точно так же, как она поддерживается для @RequestBody
из коробки Spring?
Пример для JSON в кодировке filterKeys
:
[
{
"parameter": "datetime",
"value": {
"type": "INT_RANGE",
"start": 1275782400,
"end": 1571443199
}
},
{
"parameter": "value",
"value": {
"type": "LONG_RANGE",
"start": 100,
"end": 200
}
}
]
Объект Java:
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Getter;
import javax.validation.constraints.NotNull;
import java.util.List;
@Getter
@AllArgsConstructor
@JsonInclude
public class FilterKeyRequest {
@NotNull
private String parameter;
@NotNull
private FilterValue value;
}
Я попытался просто сопоставить filterKeys
с FilterKeyRequest
, что, конечно, не работает. Текущее решение состоит в том, чтобы выполнить десериализацию внутри метода контроллера:
@GetMapping("/data")
public List<TransferResponse> getData(@RequestParam(required = false) int someOtherParam,
@RequestParam(required = false) String filterKeys) throws BadFilterKeyParameter {
List<FilterKeyRequest> filters = List.of();
try {
filters = objectMapper.readValue(filterKeys, new TypeReference<List<FilterKeyRequest>>() {});
} catch (IOException e) {
throw new BadFilterKeyParameter("The filterKeys parameters couldn't be encoded due do bad JSON format");
}
return someService.getData(someOtherParam, filters);
}
Я бы действительно хотел элегантно справиться с этим где-нибудь на заднем плане. Это может быть возможно с org.springframework.core.convert.converter.Converter
или org.springframework.web.method.support.HandlerMethodArgumentResolver
как-то. Желательно без явного вызова объекта сопоставления объектов Джексона.
ОБНОВЛЕНИЕ: Я нашел решение с Converter
, но это все еще означает явное обращение к Джексону ObjectMapper
, но я могу жить с этим:
@Slf4j
@RequiredArgsConstructor
@Component
public class FilterKeyConverter implements Converter<String, List<FilterKeyRequest>> {
private final ObjectMapper mapper;
@Override
public List<FilterKeyRequest> convert(String source) {
List<FilterKeyRequest> filters = List.of();
try {
filters = mapper.readValue(source, new TypeReference<List<FilterKeyRequest>>() {});
} catch (IOException e) {
log.warn("The parameter couldn't be encoded due do bad JSON encoding");
}
return filters;
}
}