Spring Boot Converter API未按预期转换Sort对象问题排查
问题分析与解决方案
问题原因
你遇到的Converter被触发两次、生成两个PageSort实例的问题,核心原因是Converter被重复注册,同时继承WebMvcConfigurationSupport干扰了Spring Boot的默认参数绑定逻辑:
StringToPageSortConverter标注了@Component,Spring会自动扫描并将其注册到类型转换体系中;- 同时你在
WebMvcConfig里又通过registry.addConverter(stringToPageSortConverter())手动添加了一次该Converter实例,导致Converter被注册两次; - 当Spring处理
List<PageSort>类型参数时,两次注册的Converter会分别触发转换,第二次可能接收到空值或无效参数,生成错误的PageSort实例。
另外,继承WebMvcConfigurationSupport会禁用Spring Boot的Web MVC自动配置,加剧了参数绑定的异常。
解决方案
方案1:移除重复的Converter注册
选择以下任一方式,确保Converter仅被注册一次:
方式A:保留@Component,移除WebMvcConfig中的手动注册
修改WebMvcConfig,不再手动添加Converter,让Spring通过@Component自动扫描注册:
public class WebMvcConfig extends WebMvcConfigurationSupport { @Override protected void addFormatters(FormatterRegistry registry) { super.addFormatters(registry); } // 移除该@Bean方法,Converter已通过@Component注册 // @Bean // public StringToPageSortConverter stringToPageSortConverter(){ // return new StringToPageSortConverter(); // } }
方式B:移除@Component,保留WebMvcConfig中的注册
修改StringToPageSortConverter,去掉@Component注解:
// 移除@Component public class StringToPageSortConverter implements Converter<String, PageSort> { @Override public PageSort convert(String source) { PageSort pageSort; String[] _sort = source.split(","); if(_sort.length > 1){ pageSort = PageSort.builder() .sortBy(_sort[0]) .sortDirection(_sort[1]) .build(); }else{ pageSort = PageSort.builder() .sortBy(_sort[0]) .sortDirection("asc") .build(); } return pageSort; } }
方案2:替换WebMvcConfigurationSupport为WebMvcConfigurer(推荐)
Spring Boot中推荐实现WebMvcConfigurer接口而非继承WebMvcConfigurationSupport,这样不会禁用自动配置,更好兼容默认参数绑定逻辑:
@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addFormatters(FormatterRegistry registry) { registry.addConverter(new StringToPageSortConverter()); } }
同时确保StringToPageSortConverter上没有@Component(避免重复注册),若保留@Component则可去掉addFormatters中的手动添加逻辑。
额外优化:添加参数非空校验
在Converter的convert方法中加入非空校验,避免空参数导致的错误:
@Override public PageSort convert(String source) { if (source == null || source.trim().isEmpty()) { throw new IllegalArgumentException("Sort parameter cannot be empty"); } String[] _sort = source.split(","); // 原有转换逻辑不变 }
完成上述调整后,调用http://localhost:8081/api/projects?sort=projectId,desc时,Converter只会触发一次,projectPage中的sort列表仅包含一个正常的PageSort实例。
内容的提问来源于stack exchange,提问作者Shanka Somasiri
相关产品推荐
相关产品推荐

