Пользовательская AnnotationFormatterFactory не работает

Я пытаюсь запустить свой Formatter для моей модели. Модель содержит аннотацию, подобную следующему коду. У меня есть несколько Formatter, которые я еще не запускаю, но не могу понять, в чем проблема.

public class Customer {
    @Trim
    private String firstName;
    //some other properties, getter and setter
}

Насколько я знаю, аннотация настроена правильно:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
public @interface Trim {
    boolean squashMultipleSpaces() default true;
}

И AnnotationFormatterFactory

public class TrimAnnotationFormatterFactory implements AnnotationFormatterFactory<Trim> {
    public TrimAnnotationFormatterFactory() {
    }

    public Set<Class<?>> getFieldTypes() {
        return Collections.singleton(String.class);
    }

    public Printer<String> getPrinter(Trim annotation, Class<?> fieldType) {
        return new TrimAnnotationFormatterFactory.TrimFormatter(annotation.squashMultipleSpaces());
    }

    public Parser<String> getParser(Trim annotation, Class<?> fieldType) {
        return new TrimAnnotationFormatterFactory.TrimFormatter(annotation.squashMultipleSpaces());
    }

    private static class TrimFormatter implements Formatter<String> {
        private final boolean squashMultipleSpaces;

        TrimFormatter(boolean squashMultipleSpaces) {
            this.squashMultipleSpaces = squashMultipleSpaces;
        }

        public String parse(String text, Locale locale) {
            return this.process(text);
        }

        public String print(String object, Locale locale) {
            return this.process(object);
        }

        private String process(String text) {
            if (text == null) {
                return null;
            } else {
                return this.squashMultipleSpaces ? text.trim().replaceAll("\\s+", " ") : text.trim();
            }
        }
    }
}

Я добавил свой собственный AnnotationFormatterFactory в FormatterRegistry. Когда я запускаю его, я вижу, что он успешно добавлен в FormatterRegistry.

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addFormatterForFieldAnnotation(new TrimAnnotationFormatterFactory());
    }
}

И контроллер выглядит так:

@Controller
public class CustomerController {

    @PostMapping(value = "/customer")
    @ResponseBody
    public Customer saveCustomer(@RequestBody Customer customer) {
        return customer;
    }
}

если мой ввод выглядит так

"       Christian     Walter"

в контроллере модель все та же. я ожидал

"Christian Walter"

в моей модели.

Почему мой форматтер не работает? Или мне нужно использовать PropertyEditor, и если да, то как я могу использовать его с аннотациями?

ОБНОВЛЕНИЕ: форматер успешно зарегистрирован, но не вызывается. И добавил контроллер.

Спасибо за вашу помощь.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
0
714
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Из вашего последнего обновления я понимаю, что вы используете json для десериализации своего объекта. В этом случае вам нужно (на мой взгляд) написать свой собственный десериализатор, как:

public class WhiteSpaceTrimmerDeserializer extends JsonDeserializer<String> {
    @Override
    public String deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
        JsonNode node = jp.getCodec().readTree(jp);
        return node.asText().replaceAll("\\s+", " ").trim();
    }
}

И используйте его как:

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
public class Customer {

    private String firstName;


    public String getFirstName() {
        return firstName;
    }

    @JsonDeserialize(using = WhiteSpaceTrimmerDeserializer.class)
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
}

Итак, " Christian Walter" будет производить "Christian Walter".

Есть и другие способы настроить этот десериализатор, вы можете посмотреть: Можно ли настроить Джексона для обрезки начальных/конечных пробелов из всех строковых свойств?

Но почему Formatter не работает? Единственное объяснение, которое у меня есть, это то, что @RequestBody/@ResponseBody не обрабатывается WebMvcConfigurer.

Нет. Это не проблема. Он должен сжать все пробелы до одного. Проблема в том, что форматер не вызывается. Они успешно регистрируются, но не вызываются.

Manuel 09.07.2019 21:22

Я поместил ваш код здесь github.com/mcherb/gs-serving-web-content/tree/master/complete‌​e, и он отлично работает! у нас такая же конфигурация? Вы можете поделиться своим кодом на github?

bubbles 09.07.2019 23:36

Я вижу, что ваш контроллер работает. Это интересно. Когда я обновляю ваш код в соответствии со своими потребностями, он больше не работает. Я думал, что форматер также работает, если я использую контроллер, как в моем обновленном вопросе. Взгляните на мой контроллер. Вывод по-прежнему не отформатирован.

Manuel 10.07.2019 12:03

Не могли бы вы добавить свой HTML-шаблон?

bubbles 10.07.2019 12:08

Шаблона нет. Это просто отдых. Потребление и производство json

Manuel 10.07.2019 15:38

@ManuelPolacek, я обновил свой ответ в соответствии с вашей последней информацией.

bubbles 10.07.2019 21:08

Я попытался запустить его с аннотацией сериализации json deserialize, но он еще не работает. Я думаю, вы правы с телом запроса и ответа. Похоже на другое поведение. Сегодня я проведу несколько тестов и сообщу вам, сработала ли реализация сегодня или нет. Заранее спасибо.

Manuel 11.07.2019 08:10

добро пожаловать, я уже протестировал его, прежде чем ставить, я могу обновить свой проект github, если вы хотите

bubbles 11.07.2019 16:54

Другие вопросы по теме