自定义AnnotationFormatterFactory不起作用

时间:2019-07-03 09:40:36

标签: java spring spring-mvc formatting

我正在尝试为我的模型运行我的格式化程序。该模型包含一个类似于以下代码的注释。我有多个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,如果可以,如何将其与注释一起使用?

更新:格式化程序已成功注册,但未调用。并添加了控制器。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

从您的上一次更新开始,我了解到您正在使用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"

还有另一种配置该解串器的方法,您可以查看:Can Jackson be configured to trim leading/trailing whitespace from all string properties?

但是为什么Formatter不起作用?我唯一的解释是@RequestBody/@ResponseBody没有处理WebMvcConfigurer