Я создал свой запрос POJO следующим образом
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Notification {
@NotNull
private String clientId;
private String userId;
@NotNull
private String requestingService;
@NotNull
private String message;
@NotNull
private String messageType;
когда я отправляю тело запроса, как показано ниже, он работает нормально.
{
"clientId":"9563",
"userId":"5855541",
"requestingService":"cm-dm-service",
"message":"Document Created",
"messageType":"user-msg"
}
Но когда я отправил, как показано ниже
{
"clientId":"9563",
"userId":true,
"requestingService":"cm-dm-service",
"message":"Document Created",
"messageType":"user-msg"
}
Вот мой контроллер
public ResponseEntity<Status> createNotification(@RequestBody @Valid Notification notification,
BindingResult bindingResult, HttpServletRequest request) throws AppException {
Ожидается: выдать ошибку
Фактически: преобразование истинного значения для userId в строку Джексоном.
пожалуйста, дайте мне знать, есть ли способ добиться ожидаемого поведения
Пожалуйста, проверьте stackoverflow.com/questions/12546810/…
@burm87 отредактировал. На самом деле это логический тип




Джексон NumberDeserializers.BooleanDeserializer запрограммирован на преобразование логического значения в строку.
Мы можем переопределить десериализатор нашим, предотвратить преобразование и вместо этого генерировать исключение.
Я могу привести вам пример, вы пытаетесь внедрить его в свою постановку задачи.
public class MyDeser extends JsonDeserializer {
@Override
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
JsonToken t = p.getCurrentToken();
if (t.isBoolean()) {
throw new Exception();
}
else if (t.isNumeric()) {
throw new Exception();
}
else if (t == JsonToken.VALUE_STRING) {
return p.getValueAsString();
}
return null;
}
}
@SpringBootApplication
@Configuration
public class Application {
@Bean
public SimpleModule injectDeser() {
return new SimpleModule().addDeserializer(String.class, new MyDeser());
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Здесь t.asString() вернул null. Поэтому я использовал p.getValueAsString(); а также изменил тип возвращаемого значения на String. общедоступная десериализация строки (.....). После этого код работает нормально, как и ожидалось. Спасибо Шринивасу Рагхавану.
Привет, я отредактировал это, как вы сказали. Если это решение, о котором вы просили, примите этот ответ как решение, чтобы оно было полезно и для других. Спасибо
По умолчанию com.fasterxml.jackson.databind.deser.std.StringDeserializer принимает скалярные значения. В этом случае вы можете реализовать собственный десериализатор и выдать исключение:
class StrictStringDeserializer extends StringDeserializer {
@Override
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
JsonToken token = p.currentToken();
if (token.isScalarValue()) {
ctxt.reportInputMismatch(String.class, "%s is not a `String` value!", token.toString());
return null;
}
return super.deserialize(p, ctxt);
}
}
Для регистрации используйте SimpleModule:
SimpleModule strictModule = new SimpleModule();
strictModule.addDeserializer(String.class, new StrictStringDeserializer());
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(strictModule);
Чтобы узнать, как это сделать в Spring, прочитайте: Настройте Jackson ObjectMapper.
Если вы хотите изменить его только для одного поля: userId используйте аннотацию JsonDeserialize:
@JsonDeserialize(using = StrictStringDeserializer.class)
private String userId;
Смотрите также:
Что такое
**true**?