Remove HandlerProvider

This commit is contained in:
Rossen Stoyanchev 2013-04-26 21:59:04 -04:00
parent 861ab900ae
commit 0c1b329949
40 changed files with 280 additions and 367 deletions

View File

@ -23,7 +23,6 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
import org.springframework.websocket.CloseStatus;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.TextMessage;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.WebSocketSession;
@ -53,15 +52,14 @@ public abstract class AbstractSockJsSession implements WebSocketSession {
/**
*
* @param sessionId
* @param handlerProvider the recipient of SockJS messages
* @param webSocketHandler the recipient of SockJS messages
*/
public AbstractSockJsSession(String sessionId, HandlerProvider<WebSocketHandler<?>> handlerProvider) {
public AbstractSockJsSession(String sessionId, WebSocketHandler<?> webSocketHandler) {
Assert.notNull(sessionId, "sessionId is required");
Assert.notNull(handlerProvider, "handlerProvider is required");
Assert.notNull(webSocketHandler, "webSocketHandler is required");
this.sessionId = sessionId;
this.handler = new WebSocketHandlerInvoker(handlerProvider).setLogger(logger);
this.handler = new WebSocketHandlerInvoker(webSocketHandler).setLogger(logger);
}
public String getId() {

View File

@ -16,7 +16,6 @@
package org.springframework.sockjs;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.WebSocketSession;
@ -32,9 +31,9 @@ public interface SockJsSessionFactory<S extends WebSocketSession>{
/**
* Create a new SockJS session.
* @param sessionId the ID of the session
* @param handler the underlying {@link WebSocketHandler}
* @param webSocketHandler the underlying {@link WebSocketHandler}
* @return a new non-null session
*/
S createSession(String sessionId, HandlerProvider<WebSocketHandler<?>> handler);
S createSession(String sessionId, WebSocketHandler<?> webSocketHandler);
}

View File

@ -25,7 +25,6 @@ import java.util.concurrent.ScheduledFuture;
import org.springframework.sockjs.AbstractSockJsSession;
import org.springframework.util.Assert;
import org.springframework.websocket.CloseStatus;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.TextMessage;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.WebSocketMessage;
@ -44,9 +43,7 @@ public abstract class AbstractServerSockJsSession extends AbstractSockJsSession
private ScheduledFuture<?> heartbeatTask;
public AbstractServerSockJsSession(String sessionId, SockJsConfiguration config,
HandlerProvider<WebSocketHandler<?>> handler) {
public AbstractServerSockJsSession(String sessionId, SockJsConfiguration config, WebSocketHandler<?> handler) {
super(sessionId, handler);
this.sockJsConfig = config;
}

View File

@ -36,7 +36,6 @@ import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
/**
@ -200,8 +199,7 @@ public abstract class AbstractSockJsService implements SockJsService, SockJsConf
* @throws Exception
*/
public final void handleRequest(ServerHttpRequest request, ServerHttpResponse response,
String sockJsPath, HandlerProvider<WebSocketHandler<?>> handler)
throws IOException, TransportErrorException {
String sockJsPath, WebSocketHandler<?> webSocketHandler) throws IOException, TransportErrorException {
logger.debug(request.getMethod() + " [" + sockJsPath + "]");
@ -227,7 +225,7 @@ public abstract class AbstractSockJsService implements SockJsService, SockJsConf
return;
}
else if (sockJsPath.equals("/websocket")) {
handleRawWebSocketRequest(request, response, handler);
handleRawWebSocketRequest(request, response, webSocketHandler);
return;
}
@ -247,18 +245,18 @@ public abstract class AbstractSockJsService implements SockJsService, SockJsConf
return;
}
handleTransportRequest(request, response, sessionId, TransportType.fromValue(transport), handler);
handleTransportRequest(request, response, sessionId, TransportType.fromValue(transport), webSocketHandler);
}
finally {
response.flush();
}
}
protected abstract void handleRawWebSocketRequest(ServerHttpRequest request, ServerHttpResponse response,
HandlerProvider<WebSocketHandler<?>> handler) throws IOException;
protected abstract void handleRawWebSocketRequest(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler<?> webSocketHandler) throws IOException;
protected abstract void handleTransportRequest(ServerHttpRequest request, ServerHttpResponse response,
String sessionId, TransportType transportType, HandlerProvider<WebSocketHandler<?>> handler)
String sessionId, TransportType transportType, WebSocketHandler<?> webSocketHandler)
throws IOException, TransportErrorException;

View File

@ -17,7 +17,6 @@
package org.springframework.sockjs.server;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
/**
* @author Rossen Stoyanchev

View File

@ -20,7 +20,6 @@ import java.io.IOException;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
/**
@ -29,7 +28,8 @@ import org.springframework.websocket.WebSocketHandler;
*/
public interface SockJsService {
void handleRequest(ServerHttpRequest request, ServerHttpResponse response, String sockJsPath,
HandlerProvider<WebSocketHandler<?>> handler) throws IOException, TransportErrorException;
void handleRequest(ServerHttpRequest request, ServerHttpResponse response,
String sockJsPath, WebSocketHandler<?> webSocketHandler) throws IOException, TransportErrorException;
}

View File

@ -19,7 +19,6 @@ package org.springframework.sockjs.server;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.sockjs.AbstractSockJsSession;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
/**
@ -31,6 +30,6 @@ public interface TransportHandler {
TransportType getTransportType();
void handleRequest(ServerHttpRequest request, ServerHttpResponse response,
HandlerProvider<WebSocketHandler<?>> handler, AbstractSockJsSession session) throws TransportErrorException;
WebSocketHandler<?> handler, AbstractSockJsSession session) throws TransportErrorException;
}

View File

@ -51,7 +51,6 @@ import org.springframework.sockjs.server.transport.XhrPollingTransportHandler;
import org.springframework.sockjs.server.transport.XhrStreamingTransportHandler;
import org.springframework.sockjs.server.transport.XhrTransportHandler;
import org.springframework.util.CollectionUtils;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.server.DefaultHandshakeHandler;
import org.springframework.websocket.server.HandshakeHandler;
@ -143,13 +142,13 @@ public class DefaultSockJsService extends AbstractSockJsService {
@Override
protected void handleRawWebSocketRequest(ServerHttpRequest request, ServerHttpResponse response,
HandlerProvider<WebSocketHandler<?>> handler) throws IOException {
WebSocketHandler<?> webSocketHandler) throws IOException {
if (isWebSocketEnabled()) {
TransportHandler transportHandler = this.transportHandlers.get(TransportType.WEBSOCKET);
if (transportHandler != null) {
if (transportHandler instanceof HandshakeHandler) {
((HandshakeHandler) transportHandler).doHandshake(request, response, handler);
((HandshakeHandler) transportHandler).doHandshake(request, response, webSocketHandler);
return;
}
}
@ -160,7 +159,7 @@ public class DefaultSockJsService extends AbstractSockJsService {
@Override
protected void handleTransportRequest(ServerHttpRequest request, ServerHttpResponse response,
String sessionId, TransportType transportType, HandlerProvider<WebSocketHandler<?>> handler)
String sessionId, TransportType transportType, WebSocketHandler<?> webSocketHandler)
throws IOException, TransportErrorException {
TransportHandler transportHandler = this.transportHandlers.get(transportType);
@ -188,7 +187,7 @@ public class DefaultSockJsService extends AbstractSockJsService {
return;
}
AbstractSockJsSession session = getSockJsSession(sessionId, handler, transportHandler);
AbstractSockJsSession session = getSockJsSession(sessionId, webSocketHandler, transportHandler);
if (session != null) {
if (transportType.setsNoCacheHeader()) {
@ -207,11 +206,11 @@ public class DefaultSockJsService extends AbstractSockJsService {
}
}
transportHandler.handleRequest(request, response, handler, session);
transportHandler.handleRequest(request, response, webSocketHandler, session);
}
public AbstractSockJsSession getSockJsSession(String sessionId, HandlerProvider<WebSocketHandler<?>> handler,
TransportHandler transportHandler) {
public AbstractSockJsSession getSockJsSession(String sessionId,
WebSocketHandler<?> webSocketHandler, TransportHandler transportHandler) {
AbstractSockJsSession session = this.sessions.get(sessionId);
if (session != null) {
@ -230,7 +229,7 @@ public class DefaultSockJsService extends AbstractSockJsService {
scheduleSessionTask();
}
logger.debug("Creating new session with session id \"" + sessionId + "\"");
session = (AbstractSockJsSession) sessionFactory.createSession(sessionId, handler);
session = (AbstractSockJsSession) sessionFactory.createSession(sessionId, webSocketHandler);
this.sessions.put(sessionId, session);
return session;
}

View File

@ -31,9 +31,7 @@ import org.springframework.util.Assert;
import org.springframework.web.HttpRequestHandler;
import org.springframework.web.util.NestedServletException;
import org.springframework.web.util.UrlPathHelper;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.support.SimpleHandlerProvider;
/**
* @author Rossen Stoyanchev
@ -45,7 +43,7 @@ public class SockJsHttpRequestHandler implements HttpRequestHandler {
private final SockJsService sockJsService;
private final HandlerProvider<WebSocketHandler<?>> handlerProvider;
private final WebSocketHandler<?> webSocketHandler;
private final UrlPathHelper urlPathHelper = new UrlPathHelper();
@ -57,37 +55,17 @@ public class SockJsHttpRequestHandler implements HttpRequestHandler {
* that begins with the specified prefix will be handled by this service. In a
* Servlet container this is the path within the current servlet mapping.
*/
public SockJsHttpRequestHandler(String prefix, SockJsService sockJsService, WebSocketHandler handler) {
public SockJsHttpRequestHandler(String prefix, SockJsService sockJsService, WebSocketHandler webSocketHandler) {
Assert.hasText(prefix, "prefix is required");
Assert.notNull(sockJsService, "sockJsService is required");
Assert.notNull(handler, "webSocketHandler is required");
Assert.notNull(webSocketHandler, "webSocketHandler is required");
this.prefix = prefix;
this.sockJsService = sockJsService;
this.handlerProvider = new SimpleHandlerProvider<WebSocketHandler<?>>(handler);
this.webSocketHandler = webSocketHandler;
}
/**
* Class constructor with {@link SockJsHandler} type (per request) ...
*
* @param prefix the path prefix for the SockJS service. All requests with a path
* that begins with the specified prefix will be handled by this service. In a
* Servlet container this is the path within the current servlet mapping.
*/
public SockJsHttpRequestHandler(String prefix, SockJsService sockJsService,
HandlerProvider<WebSocketHandler<?>> handlerProvider) {
Assert.hasText(prefix, "prefix is required");
Assert.notNull(sockJsService, "sockJsService is required");
Assert.notNull(handlerProvider, "handlerProvider is required");
this.prefix = prefix;
this.sockJsService = sockJsService;
this.handlerProvider = handlerProvider;
}
public String getPrefix() {
return this.prefix;
}
@ -111,7 +89,7 @@ public class SockJsHttpRequestHandler implements HttpRequestHandler {
ServerHttpResponse httpResponse = new ServletServerHttpResponse(response);
try {
this.sockJsService.handleRequest(httpRequest, httpResponse, sockJsPath, this.handlerProvider);
this.sockJsService.handleRequest(httpRequest, httpResponse, sockJsPath, this.webSocketHandler);
}
catch (Exception ex) {
// TODO

View File

@ -29,7 +29,6 @@ import org.springframework.http.server.ServerHttpResponse;
import org.springframework.sockjs.AbstractSockJsSession;
import org.springframework.sockjs.server.TransportErrorException;
import org.springframework.sockjs.server.TransportHandler;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
import com.fasterxml.jackson.databind.JsonMappingException;
@ -55,7 +54,7 @@ public abstract class AbstractHttpReceivingTransportHandler implements Transport
@Override
public final void handleRequest(ServerHttpRequest request, ServerHttpResponse response,
HandlerProvider<WebSocketHandler<?>> webSocketHandler, AbstractSockJsSession session)
WebSocketHandler<?> webSocketHandler, AbstractSockJsSession session)
throws TransportErrorException {
if (session == null) {

View File

@ -28,9 +28,8 @@ import org.springframework.sockjs.SockJsSessionFactory;
import org.springframework.sockjs.server.ConfigurableTransportHandler;
import org.springframework.sockjs.server.SockJsConfiguration;
import org.springframework.sockjs.server.SockJsFrame;
import org.springframework.sockjs.server.TransportErrorException;
import org.springframework.sockjs.server.SockJsFrame.FrameFormat;
import org.springframework.websocket.HandlerProvider;
import org.springframework.sockjs.server.TransportErrorException;
import org.springframework.websocket.WebSocketHandler;
/**
@ -58,7 +57,7 @@ public abstract class AbstractHttpSendingTransportHandler
@Override
public final void handleRequest(ServerHttpRequest request, ServerHttpResponse response,
HandlerProvider<WebSocketHandler<?>> webSocketHandler, AbstractSockJsSession session)
WebSocketHandler<?> webSocketHandler, AbstractSockJsSession session)
throws TransportErrorException {
// Set content type before writing

View File

@ -26,11 +26,10 @@ import org.springframework.http.server.ServerHttpResponse;
import org.springframework.sockjs.server.AbstractServerSockJsSession;
import org.springframework.sockjs.server.SockJsConfiguration;
import org.springframework.sockjs.server.SockJsFrame;
import org.springframework.sockjs.server.TransportErrorException;
import org.springframework.sockjs.server.SockJsFrame.FrameFormat;
import org.springframework.sockjs.server.TransportErrorException;
import org.springframework.util.Assert;
import org.springframework.websocket.CloseStatus;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
/**
@ -50,10 +49,8 @@ public abstract class AbstractHttpServerSockJsSession extends AbstractServerSock
private ServerHttpResponse response;
public AbstractHttpServerSockJsSession(String sessionId, SockJsConfiguration sockJsConfig,
HandlerProvider<WebSocketHandler<?>> handler) {
super(sessionId, sockJsConfig, handler);
public AbstractHttpServerSockJsSession(String sessionId, SockJsConfiguration config, WebSocketHandler<?> handler) {
super(sessionId, config, handler);
}
public synchronized void setInitialRequest(ServerHttpRequest request, ServerHttpResponse response,

View File

@ -25,7 +25,6 @@ import org.springframework.sockjs.server.SockJsFrame.DefaultFrameFormat;
import org.springframework.sockjs.server.SockJsFrame.FrameFormat;
import org.springframework.sockjs.server.TransportType;
import org.springframework.util.Assert;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
/**
@ -47,7 +46,7 @@ public class EventSourceTransportHandler extends AbstractHttpSendingTransportHan
}
@Override
public StreamingServerSockJsSession createSession(String sessionId, HandlerProvider<WebSocketHandler<?>> handler) {
public StreamingServerSockJsSession createSession(String sessionId, WebSocketHandler<?> handler) {
Assert.notNull(getSockJsConfig(), "This transport requires SockJsConfiguration");
return new StreamingServerSockJsSession(sessionId, getSockJsConfig(), handler) {
@Override

View File

@ -30,7 +30,6 @@ import org.springframework.sockjs.server.TransportType;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.util.JavaScriptUtils;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
/**
@ -81,7 +80,7 @@ public class HtmlFileTransportHandler extends AbstractHttpSendingTransportHandle
}
@Override
public StreamingServerSockJsSession createSession(String sessionId, HandlerProvider<WebSocketHandler<?>> handler) {
public StreamingServerSockJsSession createSession(String sessionId, WebSocketHandler<?> handler) {
Assert.notNull(getSockJsConfig(), "This transport requires SockJsConfiguration");
return new StreamingServerSockJsSession(sessionId, getSockJsConfig(), handler) {

View File

@ -29,7 +29,6 @@ import org.springframework.sockjs.server.TransportType;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.util.JavaScriptUtils;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
/**
@ -51,7 +50,7 @@ public class JsonpPollingTransportHandler extends AbstractHttpSendingTransportHa
}
@Override
public PollingServerSockJsSession createSession(String sessionId, HandlerProvider<WebSocketHandler<?>> handler) {
public PollingServerSockJsSession createSession(String sessionId, WebSocketHandler<?> handler) {
Assert.notNull(getSockJsConfig(), "This transport requires SockJsConfiguration");
return new PollingServerSockJsSession(sessionId, getSockJsConfig(), handler);
}

View File

@ -19,16 +19,13 @@ import java.io.IOException;
import org.springframework.sockjs.server.SockJsConfiguration;
import org.springframework.sockjs.server.SockJsFrame;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
public class PollingServerSockJsSession extends AbstractHttpServerSockJsSession {
public PollingServerSockJsSession(String sessionId, SockJsConfiguration sockJsConfig,
HandlerProvider<WebSocketHandler<?>> handler) {
super(sessionId, sockJsConfig, handler);
public PollingServerSockJsSession(String sessionId, SockJsConfiguration config, WebSocketHandler<?> handler) {
super(sessionId, config, handler);
}
@Override

View File

@ -25,7 +25,6 @@ import org.springframework.sockjs.server.SockJsFrame;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.websocket.CloseStatus;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.TextMessage;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.WebSocketSession;
@ -45,7 +44,7 @@ public class SockJsWebSocketHandler extends TextWebSocketHandlerAdapter {
private final SockJsConfiguration sockJsConfig;
private final HandlerProvider<WebSocketHandler<?>> handlerProvider;
private final WebSocketHandler<?> webSocketHandler;
private WebSocketServerSockJsSession sockJsSession;
@ -55,11 +54,11 @@ public class SockJsWebSocketHandler extends TextWebSocketHandlerAdapter {
private final ObjectMapper objectMapper = new ObjectMapper();
public SockJsWebSocketHandler(SockJsConfiguration config, HandlerProvider<WebSocketHandler<?>> handlerProvider) {
public SockJsWebSocketHandler(SockJsConfiguration config, WebSocketHandler<?> webSocketHandler) {
Assert.notNull(config, "sockJsConfig is required");
Assert.notNull(handlerProvider, "handlerProvider is required");
Assert.notNull(webSocketHandler, "webSocketHandler is required");
this.sockJsConfig = config;
this.handlerProvider = handlerProvider;
this.webSocketHandler = webSocketHandler;
}
protected SockJsConfiguration getSockJsConfig() {
@ -103,7 +102,7 @@ public class SockJsWebSocketHandler extends TextWebSocketHandlerAdapter {
public WebSocketServerSockJsSession(String sessionId, SockJsConfiguration config) {
super(sessionId, config, SockJsWebSocketHandler.this.handlerProvider);
super(sessionId, config, SockJsWebSocketHandler.this.webSocketHandler);
}
public void initWebSocketSession(WebSocketSession wsSession) {

View File

@ -24,7 +24,6 @@ import org.springframework.sockjs.server.SockJsConfiguration;
import org.springframework.sockjs.server.SockJsFrame;
import org.springframework.sockjs.server.SockJsFrame.FrameFormat;
import org.springframework.sockjs.server.TransportErrorException;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
public class StreamingServerSockJsSession extends AbstractHttpServerSockJsSession {
@ -32,10 +31,8 @@ public class StreamingServerSockJsSession extends AbstractHttpServerSockJsSessio
private int byteCount;
public StreamingServerSockJsSession(String sessionId, SockJsConfiguration sockJsConfig,
HandlerProvider<WebSocketHandler<?>> handler) {
super(sessionId, sockJsConfig, handler);
public StreamingServerSockJsSession(String sessionId, SockJsConfiguration config, WebSocketHandler<?> handler) {
super(sessionId, config, handler);
}

View File

@ -27,10 +27,8 @@ import org.springframework.sockjs.server.TransportErrorException;
import org.springframework.sockjs.server.TransportHandler;
import org.springframework.sockjs.server.TransportType;
import org.springframework.util.Assert;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.server.HandshakeHandler;
import org.springframework.websocket.support.SimpleHandlerProvider;
/**
@ -65,11 +63,11 @@ public class WebSocketTransportHandler implements ConfigurableTransportHandler,
@Override
public void handleRequest(ServerHttpRequest request, ServerHttpResponse response,
HandlerProvider<WebSocketHandler<?>> handler, AbstractSockJsSession session) throws TransportErrorException {
WebSocketHandler<?> webSocketHandler, AbstractSockJsSession session) throws TransportErrorException {
try {
WebSocketHandler<?> sockJsWrapper = new SockJsWebSocketHandler(this.sockJsConfig, handler);
this.handshakeHandler.doHandshake(request, response, new SimpleHandlerProvider<WebSocketHandler<?>>(sockJsWrapper));
WebSocketHandler<?> sockJsWrapper = new SockJsWebSocketHandler(this.sockJsConfig, webSocketHandler);
this.handshakeHandler.doHandshake(request, response, sockJsWrapper);
}
catch (Throwable t) {
throw new TransportErrorException("Failed to start handshake request", t, session.getId());
@ -79,8 +77,8 @@ public class WebSocketTransportHandler implements ConfigurableTransportHandler,
// HandshakeHandler methods
@Override
public boolean doHandshake(ServerHttpRequest request, ServerHttpResponse response,
HandlerProvider<WebSocketHandler<?>> handler) throws IOException {
public boolean doHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler<?> handler)
throws IOException {
return this.handshakeHandler.doHandshake(request, response, handler);
}

View File

@ -23,7 +23,6 @@ import org.springframework.sockjs.server.SockJsFrame.DefaultFrameFormat;
import org.springframework.sockjs.server.SockJsFrame.FrameFormat;
import org.springframework.sockjs.server.TransportType;
import org.springframework.util.Assert;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
@ -51,7 +50,7 @@ public class XhrPollingTransportHandler extends AbstractHttpSendingTransportHand
return new DefaultFrameFormat("%s\n");
}
public PollingServerSockJsSession createSession(String sessionId, HandlerProvider<WebSocketHandler<?>> handler) {
public PollingServerSockJsSession createSession(String sessionId, WebSocketHandler<?> handler) {
Assert.notNull(getSockJsConfig(), "This transport requires SockJsConfiguration");
return new PollingServerSockJsSession(sessionId, getSockJsConfig(), handler);
}

View File

@ -24,7 +24,6 @@ import org.springframework.sockjs.server.SockJsFrame.DefaultFrameFormat;
import org.springframework.sockjs.server.SockJsFrame.FrameFormat;
import org.springframework.sockjs.server.TransportType;
import org.springframework.util.Assert;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
@ -48,7 +47,7 @@ public class XhrStreamingTransportHandler extends AbstractHttpSendingTransportHa
}
@Override
public StreamingServerSockJsSession createSession(String sessionId, HandlerProvider<WebSocketHandler<?>> handler) {
public StreamingServerSockJsSession createSession(String sessionId, WebSocketHandler<?> handler) {
Assert.notNull(getSockJsConfig(), "This transport requires SockJsConfiguration");
return new StreamingServerSockJsSession(sessionId, getSockJsConfig(), handler) {

View File

@ -1,48 +0,0 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.websocket;
/**
* A strategy for obtaining a handler instance that is scoped to external lifecycle events
* such as the opening and closing of a WebSocket connection.
*
* @author Rossen Stoyanchev
* @since 4.0
*/
public interface HandlerProvider<T> {
/**
* Whether the provided handler is a shared instance or not.
*/
boolean isSingleton();
/**
* The type of handler provided.
*/
Class<?> getHandlerType();
/**
* Obtain the handler instance, either shared or created every time.
*/
T getHandler();
/**
* Callback to destroy a previously created handler instance if it is not shared.
*/
void destroy(T handler);
}

View File

@ -23,7 +23,6 @@ import org.eclipse.jetty.websocket.api.WebSocketListener;
import org.springframework.util.Assert;
import org.springframework.websocket.BinaryMessage;
import org.springframework.websocket.CloseStatus;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.TextMessage;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.WebSocketMessage;
@ -39,43 +38,43 @@ public class JettyWebSocketListenerAdapter implements WebSocketListener {
private static Log logger = LogFactory.getLog(JettyWebSocketListenerAdapter.class);
private final WebSocketHandler<WebSocketMessage<?>> handler;
private final WebSocketHandler<WebSocketMessage<?>> webSocketHandler;
private WebSocketSession wsSession;
public JettyWebSocketListenerAdapter(HandlerProvider<WebSocketHandler<?>> provider) {
Assert.notNull(provider, "provider is required");
this.handler = new WebSocketHandlerInvoker(provider).setLogger(logger);
public JettyWebSocketListenerAdapter(WebSocketHandler<?> webSocketHandler) {
Assert.notNull(webSocketHandler, "webSocketHandler is required");
this.webSocketHandler = new WebSocketHandlerInvoker(webSocketHandler).setLogger(logger);
}
@Override
public void onWebSocketConnect(Session session) {
this.wsSession = new JettyWebSocketSessionAdapter(session);
this.handler.afterConnectionEstablished(this.wsSession);
this.webSocketHandler.afterConnectionEstablished(this.wsSession);
}
@Override
public void onWebSocketClose(int statusCode, String reason) {
CloseStatus closeStatus = new CloseStatus(statusCode, reason);
this.handler.afterConnectionClosed(this.wsSession, closeStatus);
this.webSocketHandler.afterConnectionClosed(this.wsSession, closeStatus);
}
@Override
public void onWebSocketText(String payload) {
TextMessage message = new TextMessage(payload);
this.handler.handleMessage(this.wsSession, message);
this.webSocketHandler.handleMessage(this.wsSession, message);
}
@Override
public void onWebSocketBinary(byte[] payload, int offset, int len) {
BinaryMessage message = new BinaryMessage(payload, offset, len);
this.handler.handleMessage(this.wsSession, message);
this.webSocketHandler.handleMessage(this.wsSession, message);
}
@Override
public void onWebSocketError(Throwable cause) {
this.handler.handleTransportError(this.wsSession, cause);
this.webSocketHandler.handleTransportError(this.wsSession, cause);
}
}

View File

@ -28,11 +28,9 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
import org.springframework.websocket.BinaryMessage;
import org.springframework.websocket.CloseStatus;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.PartialMessageHandler;
import org.springframework.websocket.TextMessage;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.WebSocketMessage;
import org.springframework.websocket.WebSocketSession;
@ -46,7 +44,7 @@ public class StandardEndpointAdapter extends Endpoint {
private static Log logger = LogFactory.getLog(StandardEndpointAdapter.class);
private final WebSocketHandler<WebSocketMessage<?>> handler;
private final WebSocketHandlerInvoker handler;
private final Class<?> handlerClass;
@ -54,10 +52,10 @@ public class StandardEndpointAdapter extends Endpoint {
public StandardEndpointAdapter(HandlerProvider<WebSocketHandler<?>> provider) {
Assert.notNull(provider, "provider is required");
this.handler = new WebSocketHandlerInvoker(provider).setLogger(logger);
this.handlerClass= provider.getHandlerType();
public StandardEndpointAdapter(WebSocketHandler<?> webSocketHandler) {
Assert.notNull(webSocketHandler, "webSocketHandler is required");
this.handler = new WebSocketHandlerInvoker(webSocketHandler).setLogger(logger);
this.handlerClass= webSocketHandler.getClass();
}
@ -71,6 +69,8 @@ public class StandardEndpointAdapter extends Endpoint {
}
});
// TODO: per-connection proxy
if (!PartialMessageHandler.class.isAssignableFrom(this.handlerClass)) {
session.addMessageHandler(new MessageHandler.Whole<ByteBuffer>() {
@Override

View File

@ -23,7 +23,6 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.core.GenericTypeResolver;
import org.springframework.util.Assert;
import org.springframework.websocket.CloseStatus;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.WebSocketMessage;
import org.springframework.websocket.WebSocketSession;
@ -41,18 +40,18 @@ public class WebSocketHandlerInvoker implements WebSocketHandler<WebSocketMessag
private Log logger = LogFactory.getLog(WebSocketHandlerInvoker.class);
private final HandlerProvider<WebSocketHandler<?>> handlerProvider;
private final WebSocketHandler<?> handler;
private final Class<?> supportedMessageType;
private WebSocketHandler<?> handler;
private final AtomicInteger sessionCount = new AtomicInteger(0);
public WebSocketHandlerInvoker(HandlerProvider<WebSocketHandler<?>> provider) {
this.handlerProvider = provider;
this.supportedMessageType = GenericTypeResolver.resolveTypeArgument(provider.getHandlerType(), WebSocketHandler.class);
public WebSocketHandlerInvoker(WebSocketHandler<?> webSocketHandler) {
Assert.notNull(webSocketHandler, "webSocketHandler is required");
this.handler = webSocketHandler;
Class<?> handlerType = webSocketHandler.getClass();
this.supportedMessageType = GenericTypeResolver.resolveTypeArgument(handlerType, WebSocketHandler.class);
}
public WebSocketHandlerInvoker setLogger(Log logger) {
@ -68,7 +67,6 @@ public class WebSocketHandlerInvoker implements WebSocketHandler<WebSocketMessag
try {
Assert.isTrue(this.sessionCount.compareAndSet(0, 1), "Unexpected new session");
this.handler = this.handlerProvider.getHandler();
this.handler.afterConnectionEstablished(session);
}
catch (Throwable ex) {
@ -86,28 +84,14 @@ public class WebSocketHandlerInvoker implements WebSocketHandler<WebSocketMessag
}
if (session.isOpen()) {
try {
session.close(CloseStatus.SERVER_ERROR);
session.close((status != null) ? status : CloseStatus.SERVER_ERROR);
}
catch (Throwable t) {
destroyHandler();
// ignore
}
}
}
private void destroyHandler() {
try {
if (this.handler != null) {
this.handlerProvider.destroy(this.handler);
}
}
catch (Throwable t) {
logger.warn("Error while destroying handler", t);
}
finally {
this.handler = null;
}
}
@SuppressWarnings("unchecked")
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) {
@ -150,9 +134,6 @@ public class WebSocketHandlerInvoker implements WebSocketHandler<WebSocketMessag
catch (Throwable ex) {
logger.error("Unhandled error for " + this, ex);
}
finally {
this.handlerProvider.destroy(this.handler);
}
}
}

View File

@ -18,7 +18,6 @@ package org.springframework.websocket.client;
import java.net.URI;
import org.springframework.http.HttpHeaders;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.WebSocketSession;
@ -35,13 +34,11 @@ import org.springframework.websocket.WebSocketSession;
*/
public interface WebSocketClient {
WebSocketSession doHandshake(WebSocketHandler handler,
WebSocketSession doHandshake(WebSocketHandler webSocketHandler,
String uriTemplate, Object... uriVariables) throws WebSocketConnectFailureException;
WebSocketSession doHandshake(HandlerProvider<WebSocketHandler<?>> handler,
String uriTemplate, Object... uriVariables) throws WebSocketConnectFailureException;
WebSocketSession doHandshake(HandlerProvider<WebSocketHandler<?>> handler, HttpHeaders headers, URI uri)
WebSocketSession doHandshake(WebSocketHandler<?> webSocketHandler, HttpHeaders headers, URI uri)
throws WebSocketConnectFailureException;
}

View File

@ -21,10 +21,8 @@ import java.util.List;
import org.springframework.http.HttpHeaders;
import org.springframework.util.CollectionUtils;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.WebSocketSession;
import org.springframework.websocket.support.SimpleHandlerProvider;
/**
* @author Rossen Stoyanchev
@ -34,7 +32,7 @@ public class WebSocketConnectionManager extends AbstractWebSocketConnectionManag
private final WebSocketClient client;
private final HandlerProvider<WebSocketHandler<?>> handlerProvider;
private final WebSocketHandler<?> webSocketHandler;
private WebSocketSession webSocketSession;
@ -46,18 +44,9 @@ public class WebSocketConnectionManager extends AbstractWebSocketConnectionManag
super(uriTemplate, uriVariables);
this.client = webSocketClient;
this.handlerProvider = new SimpleHandlerProvider<WebSocketHandler<?>>(webSocketHandler);
this.webSocketHandler = webSocketHandler;
}
public WebSocketConnectionManager(WebSocketClient webSocketClient,
HandlerProvider<WebSocketHandler<?>> handlerProvider, String uriTemplate, Object... uriVariables) {
super(uriTemplate, uriVariables);
this.client = webSocketClient;
this.handlerProvider = handlerProvider;
}
public void setSubProtocols(List<String> subProtocols) {
this.subProtocols.clear();
if (!CollectionUtils.isEmpty(subProtocols)) {
@ -73,7 +62,7 @@ public class WebSocketConnectionManager extends AbstractWebSocketConnectionManag
protected void openConnection() throws Exception {
HttpHeaders headers = new HttpHeaders();
headers.setSecWebSocketProtocol(this.subProtocols);
this.webSocketSession = this.client.doHandshake(this.handlerProvider, headers, getUri());
this.webSocketSession = this.client.doHandshake(this.webSocketHandler, headers, getUri());
}
@Override

View File

@ -21,9 +21,7 @@ import javax.websocket.Session;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.support.BeanCreatingHandlerProvider;
import org.springframework.websocket.support.SimpleHandlerProvider;
/**
* @author Rossen Stoyanchev
@ -32,30 +30,34 @@ import org.springframework.websocket.support.SimpleHandlerProvider;
public class AnnotatedEndpointConnectionManager extends EndpointConnectionManagerSupport
implements BeanFactoryAware {
private final HandlerProvider<Object> handlerProvider;
private final BeanCreatingHandlerProvider<Object> endpointProvider;
private final Object endpoint;
public AnnotatedEndpointConnectionManager(Object endpointBean, String uriTemplate, Object... uriVariables) {
public AnnotatedEndpointConnectionManager(Object endpoint, String uriTemplate, Object... uriVariables) {
super(uriTemplate, uriVariables);
this.handlerProvider = new SimpleHandlerProvider<Object>(endpointBean);
this.endpointProvider = null;
this.endpoint = endpoint;
}
public AnnotatedEndpointConnectionManager(Class<?> endpointClass, String uriTemplate, Object... uriVariables) {
super(uriTemplate, uriVariables);
this.handlerProvider = new BeanCreatingHandlerProvider<Object>(endpointClass);
this.endpointProvider = new BeanCreatingHandlerProvider<Object>(endpointClass);
this.endpoint = null;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
if (this.handlerProvider instanceof BeanFactoryAware) {
((BeanFactoryAware) this.handlerProvider).setBeanFactory(beanFactory);
if (this.endpointProvider != null) {
this.endpointProvider.setBeanFactory(beanFactory);
}
}
@Override
protected void openConnection() throws Exception {
Object endpoint = this.handlerProvider.getHandler();
Object endpoint = (this.endpoint != null) ? this.endpoint : this.endpointProvider.getHandler();
Session session = getWebSocketContainer().connectToServer(endpoint, getUri());
updateSession(session);
}

View File

@ -31,9 +31,7 @@ import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.util.Assert;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.support.BeanCreatingHandlerProvider;
import org.springframework.websocket.support.SimpleHandlerProvider;
/**
* @author Rossen Stoyanchev
@ -43,19 +41,23 @@ public class EndpointConnectionManager extends EndpointConnectionManagerSupport
private final ClientEndpointConfig.Builder configBuilder = ClientEndpointConfig.Builder.create();
private final HandlerProvider<Endpoint> handlerProvider;
private final BeanCreatingHandlerProvider<Endpoint> endpointProvider;
private final Endpoint endpoint;
public EndpointConnectionManager(Endpoint endpointBean, String uriTemplate, Object... uriVariables) {
public EndpointConnectionManager(Endpoint endpoint, String uriTemplate, Object... uriVariables) {
super(uriTemplate, uriVariables);
Assert.notNull(endpointBean, "endpointBean is required");
this.handlerProvider = new SimpleHandlerProvider<Endpoint>(endpointBean);
Assert.notNull(endpoint, "endpoint is required");
this.endpointProvider = null;
this.endpoint = endpoint;
}
public EndpointConnectionManager(Class<? extends Endpoint> endpointClass, String uriTemplate, Object... uriVars) {
super(uriTemplate, uriVars);
Assert.notNull(endpointClass, "endpointClass is required");
this.handlerProvider = new BeanCreatingHandlerProvider<Endpoint>(endpointClass);
this.endpointProvider = new BeanCreatingHandlerProvider<Endpoint>(endpointClass);
this.endpoint = null;
}
@ -81,14 +83,14 @@ public class EndpointConnectionManager extends EndpointConnectionManagerSupport
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
if (this.handlerProvider instanceof BeanFactoryAware) {
((BeanFactoryAware) this.handlerProvider).setBeanFactory(beanFactory);
if (this.endpointProvider != null) {
this.endpointProvider.setBeanFactory(beanFactory);
}
}
@Override
protected void openConnection() throws Exception {
Endpoint endpoint = this.handlerProvider.getHandler();
Endpoint endpoint = (this.endpoint != null) ? this.endpoint : this.endpointProvider.getHandler();
ClientEndpointConfig endpointConfig = this.configBuilder.build();
Session session = getWebSocketContainer().connectToServer(endpoint, endpointConfig, getUri());
updateSession(session);

View File

@ -32,14 +32,12 @@ import javax.websocket.WebSocketContainer;
import org.springframework.http.HttpHeaders;
import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.WebSocketSession;
import org.springframework.websocket.adapter.StandardWebSocketSessionAdapter;
import org.springframework.websocket.adapter.StandardEndpointAdapter;
import org.springframework.websocket.adapter.StandardWebSocketSessionAdapter;
import org.springframework.websocket.client.WebSocketClient;
import org.springframework.websocket.client.WebSocketConnectFailureException;
import org.springframework.websocket.support.SimpleHandlerProvider;
/**
* A standard Java {@link WebSocketClient}.
@ -61,24 +59,18 @@ public class StandardWebSocketClient implements WebSocketClient {
}
@Override
public WebSocketSession doHandshake(WebSocketHandler handler, String uriTemplate, Object... uriVariables)
public WebSocketSession doHandshake(WebSocketHandler webSocketHandler, String uriTemplate, Object... uriVariables)
throws WebSocketConnectFailureException {
return doHandshake(new SimpleHandlerProvider<WebSocketHandler<?>>(handler), uriTemplate, uriVariables);
}
public WebSocketSession doHandshake(HandlerProvider<WebSocketHandler<?>> handler,
String uriTemplate, Object... uriVariables) throws WebSocketConnectFailureException {
URI uri = UriComponentsBuilder.fromUriString(uriTemplate).buildAndExpand(uriVariables).encode().toUri();
return doHandshake(handler, null, uri);
return doHandshake(webSocketHandler, null, uri);
}
@Override
public WebSocketSession doHandshake(HandlerProvider<WebSocketHandler<?>> handler,
public WebSocketSession doHandshake(WebSocketHandler<?> webSocketHandler,
final HttpHeaders httpHeaders, URI uri) throws WebSocketConnectFailureException {
Endpoint endpoint = new StandardEndpointAdapter(handler);
Endpoint endpoint = new StandardEndpointAdapter(webSocketHandler);
ClientEndpointConfig.Builder configBuidler = ClientEndpointConfig.Builder.create();
if (httpHeaders != null) {

View File

@ -35,7 +35,6 @@ import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
/**
@ -88,7 +87,7 @@ public class DefaultHandshakeHandler implements HandshakeHandler {
@Override
public final boolean doHandshake(ServerHttpRequest request, ServerHttpResponse response,
HandlerProvider<WebSocketHandler<?>> handler) throws IOException {
WebSocketHandler<?> webSocketHandler) throws IOException {
logger.debug("Starting handshake for " + request.getURI());
@ -136,10 +135,10 @@ public class DefaultHandshakeHandler implements HandshakeHandler {
response.flush();
if (logger.isTraceEnabled()) {
logger.trace("Upgrading with " + handler);
logger.trace("Upgrading with " + webSocketHandler);
}
this.requestUpgradeStrategy.upgrade(request, response, selectedProtocol, handler);
this.requestUpgradeStrategy.upgrade(request, response, selectedProtocol, webSocketHandler);
return true;
}

View File

@ -20,7 +20,6 @@ import java.io.IOException;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
/**
@ -33,6 +32,6 @@ public interface HandshakeHandler {
boolean doHandshake(ServerHttpRequest request, ServerHttpResponse response,
HandlerProvider<WebSocketHandler<?>> handler) throws IOException;
WebSocketHandler<?> webSocketHandler) throws IOException;
}

View File

@ -20,7 +20,6 @@ import java.io.IOException;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
/**
@ -44,7 +43,6 @@ public interface RequestUpgradeStrategy {
* @param handler the handler for WebSocket messages
*/
void upgrade(ServerHttpRequest request, ServerHttpResponse response, String selectedProtocol,
HandlerProvider<WebSocketHandler<?>> handlerProvider) throws IOException;
// FIXME how to indicate failure to upgrade?
WebSocketHandler<?> webSocketHandler) throws IOException;
}

View File

@ -33,9 +33,7 @@ import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.util.Assert;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.support.BeanCreatingHandlerProvider;
import org.springframework.websocket.support.SimpleHandlerProvider;
/**
@ -53,7 +51,9 @@ public class EndpointRegistration implements ServerEndpointConfig, BeanFactoryAw
private final String path;
private final HandlerProvider<Endpoint> handlerProvider;
private final BeanCreatingHandlerProvider<Endpoint> endpointProvider;
private final Endpoint endpoint;
private List<Class<? extends Encoder>> encoders = new ArrayList<Class<? extends Encoder>>();
@ -70,7 +70,6 @@ public class EndpointRegistration implements ServerEndpointConfig, BeanFactoryAw
/**
* Class constructor with the {@code javax.webscoket.Endpoint} class.
* TODO
*
* @param path
* @param endpointClass
@ -79,14 +78,16 @@ public class EndpointRegistration implements ServerEndpointConfig, BeanFactoryAw
Assert.hasText(path, "path must not be empty");
Assert.notNull(endpointClass, "endpointClass is required");
this.path = path;
this.handlerProvider = new BeanCreatingHandlerProvider<Endpoint>(endpointClass);
this.endpointProvider = new BeanCreatingHandlerProvider<Endpoint>(endpointClass);
this.endpoint = null;
}
public EndpointRegistration(String path, Endpoint endpointBean) {
public EndpointRegistration(String path, Endpoint endpoint) {
Assert.hasText(path, "path must not be empty");
Assert.notNull(endpointBean, "endpointBean is required");
Assert.notNull(endpoint, "endpoint is required");
this.path = path;
this.handlerProvider = new SimpleHandlerProvider<Endpoint>(endpointBean);
this.endpointProvider = null;
this.endpoint = endpoint;
}
@ -96,13 +97,13 @@ public class EndpointRegistration implements ServerEndpointConfig, BeanFactoryAw
}
@Override
@SuppressWarnings("unchecked")
public Class<? extends Endpoint> getEndpointClass() {
return (Class<? extends Endpoint>) this.handlerProvider.getHandlerType();
return (this.endpoint != null) ?
this.endpoint.getClass() : ((Class<? extends Endpoint>) this.endpointProvider.getHandlerType());
}
public Endpoint getEndpoint() {
return this.handlerProvider.getHandler();
return (this.endpoint != null) ? this.endpoint : this.endpointProvider.getHandler();
}
public void setSubprotocols(List<String> subprotocols) {
@ -115,7 +116,6 @@ public class EndpointRegistration implements ServerEndpointConfig, BeanFactoryAw
}
public void setExtensions(List<Extension> extensions) {
// TODO: verify against ServerContainer.getInstalledExtensions()
this.extensions = extensions;
}
@ -188,8 +188,8 @@ public class EndpointRegistration implements ServerEndpointConfig, BeanFactoryAw
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
if (this.handlerProvider instanceof BeanFactoryAware) {
((BeanFactoryAware) this.handlerProvider).setBeanFactory(beanFactory);
if (this.endpointProvider != null) {
this.endpointProvider.setBeanFactory(beanFactory);
}
}

View File

@ -24,7 +24,6 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.adapter.StandardEndpointAdapter;
import org.springframework.websocket.server.RequestUpgradeStrategy;
@ -43,9 +42,9 @@ public abstract class AbstractEndpointUpgradeStrategy implements RequestUpgradeS
@Override
public void upgrade(ServerHttpRequest request, ServerHttpResponse response,
String protocol, HandlerProvider<WebSocketHandler<?>> handler) throws IOException {
String protocol, WebSocketHandler<?> webSocketHandler) throws IOException {
upgradeInternal(request, response, protocol, new StandardEndpointAdapter(handler));
upgradeInternal(request, response, protocol, new StandardEndpointAdapter(webSocketHandler));
}
protected abstract void upgradeInternal(ServerHttpRequest request, ServerHttpResponse response,

View File

@ -32,7 +32,6 @@ import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.util.Assert;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.adapter.JettyWebSocketListenerAdapter;
import org.springframework.websocket.server.RequestUpgradeStrategy;
@ -63,14 +62,12 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy {
this.factory = new WebSocketServerFactory();
this.factory.setCreator(new WebSocketCreator() {
@Override
@SuppressWarnings("unchecked")
public Object createWebSocket(UpgradeRequest request, UpgradeResponse response) {
Assert.isInstanceOf(ServletWebSocketRequest.class, request);
ServletWebSocketRequest servletRequest = (ServletWebSocketRequest) request;
HandlerProvider<WebSocketHandler<?>> handlerProvider =
(HandlerProvider<WebSocketHandler<?>>) servletRequest.getServletAttributes().get(
HANDLER_PROVIDER_ATTR_NAME);
return new JettyWebSocketListenerAdapter(handlerProvider);
WebSocketHandler<?> webSocketHandler =
(WebSocketHandler<?>) servletRequest.getServletAttributes().get(HANDLER_PROVIDER_ATTR_NAME);
return new JettyWebSocketListenerAdapter(webSocketHandler);
}
});
try {
@ -89,7 +86,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy {
@Override
public void upgrade(ServerHttpRequest request, ServerHttpResponse response,
String selectedProtocol, HandlerProvider<WebSocketHandler<?>> handlerProvider) throws IOException {
String selectedProtocol, WebSocketHandler<?> webSocketHandler) throws IOException {
Assert.isInstanceOf(ServletServerHttpRequest.class, request);
HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest();
@ -97,16 +94,16 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy {
Assert.isInstanceOf(ServletServerHttpResponse.class, response);
HttpServletResponse servletResponse = ((ServletServerHttpResponse) response).getServletResponse();
upgrade(servletRequest, servletResponse, selectedProtocol, handlerProvider);
upgrade(servletRequest, servletResponse, selectedProtocol, webSocketHandler);
}
private void upgrade(HttpServletRequest request, HttpServletResponse response,
String selectedProtocol, final HandlerProvider<WebSocketHandler<?>> handlerProvider) throws IOException {
String selectedProtocol, final WebSocketHandler<?> webSocketHandler) throws IOException {
Assert.state(this.factory.isUpgradeRequest(request, response), "Not a suitable WebSocket upgrade request");
Assert.state(this.factory.acceptWebSocket(request, response), "Unable to accept WebSocket");
request.setAttribute(HANDLER_PROVIDER_ATTR_NAME, handlerProvider);
request.setAttribute(HANDLER_PROVIDER_ATTR_NAME, webSocketHandler);
}
}

View File

@ -29,11 +29,9 @@ import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.util.Assert;
import org.springframework.web.HttpRequestHandler;
import org.springframework.web.util.NestedServletException;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.server.DefaultHandshakeHandler;
import org.springframework.websocket.server.HandshakeHandler;
import org.springframework.websocket.support.SimpleHandlerProvider;
/**
* An {@link HttpRequestHandler} that wraps the invocation of a {@link HandshakeHandler}.
@ -45,22 +43,17 @@ public class WebSocketHttpRequestHandler implements HttpRequestHandler {
private final HandshakeHandler handshakeHandler;
private final HandlerProvider<WebSocketHandler<?>> handlerProvider;
private final WebSocketHandler<?> webSocketHandler;
public WebSocketHttpRequestHandler(WebSocketHandler webSocketHandler) {
this(new SimpleHandlerProvider<WebSocketHandler<?>>(webSocketHandler));
this(webSocketHandler, new DefaultHandshakeHandler());
}
public WebSocketHttpRequestHandler( HandlerProvider<WebSocketHandler<?>> handlerProvider) {
this(handlerProvider, new DefaultHandshakeHandler());
}
public WebSocketHttpRequestHandler( HandlerProvider<WebSocketHandler<?>> handlerProvider,
HandshakeHandler handshakeHandler) {
Assert.notNull(handlerProvider, "handlerProvider is required");
public WebSocketHttpRequestHandler( WebSocketHandler<?> webSocketHandler, HandshakeHandler handshakeHandler) {
Assert.notNull(webSocketHandler, "webSocketHandler is required");
Assert.notNull(handshakeHandler, "handshakeHandler is required");
this.handlerProvider = handlerProvider;
this.webSocketHandler = webSocketHandler;
this.handshakeHandler = new DefaultHandshakeHandler();
}
@ -72,7 +65,7 @@ public class WebSocketHttpRequestHandler implements HttpRequestHandler {
ServerHttpResponse httpResponse = new ServletServerHttpResponse(response);
try {
this.handshakeHandler.doHandshake(httpRequest, httpResponse, this.handlerProvider);
this.handshakeHandler.doHandshake(httpRequest, httpResponse, this.webSocketHandler);
}
catch (Exception e) {
// TODO

View File

@ -24,16 +24,13 @@ import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.util.Assert;
import org.springframework.websocket.HandlerProvider;
/**
* A {@link HandlerProvider} that uses {@link AutowireCapableBeanFactory#createBean(Class)
* creating a fresh instance every time #getHandler() is called.
*
* @author Rossen Stoyanchev
* @since 4.0
*/
public class BeanCreatingHandlerProvider<T> implements HandlerProvider<T>, BeanFactoryAware {
public class BeanCreatingHandlerProvider<T> implements BeanFactoryAware {
private static final Log logger = LogFactory.getLog(BeanCreatingHandlerProvider.class);
@ -76,7 +73,6 @@ public class BeanCreatingHandlerProvider<T> implements HandlerProvider<T>, BeanF
}
}
@Override
public void destroy(T handler) {
if (this.beanFactory != null) {
if (logger.isTraceEnabled()) {

View File

@ -0,0 +1,132 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.websocket.support;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.core.GenericTypeResolver;
import org.springframework.util.Assert;
import org.springframework.websocket.CloseStatus;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.WebSocketMessage;
import org.springframework.websocket.WebSocketSession;
/**
* A {@link WebSocketHandler} that initializes and destroys a {@link WebSocketHandler}
* instance for each WebSocket connection and delegates all other methods to it.
*
* <p>
* Essentially create an instance of this class once, providing the type of
* {@link WebSocketHandler} class to create for each connection, and then pass it to any
* API method that expects a {@link WebSocketHandler}.
*
* <p>
* If initializing the target {@link WebSocketHandler} type requires a Spring BeanFctory,
* then the {@link #setBeanFactory(BeanFactory)} property accordingly. Simply declaring
* this class as a Spring bean will do that. Otherwise, {@link WebSocketHandler} instances
* of the target type will be created using the default constructor.
*
* @author Rossen Stoyanchev
* @since 4.0
*/
public class PerConnectionWebSocketHandlerProxy implements WebSocketHandler<WebSocketMessage<?>>, BeanFactoryAware {
private Log logger = LogFactory.getLog(PerConnectionWebSocketHandlerProxy.class);
private final BeanCreatingHandlerProvider<WebSocketHandler<?>> provider;
private Map<WebSocketSession, WebSocketHandler<?>> handlers =
new ConcurrentHashMap<WebSocketSession, WebSocketHandler<?>>();
private final Class<?> supportedMessageType;
public PerConnectionWebSocketHandlerProxy(Class<? extends WebSocketHandler<?>> handlerType) {
this.provider = new BeanCreatingHandlerProvider<WebSocketHandler<?>>(handlerType);
this.supportedMessageType = GenericTypeResolver.resolveTypeArgument(handlerType, WebSocketHandler.class);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.provider.setBeanFactory(beanFactory);
}
@Override
public void afterConnectionEstablished(WebSocketSession session) {
WebSocketHandler<?> handler = this.provider.getHandler();
this.handlers.put(session, handler);
handler.afterConnectionEstablished(session);
}
@SuppressWarnings("unchecked")
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) {
if (!this.supportedMessageType.isAssignableFrom(message.getClass())) {
try {
session.close(CloseStatus.NOT_ACCEPTABLE.withReason("Message type not supported"));
}
catch (IOException e) {
destroy(session);
}
}
else {
((WebSocketHandler) getHandler(session)).handleMessage(session, message);
}
}
private WebSocketHandler<?> getHandler(WebSocketSession session) {
WebSocketHandler<?> handler = this.handlers.get(session);
Assert.isTrue(handler != null, "WebSocketHandler not found for " + session);
return handler;
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) {
getHandler(session).handleTransportError(session, exception);
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) {
try {
getHandler(session).afterConnectionClosed(session, closeStatus);
}
finally {
destroy(session);
}
}
private void destroy(WebSocketSession session) {
WebSocketHandler<?> handler = this.handlers.remove(session);
try {
if (handler != null) {
this.provider.destroy(handler);
}
}
catch (Throwable t) {
logger.warn("Error while destroying handler", t);
}
}
}

View File

@ -1,62 +0,0 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.websocket.support;
import org.springframework.util.ClassUtils;
import org.springframework.websocket.HandlerProvider;
/**
* A {@link HandlerProvider} that returns a singleton instance.
*
* @author Rossen Stoyanchev
* @since 4.0
*/
public class SimpleHandlerProvider<T> implements HandlerProvider<T> {
private final T handler;
public SimpleHandlerProvider(T handler) {
this.handler = handler;
}
@Override
public boolean isSingleton() {
return true;
}
@Override
public Class<?> getHandlerType() {
return ClassUtils.getUserClass(this.handler);
}
@Override
public T getHandler() {
return this.handler;
}
@Override
public void destroy(T handler) {
}
@Override
public String toString() {
return "SimpleHandlerProvider [handler=" + handler + "]";
}
}