每当我通过假装客户端发出请求时,我都希望为我的身份验证用户设置一个特定的标头.
这是我的过滤器,我从中获取身份验证并将其设置为spring安全上下文:
@EnableEurekaClient
@SpringBootApplication
@EnableFeignClients
public class PerformanceApplication {
@Bean
public Filter requestDetailsFilter() {
return new RequestDetailsFilter();
}
public static void main(String[] args) {
SpringApplication.run(PerformanceApplication.class, args);
}
private class RequestDetailsFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
String userName = ((HttpServletRequest)servletRequest).getHeader("Z-User-Details");
String pass = ((HttpServletRequest)servletRequest).getHeader("X-User-Details");
if (pass != null)
pass = decrypt(pass);
SecurityContext secure = new SecurityContextImpl();
org.springframework.security.core.Authentication token = new UsernamePasswordAuthenticationToken(userName, …Run Code Online (Sandbox Code Playgroud) 我遇到了需要为第三方API定义一次性@FeignClient的场景.在这个客户端中,我想使用与我的@Primary不同的自定义Jackson ObjectMapper.我知道可以覆盖spring的feign配置默认值,但是我不清楚如何只是通过这个特定的客户端简单地覆盖ObjectMapper.
我有这样的FeignClient
@RequestLine("POST /enroll")
@Headers({ "header1: {header1}", "header2: {header2}", "Content-Type: application/json" })
ResponseDto enroll(@Param("header1") String header1,@Param("header1") String header1, RequestDto requestDto)throws MyCustomException;
Run Code Online (Sandbox Code Playgroud)
`我没有使用spring cloud netflix.但我一直得到以下例外.
Caused by: java.lang.IllegalStateException: Body parameters cannot be used with form parameters.
at feign.Util.checkState(Util.java:128)
at feign.Contract$BaseContract.parseAndValidateMetadata(Contract.java:112)
at feign.Contract$BaseContract.parseAndValidatateMetadata(Contract.java:64)
at feign.ReflectiveFeign$ParseHandlersByName.apply(ReflectiveFeign.java:146)
at feign.ReflectiveFeign.newInstance(ReflectiveFeign.java:53)
at feign.Feign$Builder.target(Feign.java:209)
at feign.Feign$Builder.target(Feign.java:205)
Run Code Online (Sandbox Code Playgroud)
我像这样实例化我的客户端.
return Feign.builder()
.encoder(new JacksonEncoder())
.decoder(new JacksonDecoder())
.logger(new Slf4jLogger())
.logLevel(Logger.Level.FULL)
.target(RegularFeignClient.class, url);
Run Code Online (Sandbox Code Playgroud) 我正在使用spring-cloud-starter-openfeignclient 编写 Eureka 客户端应用程序。这是我的POM
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>service-registration-and-discovery-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>service-registration-and-discovery-client</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin> …Run Code Online (Sandbox Code Playgroud) spring-cloud netflix-eureka spring-cloud-feign feign openfeign
我正在使用 Feign 编写 REST 客户端。有一个端点可以通过参数化路径来概括。但是根据路径,我可以获得不同类型的响应。
所以我试图使用通用的单一方法。由于我必须在返回类型上告诉方法,因此我正在参数化返回值的类型,如下所示,
@RequestLine("GET /objects/{type}/{model_id}")
public <T> Entity<T> getObject(
@Param("type") String theObjectType, @Param("model_id") String theModelId,
Class<T> theResponseClass);
Run Code Online (Sandbox Code Playgroud)
但问题是,Feign 会theResponseClass用作 body。如何实现通用的假客户端方法?
我知道我们可以通过提供 url Ex 来强制 FeignClient 使用 OkHttp 而不是 Ribbon。 @FeignClient(url="serviceId", name="serviceId")
即使只提供了名称,我也希望使用 OkHttpClient。前任。@FeignClient(name="serviceId")
根据 spring cloud 文档“如果启用 Ribbon,则它是 LoadBalancerFeignClient,否则使用默认的 feign 客户端。”
如何禁用功能区以便使用默认的伪装客户端。
spring-cloud netflix-feign spring-cloud-feign feign spring-cloud-netflix
如何记录Feign客户端请求、响应和 URL的负载。我必须实现拦截器吗?因为我的要求是在数据库的特殊表上记录请求和响应。
我在 Spring Boot 应用程序中有多个伪装客户端。我正在使用控制器建议来处理每个假客户端的自定义异常。
这里我的控制器建议处理两个自定义异常(每个客户端一个:client1 和 client2):
@ControllerAdvice
public class ExceptionTranslator implements ProblemHandling {
@ExceptionHandler
public ResponseEntity<Problem> handleCustomClient1Exception(CustomException1 ex, NativeWebRequest request) {
Problem problem = Problem.builder()
.title(ex.getTitle())
.detail(ex.getMessage())
.status(ex.getStatusType())
.code(ex.getCode())
.build();
return create(ex, problem, request);
}
@ExceptionHandler
public ResponseEntity<Problem> handleCustomClient2Exception(CustomException2 ex, NativeWebRequest request) {
Problem problem = Problem.builder()
.title(ex.getTitle())
.detail(ex.getMessage())
.status(ex.getStatusType())
.code(ex.getCode())
.build();
return create(ex, problem, request);
}
}
Run Code Online (Sandbox Code Playgroud)
我已经为 feign client1 实现了一个错误解码器。
public class ClientErrorDecoder implements ErrorDecoder {
final ObjectMapper mapper;
public ClientErrorDecoder() {
this.mapper = new ObjectMapper();
} …Run Code Online (Sandbox Code Playgroud) 我尝试在 Spring 中为 REST 服务控制器创建一个假客户端。
@PostMapping("/search")
public Page<MeasureDto> searchMeasures(@RequestBody MeasureDto example, Pageable pageable) {
...
}
Run Code Online (Sandbox Code Playgroud)
客户端看起来像这样:
@PostMapping("/search")
public Page<MeasureDto> searchMeasures(@RequestHeader("apiKey") String apiKey, @RequestBody MeasureDto example, Pageable pageable);
Run Code Online (Sandbox Code Playgroud)
运行测试时抛出以下异常:
引起原因:java.lang.IllegalStateException:方法有太多主体参数:公共抽象org.springframework.data.domain.Page com.foo.bar.jobservice.client.MeasureServiceClient.searchMeasures(java.lang.String,com.example .foo.jobservice.client.dto.MeasureDto,org.springframework.data.domain.Pageable)
我已经知道/尝试过的:
github上有一个已关闭的问题:https://github.com/spring-cloud/spring-cloud-netflix/issues/556
应该已经解决问题的提交问题:
https://github.com/spring-cloud/spring-cloud-openfeign/issues/26
提交:
我配置了什么:
import feign.codec.Encoder;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.support.PageJacksonModule;
import org.springframework.cloud.openfeign.support.PageableSpringEncoder;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@EnableFeignClients
@Configuration
public class FeignConfig {
@Bean
public PageJacksonModule pageJacksonModule() {
return new PageJacksonModule();
}
@Autowired
private ObjectFactory<HttpMessageConverters> messageConverters;
@Bean …Run Code Online (Sandbox Code Playgroud) 我正在尝试组合 2 个或更多服务,并且我想检查它们的状态并返回自定义响应。例如,其中一个返回 200,另一个返回 500、404、400 等。在这种情况下,我想返回空列表。下面的示例仅当所有服务返回 200 时才有效
@RestController
@RequiredArgsConstructor
public class Demo3Controller {
private final Demo1Client demo1Client;
private final Demo2Client demo2Client;
@GetMapping("/demo3")
public String get(){
return demo1Client.getDemo1() + "&&" + demo2Client.getDemo2();
}
}
Run Code Online (Sandbox Code Playgroud) feign ×10
spring ×5
java ×4
spring-boot ×3
spring-cloud ×3
openfeign ×2
generics ×1
header ×1
httpclient ×1
interceptor ×1
logging ×1
request ×1
spring-mvc ×1