以下示例仅供参考,提供实现思路,并不能直接使用,可能会出现意向不到BUG,因为我只是单存的测试某个效果
package luck.spring.boot.webflux;
import lombok.extern.slf4j.Slf4j;
import org.reactivestreams.Publisher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.ResolvableType;
import org.springframework.http.MediaType;
import org.springframework.http.codec.EncoderHttpMessageWriter;
import org.springframework.http.codec.HttpMessageReader;
import org.springframework.http.codec.HttpMessageWriter;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.http.codec.json.Jackson2JsonEncoder;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.util.MimeType;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.reactive.config.CorsRegistry;
import org.springframework.web.reactive.config.DelegatingWebFluxConfiguration;
import org.springframework.web.reactive.config.WebFluxConfigurer;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.Map;
// 如果需要高度自定WebFlux的配置,可以继承DelegatingWebFluxConfiguration进行扩展
// 因为@EnableWebFlux导入的是默认的DelegatingWebFluxConfiguration
// @EnableWebFlux
@Configuration
@Slf4j
public class WebFluxConfig extends DelegatingWebFluxConfiguration {
// 设置请求跨域的过滤器,这个跨域处理事通过过滤器处理的
// 和addCorsMappings
// @Bean
public CorsWebFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return new CorsWebFilter(source);
}
@Bean
public WebFluxConfigurer webFluxConfigurer() {
return new WebFluxConfigurer() {
@Override
public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
// 开启编码解码器的详细日志信息
configurer.defaultCodecs().enableLoggingRequestDetails(true);
List<HttpMessageWriter<?>> writers = configurer.getWriters();
List<HttpMessageReader<?>> readers = configurer.getReaders();
// 自定义的编码解码器,就是对请求响应体的处理器
EncoderHttpMessageWriter<Object> writer = new EncoderHttpMessageWriter<>(new Jackson2JsonEncoder() {
@Override
public boolean canEncode(ResolvableType elementType, MimeType mimeType) {
return CharSequence.class.isAssignableFrom(elementType.resolve()) || super.canEncode(elementType, mimeType);
}
}) {
@Override
public Mono<Void> write(Publisher<?> inputStream, ResolvableType actualType, ResolvableType elementType, MediaType mediaType, ServerHttpRequest request, ServerHttpResponse response, Map<String, Object> hints) {
if (CharSequence.class.isAssignableFrom(elementType.resolve())) {
mediaType = MediaType.APPLICATION_JSON;
}
if (inputStream instanceof Flux flux) {
inputStream = flux.flatMap(value -> {
if (!(value instanceof Result)) {
return Flux.just(Result.OK(value));
}
return Flux.just(value);
});
}
if (inputStream instanceof Mono mono) {
inputStream = mono.flatMap(value -> {
if (!(value instanceof Result)) {
return Mono.just(Result.OK(value));
}
return Mono.just(value);
});
}
return super.write(inputStream, actualType, elementType, mediaType, request, response, hints);
}
};
log.error("writer is {}", writers.hashCode());
configurer.customCodecs().register(writer);
}
// 处理跨域,这种方式是在获取handler的时候处理的
@Override
public void addCorsMappings(CorsRegistry registry) {
// registry.addMapping("/**")
// .allowedOrigins("*")
// .allowedMethods("*")
// .allowedHeaders("*")
// .exposedHeaders("*")
// .maxAge(3600);
}
};
}
}