在我的应用程序中,我使用 spring webflux,并使用 webclient 从某些第 3 方 API 检索详细信息。现在,我想将第一次 webClient 响应存储在内存缓存中,以便第二次我可以直接从缓存中获取这些响应。我正在尝试在内存缓存机制和“咖啡”中使用Spring boot。但没有一个能按预期工作。 应用程序.yml:
spring:
cache:
cache-names: employee
caffiene:
spec: maximumSize=200, expireAfterAccess=5m
Run Code Online (Sandbox Code Playgroud)
EmployeeApplication.java:
@SpringBootApplication
@EnableCaching
public class EmployeeApplication{
public static void main(String[] args){
}
}
Run Code Online (Sandbox Code Playgroud)
EmployeeController.java:
它有一个休息端点employee/all,可以从第 3 方 Api 获取所有员工。
EmployeeService.java:
@Service
@Slf4j
public class EmployeeService{
@Autowired
private WebClient webClient;
@Autowired
private CacheManager cacheManager;
@Cacheable("employee")
public Mono<List<Employee>> getAllEmployee(){
log.info("inside employee service {}");
return webClient.get()
.uri("/employees/")
.retrieve()
.bodyToMono(Employee.class);
}
}
Run Code Online (Sandbox Code Playgroud)
虽然我已经配置了缓存名称,但当我第二次点击该网址时,它正在调用服务方法。需要使用什么缓存机制来缓存 Mono 响应?请建议。
我们有一个使用已弃用的 @StreamListener 的 Spring boot 项目,现在我们正在切换到 Spring Cloud Stream 功能性 kafka 绑定器。
问题是这个服务连接到多个kafka主题并且我们的单线spring.cloud.function.definition: topicA;topicB;topicC;...;topicN变得很长
我想知道如何在 Spring 的application.yaml上使用yaml 功能,例如多行值(例如 | 或 > 运算符),但我在文档中没有找到类似的内容。
我的目标是这样的
spring.cloud.function.definition: | topicA;
topicB;
topicC;
...;
topicN
Run Code Online (Sandbox Code Playgroud)
谢谢
我有这段代码,它使用 WebClient 调用第三方 API。
public Mono<JsonNode> callApi(String url) {
return webClient.get()
.uri(url)
.headers(httpHeaders -> httpHeaders.set(Constants.X_API_KEY, apiKey))
.retrieve()
.onStatus(HttpStatus::is5xxServerError,
res -> {
res.bodyToMono(String.class)
.subscribe(e -> log.error(Constants.EXCEPTION_LOG, e));
return Mono.error(new RetryableException("Server error: " + res.rawStatusCode()));
})
.onStatus(HttpStatus::is4xxClientError,
res -> {
res.bodyToMono(String.class)
.subscribe(e -> log.error("Exception occurred in callPartnerApi: No retries {}", e));
return Mono.error(new Exception("Exception occurred calling partner api, no retries " + res.rawStatusCode()));
})
.bodyToMono(JsonNode.class);
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试使用 Mockito 对此进行单元测试,到目前为止我的测试失败了:
@Test
void testCallPartnerApi_then5xxException() {
WebClient.RequestHeadersUriSpec requestHeadersUriSpec = mock(WebClient.RequestHeadersUriSpec.class);
WebClient.RequestHeadersSpec requestHeadersSpec = mock(WebClient.RequestHeadersSpec.class);
WebClient.ResponseSpec …Run Code Online (Sandbox Code Playgroud) 我的 Spring Boot 应用程序(版本 2.6.3)有问题。我已经配置了反应式弹簧安全性,如下所示:
我的应用程序.java:
@SpringBootApplication
@EnableWebFlux
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class);
}
@Bean
public SecurityWebFilterChain springSecurityFilterChain(final ServerHttpSecurity http, final ReactiveOpaqueTokenIntrospector reactiveOpaqueTokenIntrospector) {
return http.authorizeExchange()
.anyExchange().authenticated()
.and()
.httpBasic().disable()
.cors().and()
.logout().disable()
.formLogin().disable()
.oauth2ResourceServer()
.opaqueToken()
.introspector(reactiveOpaqueTokenIntrospector)
.and().and()
.csrf()
.disable()
.build();
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的网络资源(控制器):
MyWebResource.java:
@RestController
public class MyWebResource implements MyWebResourceApi {
@PreAuthorize("hasRole('ROLE_USER')")
@Override
public Mono<String> details(String userId, ServerWebExchange exchange) {
return exchange.getPrincipal().map(Principal::getName);
}
}
Run Code Online (Sandbox Code Playgroud)
它工作正常,当我的访问令牌过期或不正确时,请求应该被拒绝。但是,当预授权允许请求时,我的用户主体将永远不会在我的交换中得到解决...
我正在学习教程,我相信我的代码与讲师的代码相同,但我不明白为什么delayElements()不起作用。
这是调用者方法:
public static void main(String[] args) {
FluxAndMonoGeneratorService fluxAndMonoGeneratorService = new FluxAndMonoGeneratorService();
fluxAndMonoGeneratorService.explore_merge()
.doOnComplete(() -> System.out.println("Completed !"))
.onErrorReturn("asdasd")
.subscribe(System.out::println);
}
Run Code Online (Sandbox Code Playgroud)
如果我将没有延迟元素的方法编写为:
public Flux<String> explore_merge() {
Flux<String> abcFlux = Flux.just("A", "B", "C");
Flux<String> defFlux = Flux.just("D", "E", "F");
return Flux.merge(abcFlux, defFlux);
}
Run Code Online (Sandbox Code Playgroud)
然后控制台中的输出是(如预期):
00:53:19.443 [main] DEBUG reactor.util.Loggers$LoggerFactory - Using Slf4j logging framework
A
B
C
D
E
F
Completed !
BUILD SUCCESSFUL in 1s
Run Code Online (Sandbox Code Playgroud)
但我想使用delayElements()来测试merge()方法:
public Flux<String> explore_merge() {
Flux<String> abcFlux = Flux.just("A", "B", …Run Code Online (Sandbox Code Playgroud)