Конвертер работает для RequestParameter, но не для поля RequestBody - PullRequest
0 голосов
/ 19 февраля 2020

У меня есть следующий конвертер:

@Component
public class CountryEnumConverter implements Converter<String, CountryEnum> {

    @Override
    public CountryEnum convert(String country) {
        CountryEnum countryEnum = CountryEnum.getBySign(country);

        if (countryEnum == null) {
            throw new IllegalArgumentException(country + " - Country is not supported!");
        }

        return countryEnum;
    }
}

Зарегистрирован, он вызывается при использовании для RequestParam

@GetMapping(value = RestApiEndpoints.RESULTS, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ResultDto> getResults(
        Principal principal,
        @RequestParam CountryEnum country) {
    ....
}

Но этот конвертер никогда не вызывается при использовании для поля в RequstBody:

@GetMapping(value = RestApiEndpoints.RESULTS, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ResultDto> getResults(
        Principal principal,
        @RequestBody MyBody myBody) {
    ....
}

public class MyBody {

    @NotNull
    private CountryEnum country;


    public MyBody() {
    }

    public CountryEnum getCountry() {
        return country;
    }

    public void setCountry(CountryEnum country) {
        this.country = country;
    }

}

Ответы [ 2 ]

1 голос
/ 19 февраля 2020

Ваш существующий экземпляр org.springframework.core.convert.converter.Converter будет работать только с данными, представленными как данные, закодированные в форме. С @RequestBody вы отправляете JSON данные, которые будут десериализованы с использованием библиотеки Джексона.

Затем можно создать экземпляр com.fasterxml.jackson.databind.util.StdConverter<IN, OUT>

public class StringToCountryTypeConverter extends StdConverter<String, CountryType> {

  @Override
  public CountryType convert(String value) {
      //convert and return
  }
}

и применить его к целевому свойству:

public class MyBody {

    @NotNull
    @JsonDeserialize(converter = StringToCountryTypeConverter.class)
    private CountryEnum country;
}

Учитывая сходство 2 интерфейсов Я ожидаю, что вы можете создать один класс для обработки обоих сценариев ios:

public class StringToCountryTypeConverter extends StdConverter<String, CountryType> 
           implements org.springframework.core.convert.converter.Converter<String, CountryType> {
  @Override
  public CountryType convert(String value) {
      //convert and return
  }
}
0 голосов
/ 19 февраля 2020

Я обнаружил, что если я добавлю следующий код к моему CountryEnum, то добьюсь цели.

@JsonCreator
public static CountryEnum fromString(String value) {
    CountryEnumConverter converter = new CountryEnumConverter();
    return converter.convert(value);
}
...