没有调用WebMvcConfigurerAdapter的Spring addFormatters

时间:2017-01-19 07:25:04

标签: java spring spring-mvc spring-boot converter

我尝试在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;
}

4 个答案:

答案 0 :(得分:0)

我不是100%肯定,但您是否尝试从课程中删除@EnableWebMvc注释?因为according to documentation它不应该存在:

  

如果您想保留Spring Boot MVC功能,并且只想添加其他MVC配置(拦截器,格式化程序,视图控制器等),您可以添加自己的@Configuration类WebMvcConfigurerAdapter,但不带< / strong> @EnableWebMvc。

答案 1 :(得分:0)

微米。 Deinum的评论就是答案。我已删除@EnableWebMvc并删除了方法addFormatters,然后添加了:

@Bean
StringToPersonConverter stringToPersonConverter() {
  return new StringToPersonConverter();
}

答案 2 :(得分:0)

您是否已使用超类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 {

答案 3 :(得分:-2)

我已经解决了类似的错误

EnableWebMvc

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}

DelegatingWebMvcConfiguration

@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);
    }

    //...

}

WebMvcConfigurationSupport

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,则不会调用该方法。

我使用带有弹簧版4.3.6的ConversionService Lazy注释解决了我的问题。