我正在尝试在
Spring
启动应用程序中实现转换器,但由于某种原因,我对 addFormatters(FormatterRegistry formatterRegistry)
的覆盖从未被调用。令人困惑的是,调用了其他重写的方法,addInterceptors
工作得很好。此应用程序已启用安全性。
@EnableWebMvc
@Configuration
@ComponentScan(basePackages = {"com.company.web"})
public class WebMvcConfig extends WebMvcConfigurerAdapter {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
@Inject
private TenantIdentifierInterceptorAdapter multiTenancyInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
logger.info("adding interceptor");
registry.addInterceptor(multiTenancyInterceptor);
}
//THIS IS NOT CALLED
@Override
public void addFormatters(FormatterRegistry formatterRegistry) {
logger.info("adding converters");
formatterRegistry.addConverter(new StringToPersonConverter());
}
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {"classpath:/META-INF/resources/",
"classpath:/resources/", "classpath:/static/", "classpath:/public/"};
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS)
.setCachePeriod(3600).resourceChain(true).addResolver(new PathResourceResolver());
}
@PostConstruct
public void init() {
requestMappingHandlerAdapter.setIgnoreDefaultModelOnRedirect(true);
}
}
出于某种原因,如果我将此代码添加到文件中,则会命中格式化程序代码,但我收到错误“需要 ServletContext 来配置默认 servlet 处理”,并且应用程序将无法编译。
@Bean
public ResourceBundleMessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
您是否使用超类 WebMvcConfigurationSupport 配置了 bean?
如果您这样做,它将禁用 WebMvcAutoConfiguration Bootstrap。
检查此代码:
@Configuration
@ConditionalOnWebApplication(
type = Type.SERVLET
)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
@AutoConfigureOrder(-2147483638)
@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, ValidationAutoConfiguration.class})
public class WebMvcAutoConfiguration {
我不是 100% 确定,但您是否尝试从类中删除
@EnableWebMvc
注释?因为根据文档它不应该在那里:
如果您想保留 Spring Boot MVC 功能,并且只想添加额外的 MVC 配置(拦截器、格式化程序、视图控制器等),您可以添加自己的 WebMvcConfigurerAdapter 类型的 @Configuration 类,但不使用 @EnableWebMvc。
M。 Deinum 的评论就是答案。我删除了
@EnableWebMvc
并删除了方法 addFormatters
,然后添加了:
@Bean
StringToPersonConverter stringToPersonConverter() {
return new StringToPersonConverter();
}
我遇到了同样的问题(
addFormatters()
没有被调用),最终通过自动装配FormatterRegistry
并从ApplicationContextAware.setApplicationContext()
添加我的转换器来解决它。
Spring Boot 2.7.0
public class WebConfig implements WebMvcConfigurer, ApplicationContextAware
{
@Autowired
FormatterRegistry registry;
@Override
public void setApplicationContext(ApplicationContext ctx) {
registry.addConverter(new CardTypeConverter());
}
}
我已经解决了类似的错误
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}
@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();
@Autowired(required = false)
public void setConfigurers(List<WebMvcConfigurer> configurers) {
if (!CollectionUtils.isEmpty(configurers)) {
this.configurers.addWebMvcConfigurers(configurers);
}
}
//...
@Override
protected void addFormatters(FormatterRegistry registry) {
this.configurers.addFormatters(registry);
}
//...
}
public class WebMvcConfigurationSupport implements ApplicationContextAware, ServletContextAware {
//...
@Bean
public FormattingConversionService mvcConversionService() {
FormattingConversionService conversionService = new DefaultFormattingConversionService();
addFormatters(conversionService);
return conversionService;
}
/**
* Override this method to add custom {@link Converter}s and {@link Formatter}s.
*/
protected void addFormatters(FormatterRegistry registry) {
}
//...
}
我的自定义配置具有多个 WebMvcConfigurerAdapter 实现 WebMvcConfigurer
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter
{
@Autowired
private ConversionService conversionService;
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers)
{
argumentResolvers.add(new RequestTenantResolverComposite(conversionService));
}
}
如果 FormattingConversionService 实现了在注入 WebMvcConfigurer 之前创建的 ConversionService bean,则不会调用该方法。
我使用 spring 版本 4.3.6 的 ConversionService 的 Lazy 注释解决了我的问题。