Как да използвам различни кодове за грешка за съобщения за проверка?

Имам Spring Boot REST сървър, който трябва да връща специфични кодове за грешка, когато е предоставен невалиден вход. Нямам нужда от i18n тук, достатъчни са само обикновени английски кодове за грешка като „липсва“.

Използвайки Spring Boot с Hibernate Validator, след валидиране получавам обратно Spring Errors обект.

За всяка грешка мога да получа code и defaultMessage. За ограничение @NotBlank това ще върне съответно NotBlank и may not be null.

По принцип искам да преведа тази грешка само на missing, тъй като не се интересувам от i18n превод. Също така други ограничения. Искам да имам по-удобни за REST кодове за грешки.

Исках да използвам просто messages.properties или ValidationMessages.properties вътре в src/main/resources, но това няма да работи за съжаление. Забележете, че опитах да добавя както общи NotBlank=missing, така и специфични NotBlank.entity.field=missing свойства.

Не съм сигурен защо не работи... може би защото разрешаването на i18n съобщения (в света на jsp) не минава директно през Spring Errors, а през имплементацията MessageCodesResolver (само предполагам).

Вероятно бих могъл да получа кода за грешка от Spring Error и да направя търсене от резолвера на кода на съобщението. Но се чудя защо error.getDefaultMessage не връща подходящата стойност от ValidationMessages.properties.

Всяко предложение е добре дошло.


person Marcel Overdijk    schedule 30.12.2014    source източник
comment
Тъй като error.getDefaultMessage получава съобщението по подразбиране и това е съобщението, генерирано от код, а не от файлове със свойства. Ако погледнете MessageSource.getMessage виждате, че defaultMessage е предаден. Същият механизъм се използва при използване на валидиране.   -  person M. Deinum    schedule 31.12.2014
comment
Благодаря за обяснението! Какво бихте предложили да продължим напред?   -  person Marcel Overdijk    schedule 31.12.2014
comment
Можете просто да предадете грешката (както е) на MessageSource грешките, върнати от обекта Errors, са всички екземпляри на MessageSourceResolvable. Така че просто прегледайте грешките, предайте ги на MessageSource и получете съобщението, което искате от messages.properties. Може би бихте могли да облагородите тази логика и да я поставите в клас, който генерира обект на отговор.   -  person M. Deinum    schedule 31.12.2014
comment
Да, както сам предложих. Мерси!   -  person Marcel Overdijk    schedule 31.12.2014
comment
Добре, вие предложихте да използвате кода, не е нужно да правите това, просто предайте обекта такъв, какъвто е.   -  person M. Deinum    schedule 31.12.2014
comment
Ок, разбирам какво имаш предвид.   -  person Marcel Overdijk    schedule 31.12.2014


Отговори (1)


Съобщението по подразбиране е съобщението, посочено от програмиста. В случая с тези анотации JSR-303 вероятно тези, които Hibernate са се сетили за тях. Съобщението по подразбиране, включващо кода, се предава на MessageSource.getMessage метод, който съдържа параметър defaultMessage

Когато погледнете обекта Errors или всъщност метода ObjectError, ще видите, че той имплементира интерфейса MessageSourceResolvable. Това означава, че можете просто да предадете грешката, както е, на MessageSource, включително Locale, ако желаете.

@RequestMapping
public Object foo(@Valid @RequestBody MyObject obj, Errors errors, Locale locale) {
    for (ObjectError err : errors.getAllErrors()) {
        String msg = messageSource.getMessage(err, locale);
        // Do something with msg
    }
}

Нещо като горното трябва да разреши съобщението. Предимството на използването на самия ObjectError е, че до кода имате и параметрите (за @Range или @Min), които след това можете да използвате в съобщението си със запазени места.

person M. Deinum    schedule 30.12.2014
comment
Съобщенията по подразбиране на валидатора за хибернация на Ps трябва да бъдат заменени чрез ValidationMessages.properties, но изглежда не работят (поне в приложението Spring). Вижте също docs.jboss. org/hibernate/validator/5.1/reference/en-US/html/ - person Marcel Overdijk; 31.12.2014
comment
Правилно, защото това отменя този механизъм, така че да може да се използва MessageSource. ValidationMessages.properties се прилага в обикновен JSR-303. Това е обяснено в LocalValidatorFactoryBean javadoc. - person M. Deinum; 31.12.2014
comment
Хм, възможно ли е да се промени това поведение през пролетта? Така че да използвам ValidationMessages.properties? - person Marcel Overdijk; 31.12.2014
comment
Можем ли автоматично да разрешим съобщението за грешка, без да инжектираме message source и locale във всеки от контролерите? Това е наистина обезпокоително, защото мога да го направя в анотация за хибернация, но защо Spring validator не работи. - person Sam YC; 13.07.2017