Spring REST - 有没有办法覆盖 Spring 用来将查询参数分隔到值列表中的字符?



我正在使用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 请求。

任何建议将不胜感激,谢谢!

>由于URL编码问题,404即将到来。

您需要编码|然后它将起作用,但它会产生另一个问题,参数不会被拆分。

要解决此问题,您需要创建一个自定义转换,该转换可以将String转换为Collection。对于自定义转换,您可以检查StringToCollectionConverter类。自定义转换后,您可以注册该服务,在任何配置类中添加以下函数


@Autowired
void conversionService(GenericConversionService genericConversionService) {
genericConversionService.addConverter(myStringToCollectionConvert());
}
@Bean
public MyStringToCollectionConvert myStringToCollectionConvert() {
return new MyStringToCollectionConvert();
}

在此MyStringToCollectionConvert中,类将分析String并转换为字符串集合。

我已经接受了 Sonus21 的回答,因为他的建议允许我找到一个有效的例子,但我的解决方案并不完全是他的。

实际上,StringToCollectionConverter类对我来说确实存在,但它无法访问,我无法以任何方式使用它。然而,在查看它实现的接口(ConditionalGenericConverter(并搜索更多使用Spring转换器的示例时,我最终选择了以下解决方案。

我问题中的listParam实际上是指一组枚举值。我做的第一件事是重写我的控制器,使其实际使用枚举值而不是原始整数。

@GetMapping("/api/endpoint")
public ResponseEntity endpoint(@RequestParam("listParam" List<EnumClass> listParam){
// ...
}

接下来,我写了一个Spring Custom Converter(Baeldung Doc(

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 并使用 Spring 注册了这个自定义转换器:

@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry){
registry.addConverter(new CustomStringToEnumClassListConverter());
}
}

完成所有这些操作后,Spring 会自动用EnumClass对象填充listParam列表。

最新更新