gpt4 book ai didi

java - 向现有 Spring 应用程序添加 Web 套接字支持

转载 作者:行者123 更新时间:2023-12-01 09:38:54 32 4
gpt4 key购买 nike

我正在使用 Spring 4 应用程序(不幸的是,不是 Spring Boot),但我无法让 Web 套接字正常工作。我在 /ws 路径注册了一个简单的 TextWebSocketHandler 实现,并且我确实获得了确认日志:

Mapped URL path [/ws] onto handler of type [class org.springframework.web.socket.server.support.WebSocketHttpRequestHandler]

...但我无法连接网络浏览器中的地址。我尝试过这种基于注释的配置:

@Slf4j
@Configuration
@EnableWebSocket
public class WebSocketConfiguration implements WebSocketConfigurer {
public static final String WEB_SOCKET_PATH = "/ws";
@Autowired
private WebSocketService handler;

@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
log.info("Registering web socket handler {} at '{}'.", handler, WEB_SOCKET_PATH);
registry.addHandler(handler, WEB_SOCKET_PATH);
}
}

我可以确认 WebSocketService handler 不为 null,并且实际上实现了 WebSocketHandler 接口(interface)。虽然配置器明显被触发,但使用 "ws://localhost:8081/ws" 连接会导致错误:

WebSocket connection to 'ws://localhost:8081/ws' failed: Error during WebSocket handshake: Unexpected response code: 404

error { target: WebSocket, isTrusted: true, currentTarget: WebSocket, eventPhase: 2, bubbles: false, cancelable: false, defaultPrevented: false, timeStamp: 1469616712980247, originalTarget: WebSocket, explicitOriginalTarget: WebSocket, NONE: 0 }

我用来测试 Web 套接字机制的客户端代码非常简单:

var ws = new WebSocket("ws://localhost:8081/ws");
ws.onerror = function(e) { console.log(e); }
ws.onopen = function() { console.log("Opened"); }

我什至尝试通过 XML 配置注册处理程序,但是虽然我得到了几乎相同的日志,但它仍然不起作用。请注意,我正在使用 Jetty 9 的默认配置运行应用程序(通过 Gretty Gradle 插件)。

在查看 Spring 调试日志时,我只能猜测 Spring 未能将 HTTP 请求提升到 Web 套接字连接:

13:14:02.322 [qtp1305935114-14] DEBUG - /ws at position 1 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
13:14:02.322 [qtp1305935114-14] DEBUG - Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@4190548c: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@4190548c: Principal: org.springframework.security.core.userdetails.User@58c7c40: Username: [removed]; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@12afc: RemoteIpAddress: 127.0.0.1; SessionId: 1om9yxo93cwce1qb1tu0rcs15n; Granted Authorities: ROLE_USER'
13:14:02.322 [qtp1305935114-14] DEBUG - /ws at position 2 of 13 in additional filter chain; firing Filter: 'ConcurrentSessionFilter'
13:14:02.322 [qtp1305935114-14] DEBUG - /ws at position 3 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
13:14:02.322 [qtp1305935114-14] DEBUG - /ws at position 4 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
13:14:02.322 [qtp1305935114-14] DEBUG - /ws at position 5 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
13:14:02.322 [qtp1305935114-14] DEBUG - Checking match of request : '/ws'; against '/logout'
13:14:02.322 [qtp1305935114-14] DEBUG - /ws at position 6 of 13 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
13:14:02.322 [qtp1305935114-14] DEBUG - Request 'GET /ws' doesn't match 'POST /securityCheck
13:14:02.322 [qtp1305935114-14] DEBUG - /ws at position 7 of 13 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
13:14:02.322 [qtp1305935114-14] DEBUG - /ws at position 8 of 13 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
13:14:02.322 [qtp1305935114-14] DEBUG - /ws at position 9 of 13 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
13:14:02.322 [qtp1305935114-14] DEBUG - /ws at position 10 of 13 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
13:14:02.322 [qtp1305935114-14] DEBUG - SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken@4190548c: Principal: org.springframework.security.core.userdetails.User@58c7c40: Username: [removed]; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@12afc: RemoteIpAddress: 127.0.0.1; SessionId: 1om9yxo93cwce1qb1tu0rcs15n; Granted Authorities: ROLE_USER'
13:14:02.322 [qtp1305935114-14] DEBUG - /ws at position 11 of 13 in additional filter chain; firing Filter: 'SessionManagementFilter'
13:14:02.322 [qtp1305935114-14] DEBUG - /ws at position 12 of 13 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
13:14:02.322 [qtp1305935114-14] DEBUG - /ws at position 13 of 13 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
13:14:02.322 [qtp1305935114-14] DEBUG - Checking match of request : '/ws'; against '/login*'
13:14:02.322 [qtp1305935114-14] DEBUG - Secure object: FilterInvocation: URL: /ws; Attributes: [ROLE_USER]
13:14:02.322 [qtp1305935114-14] DEBUG - Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@4190548c: Principal: org.springframework.security.core.userdetails.User@58c7c40: Username: [removed]; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@12afc: RemoteIpAddress: 127.0.0.1; SessionId: 1om9yxo93cwce1qb1tu0rcs15n; Granted Authorities: ROLE_USER
13:14:02.322 [qtp1305935114-14] DEBUG - Voter: org.springframework.security.access.vote.RoleVoter@b5de58f, returned: 1
13:14:02.322 [qtp1305935114-14] DEBUG - Authorization successful
13:14:02.322 [qtp1305935114-14] DEBUG - RunAsManager did not change Authentication object
13:14:02.322 [qtp1305935114-14] DEBUG - /ws reached end of additional filter chain; proceeding with original chain
13:14:02.323 [qtp1305935114-14] DEBUG - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@425f619f
13:14:02.324 [qtp1305935114-14] DEBUG - Chain processed normally
13:14:02.324 [qtp1305935114-14] DEBUG - SecurityContextHolder now cleared, as request processing completed

浏览了官方文档和示例,似乎 Web 套接字配置非常标准。是否有我可能错过的任何内容或我可能需要更改的任何配置才能在 Spring 中启用 Web 套接字?

最佳答案

事实证明,Web 套接字按预期工作,但 Spring servlet 映射未在 web.xml 中的 /* 处设置:

<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/spring/*</url-pattern>
</servlet-mapping>

这真的很愚蠢 - 我所要做的就是将地址更改为 ws://localhost:8081/spring/ws。让我措手不及的是,一些 Spring 过滤器被映射到 /*,而且我的印象是 Spring servlet 共享这个映射 - 毕竟,调用 ws://localhost :8081/ws 触发了一些 Spring 的东西(如日志中所示)。

关于java - 向现有 Spring 应用程序添加 Web 套接字支持,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38611292/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com