Feign客户端支持可选请求参数

4

Feign客户端支持可选的请求参数吗?

例如,我有一个端点,但我找不到使用Feign客户端使param1成为可选项的方法。

@GetMapping(path = "endpoint1")
ResponseEntity request(@RequestParam(name = "param1", required = false, defaultValue = "key") String param1){}
3个回答

4

我通过创建自定义的FeignFormatterRegistrar,成功地使用了Feign中的可选请求参数(Optional request params)。以下是代码:

package feignformatters;

import org.springframework.cloud.openfeign.FeignFormatterRegistrar;
import org.springframework.format.FormatterRegistry;
import org.springframework.stereotype.Component;

import java.util.Optional;

@Component
public class OptionalFeignFormatterRegistrar implements FeignFormatterRegistrar {
    
    @Override
    public void registerFormatters(FormatterRegistry registry) {
        registry.addConverter(
            Optional.class, 
            String.class, 
            optional -> {
                if (optional.isPresent())
                    return optional.get().toString();
                else
                    return "";
            });
    }
}

以下客户端在之前的组件加载到项目中后开始正常工作:
@FeignClient("book-service")
public interface BookServiceClient {

    @GetMapping("/books")
    public List<Book> getBooks(
        @RequestParam("page") Optional<Integer> pageNum,
        @RequestParam("size") Optional<Integer> pageSize,
        @RequestParam("reader") Optional<Long> readerId);
}

1
谢谢,这对我们的项目很有帮助!我们不得不将return ""更改为return null,以便还能消除我们自己不需要的空字段。干杯! - undefined

4

由于您正在使用Spring Cloud Feign,我发现实现可选参数的最简单方法是使用DTO,并可选择实现构建器模式(Lombok可帮助使其不那么冗长)。

DTO将使请求中的参数变为可选(当为null时),而不是方法签名。方法的可选参数应该是几乎不可能的,但可以找到一些替代方案。点击这里查看

构建器模式将使初始化参数变为可选(或强制性)。详情请点击这里。构建器还可用于设置默认值。点击这里查看Lombok详情。 或者手动构建一个构建器。从维基百科开始点击这里查看一些Java代码示例

代码可能如下所示:

@GetMapping(path = "/endpoint1") //Not starting with / does not look ok...
ResponseEntity request(@SpringQueryMap MyDTO);

//MyDTO

import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class MyDTO {

  private String param1;
  private String param2;
  private String param3;
}

//when using

request(MyDTO.Builder().build()); //use all defaults
request(MyDTO.Builder().param1("foo").build()); //param1 set, all other defaults
request(MyDTO.Builder().param1("foo").param2("bar").build()); //param1 and param2 set

这是最干净的方法,不涉及创建任何自定义配置。 - Saideep Ullal

0

您可以使用简单的Map<String, String>,并用@SpringQueryMap进行注释,然后您可以传递任意数量的可选/必需参数。

@GetMapping("/task")
ResponseEntity<List<TaskResponse>> getTasks(@SpringQueryMap Map<String, String> queryParameters);

请确保在传递给地图的参数中,如果有一些参数是必填项,请进行验证。
就像这样:
List<TaskResponse> getTasks(@NotBlank final String mandatoryParam1, final String optionalParam2) {

        Map<String, String> parameters = new HashMap<>();
        parameters.put("mandatoryParam1", mandatoryParam1);
        Optional.ofNullable(optionalParam2)
                .ifPresent(nonNullParam -> parameters.put("optionalParam2", nonNullParam));

        return yourFiegnApiClient.getTasks(parameters).getBody();
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接