这里写自定义目录标题

gateway整合websocket踩坑jar包冲突连上websocket后立马断开问题

gateway整合websocket踩坑

在gateway整合websocket时,总共遇到的问题有两个,一个是jar冲突,另外一个是网关设置跨域后websocket连接上马上断开

jar包冲突

jar包冲突主要是:org.apache.catalina.connector.ResponseFacade cannot be cast to reactor.netty.http.server.HttpServerResponse,提示get请求报错500

15:30:38.092 [http-nio-9999-exec-1] ERROR c.m.g.e.GlobalErrorWebExceptionHandler - [handle,38] - org.apache.catalina.connector.ResponseFacade cannot be cast to reactor.netty.http.server.HttpServerResponse

java.lang.ClassCastException: org.apache.catalina.connector.ResponseFacade cannot be cast to reactor.netty.http.server.HttpServerResponse

at org.springframework.web.reactive.socket.server.upgrade.ReactorNettyRequestUpgradeStrategy.getNativeResponse(ReactorNettyRequestUpgradeStrategy.java:182)

Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:

Error has been observed at the following site(s):

|_ checkpoint ⇢ org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain]

|_ checkpoint ⇢ org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain]

|_ checkpoint ⇢ HTTP GET "/sys/websocket/1" [ExceptionHandlingWebHandler]

Stack trace:

at org.springframework.web.reactive.socket.server.upgrade.ReactorNettyRequestUpgradeStrategy.getNativeResponse(ReactorNettyRequestUpgradeStrategy.java:182)

at org.springframework.web.reactive.socket.server.upgrade.ReactorNettyRequestUpgradeStrategy.upgrade(ReactorNettyRequestUpgradeStrategy.java:162)

at org.springframework.web.reactive.socket.server.support.HandshakeWebSocketService.lambda$handleRequest$1(HandshakeWebSocketService.java:235)

at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:151)

at reactor.core.publisher.MonoFlatMap.subscribeOrReturn(MonoFlatMap.java:53)

at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:57)

at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)

at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)

at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)

at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)

at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)

at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)

at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)

at reactor.core.publisher.Mono.subscribe(Mono.java:4252)

at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:172)

at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56)

at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)

at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)

at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)

at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)

at com.alibaba.csp.sentinel.adapter.reactor.MonoSentinelOperator.subscribe(MonoSentinelOperator.java:40)

at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)

at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)

at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)

我出现这种情况主要是调用feign接口,引用的包里面有如下冲突

javax.servlet

javax.servlet-api

org.springframework.boot

spring-boot-starter-web

javax.servlet

jstl

org.apache.tomcat.embed

tomcat-embed-jasper

解决办法:我是使用的idea,可以利用idea自带的jar包依赖来查看当前项目引用情况,具体ctrl+shift+alt+u来查看依赖情况,找到上面的jar包,去除依赖

连上websocket后立马断开问题

报错java.lang.UnsupportedOperationException,就是在请求头那块报错不支持

2022-08-26 16:12:11.334 ERROR 20032 --- [ctor-http-nio-2] o.s.w.s.adapter.HttpWebHandlerAdapter : [7e7b8a68-1] Error [java.lang.UnsupportedOperationException] for HTTP GET "/plat/approveabc/websocket/1123213", but ServerHttpResponse already committed (200 OK)

2022-08-26 16:12:11.338 ERROR 20032 --- [ctor-http-nio-2] r.n.http.server.HttpServerOperations : [id: 0x7e7b8a68, L:/127.0.0.1:8081 - R:/127.0.0.1:56941] Error finishing response. Closing connection

java.lang.UnsupportedOperationException: null

at org.springframework.http.ReadOnlyHttpHeaders.set(ReadOnlyHttpHeaders.java:106) ~[spring-web-5.2.12.RELEASE.jar:5.2.12.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 ⇢ HTTP GET "/plat/approveabc/websocket/1123213" [ExceptionHandlingWebHandler]

查看代码,发现是gateway处理跨域时使用的

UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();

final CorsConfiguration config = new CorsConfiguration();

// 允许cookies跨域

config.setAllowCredentials(true);

// #允许向该服务器提交请求的URI,*表示全部允许,在SpringMVC中,如果设成*,会自动转成当前请求头中的Origin

config.addAllowedOrigin("*");

// #允许访问的头信息,*表示全部

config.addAllowedHeader("*");

后来换成

return (exchange, chain) -> {

ServerHttpRequest request = exchange.getRequest();

if (!CorsUtils.isCorsRequest(request)) {

return chain.filter(exchange);

}

ServerHttpResponse response = exchange.getResponse();

HttpHeaders headers = response.getHeaders();

headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*");

headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "*");

headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, "*");

headers.add(HttpHeaders.ACCESS_CONTROL_MAX_AGE, "3628800");

return chain.filter(exchange);

};

就可以解决问题,后面那种解决跨域是reactive,在网关最好使用这种响应式编程,不然问题可能会很多

查看原文