This changes switches from using Jetty's WebSocketListener interface
to use Jetty's @WebSocket annotations instead. The change should be
transparent but the annnotations provide a little more controler
including handling pong frames.
This change also introduces a WebSocketMessage interface.
Issue: SPR-10877
- add WebSocketHttpHeaders
- client-side support for WebSocket extensions
- DefaultHandshakeHandler updates
- replace use of ServletAttributes in JettyRequestUpgradeStratey
- upgrade spring-web to jetty 9.0.5
This commits adds simple, overridable WebSocket Extension
filtering during the handshake phase and adds that
information in the WebSocket session.
The actual WebSocket Extension negotiation happens
within the server implementation (Glassfish, Jetty, Tomcat...),
so one can only remove requested extensions from
the list provided by the WebSocket client.
See RFC6455 Section 9.
Issue: SPR-10843
After this change, annotated message handling methods configured to use
a destination prefix (e.g. "/app") no longer have to include the prefix
in their mapping. For example if a client sends a message to "/app/foo"
the annotated methods should be mapped with @MessageMapping("/foo").
Ensure configuration provided for WebSocketHandler's (eg interceptors,
or HandshakeHandler) are passed on to the SockJsService if congiured.
Better separate Servlet-specific parts of the configuration to make it
more obvious where non-Servlet alternatives could fit in.
Add more tests.
Improve WebSocket integration tests.
After this change the DefaultHandshakeHandler delegates to a
server-specific RequestUpgradeStrategy to update the HTTP response for
the handshake request and to begin the WebSocket interaction.
The DefaultHandshakeHandler however still retains the initial
validation of the WebSocket handshake including negotation of origin,
sub-protocol, etc. This allows sub-classes to override various
aspects of the negotiation independant of the WebSocket engine.
A HandshakeInterceptor can be used to intercept WebSocket handshakes
(or SockJS requests where a new session is created) in order to
inspect the request and response before and after the handshake
including the ability to pass attributes to the WebSocketHandler,
which the hander can access through
WebSocketSession.getHandshakeAttributes()
An HttpSessionHandshakeInterceptor is available that can copy
attributes from the HTTP session to make them available to the
WebSocket session.
Issue: SPR-10624
The method returning query parameters now returns only query string
parameters as opposed to any Servlet request parameter.
This commit also adds a ReadOnlyMultiValueMap.
ServerHttpAsyncResponseControl wraps a ServetHttpRequest and -Response
pair and allows putting the processing of the request in async mode
so that the response remains open until explicitly closed, either from
the current or from another thread.
ServletServerHttpAsyncResponseControl provides a Serlvet-based
implementation.
A getCookies method is now available on ServerHttpRequest with one
ServletServerCookie implementation that wraps a Servlet cookie.
The SockJS service makes use of this to check for an existing session
cookie in the request.
Add SubProtocolHandler to encapsulate the logic for using a
sub-protocol.
A SubProtocolWebSocketHandler is also provided to
delegate to the appropriate SubProtocolHandler based on the
negotiated sub-protocol value at handshake.
StompSubProtocolHandler provides handling for STOMP messages.
Issue: SPR-10786
A SockJS message frame is an array of JSON-encoded messages and before
this change the use of the Jackson 2 library was hard-coded.
A Jackson 2 and Jackson 1.x implementations are provided and
automatically used if those libraries are present on the classpath.
Issue: SPR-10800
The SubscriptionRegistry and implementations are now in a package
together with SimpleBrokerWebMessageHandler and primarily support
with matching subscriptions to messages. Subscriptions can contain
patterns as supported by AntPathMatcher.
StopmWebSocketHandler no longer keeps track of subscriptions and simply
ignores messages without a subscription id, since it has no way of
knowing broker-specific destination semantics for patterns.
A new type MessageHeaderAccesssor provides read/write access to
MessageHeaders along with typed getter/setter methods along the lines
of the existing MessageBuilder methods (internally MessageBuilder
merely delegates to MessageHeaderAccessor). This class is extensible
with sub-classes expected to provide typed getter/setter methods for
specific categories of message headers.
NativeMessageHeaderAccessor is one specific sub-class that further
provides read/write access to headers from some external message
source (e.g. STOMP headers). Native headers are stored in a separate
MultiValueMap and kept under a specific key.
Rename to PubSubHeaderAccessor and StompHeaderAccessor
Move the renamed classes to support packages
Remove fromPayloadAndHeaders from MessageBuilder, just use
withPayload(..).copyHeaders(..) instead.