我正在使用Spring编写一个REST API,并且有一些客户端不能或不会改变他们调用我的服务的方式。
通常,当发送一个带有值列表的查询参数时,你只需用逗号分隔参数,Spring就会完成剩下的工作。curl http://host.com/api/endpoint?listParam=1,2,3
和控制器
@GetMapping("/api/endpoint")
public ResponseEntity endpoint(@RequestParam("listParam" List<String> listParam){
// Here, listParam is populated with 1,2,3
}
不幸的是,我的客户将通过列表与酒吧 |
定界符,根本不可能让他们改变。举个例子。 curl http://host.com/api/endpoint?listParam=1%7C2%7C3%7C
我还是想用Spring把这些调用分解成列表,这样我就不必用手动的 String.split()
呼叫。
我已经试过的。 我发现 @InitBinder
注释,并写了以下内容
@InitBinder
public void initBinder(WebDataBinder dataBinder){
dataBinder.registerCustomEditor(String[].class, new StringArrayPropertyEditor("|"));
}
但是,这段代码似乎从来没有被调用过(用断点观察),而且使用条形作为定界符的请求会以400 BAD REQUEST失败。
任何建议都会非常感激,谢谢!
由于URL编码问题,出现404。
您需要对以下内容进行编码 |
那么它将会工作,但它会产生另一个问题,params不会被分割。
为了解决这个问题,你需要创建一个自定义的转换,它可以转换为 String
到 Collection
. 对于自定义转换,你可以查看 StringToCollectionConverter
类。一旦你有了自定义转换,那么你就可以注册该服务,在任何一个配置类中添加以下功能
@Autowired
void conversionService(GenericConversionService genericConversionService) {
genericConversionService.addConverter(myStringToCollectionConvert());
}
@Bean
public MyStringToCollectionConvert myStringToCollectionConvert() {
return new MyStringToCollectionConvert();
}
在此 MyStringToCollectionConvert
是将解析 String
并转换为Strings的集合。
我接受了Sonus21的答案,因为他的建议让我找到了一个可行的例子,但我的解决方案并不完全是他的。
这个类 StringToCollectionConverter
对我来说确实存在,但它无法访问,我无法以任何方式使用它。然而,在看了它所实现的接口后(ConditionalGenericConverter
),并搜索更多的Spring转换器的例子,我最终确定了以下解决方案。
该 listParam
在我的问题中,实际上指的是一组Enum值。我做的第一件事是重写控制器,使其使用Enum值而不是原始的Integer。
@GetMapping("/api/endpoint")
public ResponseEntity endpoint(@RequestParam("listParam" List<EnumClass> listParam){
// ...
}
public class CustomStringToEnumClassListConverter implements Converter<String, List<EnumClass>> {
@Override
public List<EnumClass> convert(String str) {
return Stream.of(
str.split("\\|")) // Here is where we manually delimit the incoming string with bars instead of commas
.map(i -> EnumClass.intToValue(Integer.parseInt(i))) // intToValue is a method I wrote to get the actual Enum for a given int
.collect(Collectors.toList());
}
}
最后,我写了一个Config Bean,并将这个Custom Converter注册到Spring中。
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry){
registry.addConverter(new CustomStringToEnumClassListConverter());
}
}
一旦这些都完成了,Spring就会自动地填充了 listParam
列表 EnumClass
对象。