При передачи boolean через postman записывается String
кейс:
В Postman, в строковое значение (String), передаю bolean(true или false). Все отлично отрабатывает c неправильными по типу данными, т.к. становится String = "false" ( как я понимаю это из-за протокола HTTP все приводится к строковым значениям).
JSON
{
"str": false
}
НО:
Мне надо, чтобы была ошибка, т.к. я передал булевое значение, false (без кавычек).
Как вариант решения:
Есть метод с параметром(@RequestBody @Valid Request request){};.
клас Request
@Data
public class Request {
private String str;
}
Я сделал свой валидатор над полем String (в классе Request). Если в это поле(String) записывается true или false, то @Valid кидает ошибку.
Мне кажется можно, как-то проще сделать...
Вопрос:
Есть ли способ легче это написать? может одной аннотацией или несколько строчек кода. Как можно оптимизировать?
Ответы (1 шт):
Это известное ограничение json парсера jackson, который используется в spring по-умолчанию. Суть проблемы в том, что парсер автоматически делает преобразование объекта в строку, хотя у него и есть контекст, т.е. тип, который ожидается.
Можно исправить глобально заменив десериализатор для строк, чтоб он не делал автоматическое преобразование в строку.
// ForceStringDeserializer.java
public class ForceStringDeserializer extends JsonDeserializer<String> {
@Override
public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
if (jsonParser.getCurrentToken() != JsonToken.VALUE_STRING) {
throw deserializationContext.wrongTokenException(
jsonParser, String.class, JsonToken.VALUE_STRING,
"Attempted to parse non-string to string but this is forbidden");
}
return jsonParser.getValueAsString();
}
}
// MyConfig.java
@Configuration
class MyConfig {
@Bean
public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() {
return new Jackson2ObjectMapperBuilder()
.serializerByType(String.class, new ForceStringDeserializer());
}
}