websocket走Spring Cloud Gateway报错:java.lang.UnsupportedOperationException: null

websocket走网关后,开始报这个错!

2023-03-30 20:11:25.182 ERROR 21676 --- [ctor-http-nio-4] o.s.w.s.adapter.HttpWebHandlerAdapter    : [737ff8d7-2] Error [java.lang.UnsupportedOperationException] for HTTP GET "/platform-merchant/hk_ws?hk_user_token=eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOiIxNjAyNDk3ODA2NTAzOTAzMjMyIiwibWVyY2hhbnRJZCI6IjE2MDI0OTkxMDU2MDE0ODY4NDgiLCJrZXkiOiI3MTc4ODY0Mjc3MjQ0ZDBhYWNlZDIwMjlhYzg2NGYwYyJ9.uMKehcdCjILsyBGiE7DulAA02Uur9ntHiibwuDRcxBo", but ServerHttpResponse already committed (200 OK)
2023-03-30 20:11:25.188 ERROR 21676 --- [ctor-http-nio-4] r.n.http.server.HttpServerOperations     : [id: 0x737ff8d7, L:/192.168.3.52:9090 - R:/192.168.3.52:55782] Error finishing response. Closing connection

java.lang.UnsupportedOperationException: null
	at org.springframework.http.ReadOnlyHttpHeaders.put(ReadOnlyHttpHeaders.java:126) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
	|_ checkpoint ⇢ org.springframework.web.cors.reactive.CorsWebFilter [DefaultWebFilterChain]
	|_ checkpoint ⇢ org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain]
	|_ checkpoint ⇢ org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain]
	|_ checkpoint ⇢ HTTP GET "/platform-merchant/hk_ws?hk_user_token=eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOiIxNjAyNDk3ODA2NTAzOTAzMjMyIiwibWVyY2hhbnRJZCI6IjE2MDI0OTkxMDU2MDE0ODY4NDgiLCJrZXkiOiI3MTc4ODY0Mjc3MjQ0ZDBhYWNlZDIwMjlhYzg2NGYwYyJ9.uMKehcdCjILsyBGiE7DulAA02Uur9ntHiibwuDRcxBo" [ExceptionHandlingWebHandler]
Stack trace:
		at org.springframework.http.ReadOnlyHttpHeaders.put(ReadOnlyHttpHeaders.java:126) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
		at org.springframework.cloud.gateway.filter.factory.DedupeResponseHeaderGatewayFilterFactory.dedupe(DedupeResponseHeaderGatewayFilterFactory.java:149) ~[spring-cloud-gateway-core-2.2.2.RELEASE.jar:2.2.2.RELEASE]
		at org.springframework.cloud.gateway.filter.factory.DedupeResponseHeaderGatewayFilterFactory.dedupe(DedupeResponseHeaderGatewayFilterFactory.java:132) ~[spring-cloud-gateway-core-2.2.2.RELEASE.jar:2.2.2.RELEASE]
		at org.springframework.cloud.gateway.filter.factory.DedupeResponseHeaderGatewayFilterFactory$1.lambda$filter$0(DedupeResponseHeaderGatewayFilterFactory.java:93) ~[spring-cloud-gateway-core-2.2.2.RELEASE.jar:2.2.2.RELEASE]
		at reactor.core.publisher.MonoRunnable.call(MonoRunnable.java:73) ~[reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
		at reactor.core.publisher.MonoRunnable.call(MonoRunnable.java:32) ~[reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
		at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:135) [reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
		at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56) [reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
		at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) [reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
		at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) [reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
		at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) [reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
		at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) [reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
		at reactor.core.publisher.Mono.subscribe(Mono.java:4218) [reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
		at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:172) [reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
		at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56) [reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
		at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) [reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]

网上找答案,意思是要把gateway跨域配置去掉,检查了代码,果然有跨域配置;注释掉后重启,上面报的错解决了!

@Configuration
public class GwCorsFilter {

    @Bean
    public CorsWebFilter corsFilter() {
        CorsConfiguration corsConfig = new CorsConfiguration();
        List<String> allowedHeaders = Arrays.asList("x-auth-token", "content-type", "X-Requested-With", "XMLHttpRequest", "Authorization");
        List<String> exposedHeaders = Arrays.asList("x-auth-token", "content-type", "X-Requested-With", "XMLHttpRequest", "Authorization");
        List<String> allowedMethods = Arrays.asList("POST", "GET", "DELETE", "PUT", "OPTIONS");
        List<String> allowedOrigins = Collections.singletonList("*");
        corsConfig.setAllowedHeaders(allowedHeaders);
        corsConfig.setAllowedMethods(allowedMethods);
        corsConfig.setAllowedOrigins(allowedOrigins);
        corsConfig.setExposedHeaders(exposedHeaders);
        corsConfig.setMaxAge(36000L);
        corsConfig.setAllowCredentials(true);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
        source.registerCorsConfiguration("/**", corsConfig);

        return new CorsWebFilter(source);
    }
}

原本以为就此大功告成,轻松解决;最后被告知,要留下跨域的配置,前端就是需要跨域。。。
诶呀!领导一开始没规划好路径,只能硬着头皮解决。尝试留着跨域配置,解决websocket连接报错的问题!
最后调试源码,还真发现问题了


无法推断Vary,header不支持Vary操作,检查了一下果然有这个配置

想起来之前看过Spring Cloud Gateway官方文档,有这个介绍DedupeResponseHeader怎么配置。
支持RETAIN_FIRSTRETAIN_LASTRETAIN_UNIQUE,没有Vary相关配置

最后找了配置的同事,是2年前配置上去,也不知从那里抄来的!!!当时不是很清楚每一项配置,之前也一直没出问题,直到接入websocket+跨域配置一起才出现问题。所以加每一个配置项都要很清楚它的作用,否则不知什么时候出问题!

posted @ 2023-03-30 20:53  搬运工001  阅读(905)  评论(0编辑  收藏  举报