Jakarta EE 9 migration

Upgrades many dependency declarations; removes old EJB 2.x support and outdated Servlet-based integrations (Commons FileUpload, FreeMarker JSP support, Tiles).

Closes gh-22093
Closes gh-25354
Closes gh-26185
Closes gh-27423
See gh-27424
This commit is contained in:
Juergen Hoeller
2021-09-17 09:14:07 +02:00
parent 5822f1bf85
commit d84ca2ba90
1291 changed files with 4992 additions and 25322 deletions

View File

@@ -1,137 +0,0 @@
/*
* Copyright 2002-2021 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
*
* https://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.web.socket.adapter.jetty;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
import org.eclipse.jetty.websocket.api.extensions.Frame;
import org.springframework.util.Assert;
import org.springframework.web.socket.BinaryMessage;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.handler.ExceptionWebSocketHandlerDecorator;
/**
* Identical to {@link JettyWebSocketHandlerAdapter}, only excluding the
* {@code onWebSocketFrame} method, since the {@link Frame} argument has moved
* to a different package in Jetty 10.
*
* @author Rossen Stoyanchev
* @since 5.3.4
*/
@WebSocket
public class Jetty10WebSocketHandlerAdapter {
private static final Log logger = LogFactory.getLog(Jetty10WebSocketHandlerAdapter.class);
private final WebSocketHandler webSocketHandler;
private final JettyWebSocketSession wsSession;
public Jetty10WebSocketHandlerAdapter(WebSocketHandler webSocketHandler, JettyWebSocketSession wsSession) {
Assert.notNull(webSocketHandler, "WebSocketHandler must not be null");
Assert.notNull(wsSession, "WebSocketSession must not be null");
this.webSocketHandler = webSocketHandler;
this.wsSession = wsSession;
}
@OnWebSocketConnect
public void onWebSocketConnect(Session session) {
try {
this.wsSession.initializeNativeSession(session);
this.webSocketHandler.afterConnectionEstablished(this.wsSession);
}
catch (Exception ex) {
ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, ex, logger);
}
}
@OnWebSocketMessage
public void onWebSocketText(String payload) {
TextMessage message = new TextMessage(payload);
try {
this.webSocketHandler.handleMessage(this.wsSession, message);
}
catch (Exception ex) {
ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, ex, logger);
}
}
@OnWebSocketMessage
public void onWebSocketBinary(byte[] payload, int offset, int length) {
BinaryMessage message = new BinaryMessage(payload, offset, length, true);
try {
this.webSocketHandler.handleMessage(this.wsSession, message);
}
catch (Exception ex) {
ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, ex, logger);
}
}
// TODO: onWebSocketFrame can't be declared without compiling against Jetty 10
// Jetty 10: org.eclipse.jetty.websocket.api.Frame
// Jetty 9: org.eclipse.jetty.websocket.api.extensions.Frame
// @OnWebSocketFrame
// public void onWebSocketFrame(Frame frame) {
// if (OpCode.PONG == frame.getOpCode()) {
// ByteBuffer payload = frame.getPayload() != null ? frame.getPayload() : EMPTY_PAYLOAD;
// PongMessage message = new PongMessage(payload);
// try {
// this.webSocketHandler.handleMessage(this.wsSession, message);
// }
// catch (Exception ex) {
// ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, ex, logger);
// }
// }
// }
@OnWebSocketClose
public void onWebSocketClose(int statusCode, String reason) {
CloseStatus closeStatus = new CloseStatus(statusCode, reason);
try {
this.webSocketHandler.afterConnectionClosed(this.wsSession, closeStatus);
}
catch (Exception ex) {
if (logger.isWarnEnabled()) {
logger.warn("Unhandled exception after connection closed for " + this, ex);
}
}
}
@OnWebSocketError
public void onWebSocketError(Throwable cause) {
try {
this.webSocketHandler.handleTransportError(this.wsSession, cause);
}
catch (Exception ex) {
ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, ex, logger);
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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.
@@ -20,6 +20,7 @@ import java.nio.ByteBuffer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jetty.websocket.api.Frame;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
@@ -27,8 +28,7 @@ import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketFrame;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
import org.eclipse.jetty.websocket.api.extensions.Frame;
import org.eclipse.jetty.websocket.common.OpCode;
import org.eclipse.jetty.websocket.core.OpCode;
import org.springframework.util.Assert;
import org.springframework.web.socket.BinaryMessage;

View File

@@ -17,9 +17,7 @@
package org.springframework.web.socket.adapter.jetty;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.URI;
import java.security.Principal;
import java.util.ArrayList;
@@ -27,16 +25,14 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.eclipse.jetty.websocket.api.ExtensionConfig;
import org.eclipse.jetty.websocket.api.RemoteEndpoint;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
import org.springframework.http.HttpHeaders;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.socket.BinaryMessage;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.PingMessage;
@@ -57,12 +53,6 @@ import org.springframework.web.socket.adapter.AbstractWebSocketSession;
*/
public class JettyWebSocketSession extends AbstractWebSocketSession<Session> {
private static final ClassLoader loader = JettyWebSocketSession.class.getClassLoader();
private static final boolean jetty10Present = ClassUtils.isPresent(
"org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer", loader);
private final String id;
@Nullable
@@ -80,8 +70,6 @@ public class JettyWebSocketSession extends AbstractWebSocketSession<Session> {
@Nullable
private Principal user;
private final SessionHelper sessionHelper;
/**
* Create a new {@link JettyWebSocketSession} instance.
@@ -102,7 +90,6 @@ public class JettyWebSocketSession extends AbstractWebSocketSession<Session> {
super(attributes);
this.id = idGenerator.generateId().toString();
this.user = user;
this.sessionHelper = (jetty10Present ? new Jetty10SessionHelper() : new Jetty9SessionHelper());
}
@@ -144,13 +131,13 @@ public class JettyWebSocketSession extends AbstractWebSocketSession<Session> {
@Override
public InetSocketAddress getLocalAddress() {
checkNativeSessionInitialized();
return this.sessionHelper.getLocalAddress(getNativeSession());
return (InetSocketAddress) getNativeSession().getLocalAddress();
}
@Override
public InetSocketAddress getRemoteAddress() {
checkNativeSessionInitialized();
return this.sessionHelper.getRemoteAddress(getNativeSession());
return (InetSocketAddress) getNativeSession().getRemoteAddress();
}
/**
@@ -164,7 +151,7 @@ public class JettyWebSocketSession extends AbstractWebSocketSession<Session> {
@Override
public int getTextMessageSizeLimit() {
checkNativeSessionInitialized();
return this.sessionHelper.getTextMessageSizeLimit(getNativeSession());
return (int) getNativeSession().getMaxTextMessageSize();
}
/**
@@ -178,7 +165,7 @@ public class JettyWebSocketSession extends AbstractWebSocketSession<Session> {
@Override
public int getBinaryMessageSizeLimit() {
checkNativeSessionInitialized();
return this.sessionHelper.getBinaryMessageSizeLimit(getNativeSession());
return (int) getNativeSession().getMaxBinaryMessageSize();
}
@Override
@@ -201,13 +188,25 @@ public class JettyWebSocketSession extends AbstractWebSocketSession<Session> {
this.headers = HttpHeaders.readOnlyHttpHeaders(headers);
this.acceptedProtocol = session.getUpgradeResponse().getAcceptedSubProtocol();
this.extensions = this.sessionHelper.getExtensions(session);
this.extensions = getExtensions(session);
if (this.user == null) {
this.user = session.getUpgradeRequest().getUserPrincipal();
}
}
private List<WebSocketExtension> getExtensions(Session session) {
List<ExtensionConfig> configs = session.getUpgradeResponse().getExtensions();
if (!CollectionUtils.isEmpty(configs)) {
List<WebSocketExtension> result = new ArrayList<>(configs.size());
for (ExtensionConfig config : configs) {
result.add(new WebSocketExtension(config.getName(), config.getParameters()));
}
return Collections.unmodifiableList(result);
}
return Collections.emptyList();
}
@Override
protected void sendTextMessage(TextMessage message) throws IOException {
@@ -238,127 +237,4 @@ public class JettyWebSocketSession extends AbstractWebSocketSession<Session> {
getNativeSession().close(status.getCode(), status.getReason());
}
/**
* Encapsulate incompatible changes between Jetty 9.4 and 10.
*/
private interface SessionHelper {
List<WebSocketExtension> getExtensions(Session session);
int getTextMessageSizeLimit(Session session);
int getBinaryMessageSizeLimit(Session session);
InetSocketAddress getRemoteAddress(Session session);
InetSocketAddress getLocalAddress(Session session);
}
private static class Jetty9SessionHelper implements SessionHelper {
@Override
public List<WebSocketExtension> getExtensions(Session session) {
List<ExtensionConfig> configs = session.getUpgradeResponse().getExtensions();
if (!CollectionUtils.isEmpty(configs)) {
List<WebSocketExtension> result = new ArrayList<>(configs.size());
for (ExtensionConfig config : configs) {
result.add(new WebSocketExtension(config.getName(), config.getParameters()));
}
return Collections.unmodifiableList(result);
}
return Collections.emptyList();
}
@Override
public int getTextMessageSizeLimit(Session session) {
return session.getPolicy().getMaxTextMessageSize();
}
@Override
public int getBinaryMessageSizeLimit(Session session) {
return session.getPolicy().getMaxBinaryMessageSize();
}
@Override
public InetSocketAddress getRemoteAddress(Session session) {
return session.getRemoteAddress();
}
@Override
public InetSocketAddress getLocalAddress(Session session) {
return session.getLocalAddress();
}
}
private static class Jetty10SessionHelper implements SessionHelper {
private static final Method getTextMessageSizeLimitMethod;
private static final Method getBinaryMessageSizeLimitMethod;
private static final Method getRemoteAddressMethod;
private static final Method getLocalAddressMethod;
static {
try {
Class<?> type = loader.loadClass("org.eclipse.jetty.websocket.api.Session");
getTextMessageSizeLimitMethod = type.getMethod("getMaxTextMessageSize");
getBinaryMessageSizeLimitMethod = type.getMethod("getMaxBinaryMessageSize");
getRemoteAddressMethod = type.getMethod("getRemoteAddress");
getLocalAddressMethod = type.getMethod("getLocalAddress");
}
catch (ClassNotFoundException | NoSuchMethodException ex) {
throw new IllegalStateException("No compatible Jetty version found", ex);
}
}
// TODO: Extension info can't be accessed without compiling against Jetty 10
// Jetty 10: org.eclipse.jetty.websocket.api.ExtensionConfig
// Jetty 9: org.eclipse.jetty.websocket.api.extensions.ExtensionConfig
@Override
public List<WebSocketExtension> getExtensions(Session session) {
return Collections.emptyList();
}
// TODO: WebSocketPolicy can't be accessed without compiling against Jetty 10 (class -> interface)
@Override
@SuppressWarnings("ConstantConditions")
public int getTextMessageSizeLimit(Session session) {
long result = (long) ReflectionUtils.invokeMethod(getTextMessageSizeLimitMethod, session.getPolicy());
Assert.state(result <= Integer.MAX_VALUE, "textMessageSizeLimit is larger than Integer.MAX_VALUE");
return (int) result;
}
@Override
@SuppressWarnings("ConstantConditions")
public int getBinaryMessageSizeLimit(Session session) {
long result = (long) ReflectionUtils.invokeMethod(getBinaryMessageSizeLimitMethod, session.getPolicy());
Assert.state(result <= Integer.MAX_VALUE, "binaryMessageSizeLimit is larger than Integer.MAX_VALUE");
return (int) result;
}
@Override
@SuppressWarnings("ConstantConditions")
public InetSocketAddress getRemoteAddress(Session session) {
SocketAddress address = (SocketAddress) ReflectionUtils.invokeMethod(getRemoteAddressMethod, session);
Assert.isInstanceOf(InetSocketAddress.class, address);
return (InetSocketAddress) address;
}
@Override
@SuppressWarnings("ConstantConditions")
public InetSocketAddress getLocalAddress(Session session) {
SocketAddress address = (SocketAddress) ReflectionUtils.invokeMethod(getLocalAddressMethod, session);
Assert.isInstanceOf(InetSocketAddress.class, address);
return (InetSocketAddress) address;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 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.
@@ -16,7 +16,8 @@
package org.springframework.web.socket.adapter.jetty;
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
import org.eclipse.jetty.websocket.api.ExtensionConfig;
import org.eclipse.jetty.websocket.common.JettyExtensionConfig;
import org.springframework.web.socket.WebSocketExtension;
@@ -27,7 +28,7 @@ import org.springframework.web.socket.WebSocketExtension;
* @author Rossen Stoyanchev
* @since 4.0
*/
public class WebSocketToJettyExtensionConfigAdapter extends ExtensionConfig {
public class WebSocketToJettyExtensionConfigAdapter extends JettyExtensionConfig {
public WebSocketToJettyExtensionConfigAdapter(WebSocketExtension extension) {
super(extension.getName());

View File

@@ -18,11 +18,11 @@ package org.springframework.web.socket.adapter.standard;
import java.nio.ByteBuffer;
import javax.websocket.DecodeException;
import javax.websocket.Decoder;
import javax.websocket.EncodeException;
import javax.websocket.Encoder;
import javax.websocket.EndpointConfig;
import jakarta.websocket.DecodeException;
import jakarta.websocket.Decoder;
import jakarta.websocket.EncodeException;
import jakarta.websocket.Encoder;
import jakarta.websocket.EndpointConfig;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
@@ -38,8 +38,8 @@ import org.springframework.util.Assert;
import org.springframework.web.context.ContextLoader;
/**
* Base class that can be used to implement a standard {@link javax.websocket.Encoder}
* and/or {@link javax.websocket.Decoder}. It provides encode and decode method
* Base class that can be used to implement a standard {@link jakarta.websocket.Encoder}
* and/or {@link jakarta.websocket.Decoder}. It provides encode and decode method
* implementations that delegate to a Spring {@link ConversionService}.
*
* <p>By default, this class looks up a {@link ConversionService} registered in the
@@ -50,7 +50,7 @@ import org.springframework.web.context.ContextLoader;
* {@link #getConversionService()} method to provide an alternative lookup strategy.
*
* <p>Subclasses can extend this class and should also implement one or
* both of {@link javax.websocket.Encoder} and {@link javax.websocket.Decoder}.
* both of {@link jakarta.websocket.Encoder} and {@link jakarta.websocket.Decoder}.
* For convenience {@link ConvertingEncoderDecoderSupport.BinaryEncoder},
* {@link ConvertingEncoderDecoderSupport.BinaryDecoder},
* {@link ConvertingEncoderDecoderSupport.TextEncoder} and
@@ -80,8 +80,8 @@ public abstract class ConvertingEncoderDecoderSupport<T, M> {
/**
* Called to initialize the encoder/decoder.
* @see javax.websocket.Encoder#init(EndpointConfig)
* @see javax.websocket.Decoder#init(EndpointConfig)
* @see jakarta.websocket.Encoder#init(EndpointConfig)
* @see jakarta.websocket.Decoder#init(EndpointConfig)
*/
public void init(EndpointConfig config) {
ApplicationContext applicationContext = getApplicationContext();
@@ -94,8 +94,8 @@ public abstract class ConvertingEncoderDecoderSupport<T, M> {
/**
* Called to destroy the encoder/decoder.
* @see javax.websocket.Encoder#destroy()
* @see javax.websocket.Decoder#destroy()
* @see jakarta.websocket.Encoder#destroy()
* @see jakarta.websocket.Decoder#destroy()
*/
public void destroy() {
}
@@ -158,8 +158,8 @@ public abstract class ConvertingEncoderDecoderSupport<T, M> {
/**
* Encode an object to a message.
* @see javax.websocket.Encoder.Text#encode(Object)
* @see javax.websocket.Encoder.Binary#encode(Object)
* @see jakarta.websocket.Encoder.Text#encode(Object)
* @see jakarta.websocket.Encoder.Binary#encode(Object)
*/
@SuppressWarnings("unchecked")
@Nullable
@@ -175,8 +175,8 @@ public abstract class ConvertingEncoderDecoderSupport<T, M> {
/**
* Determine if a given message can be decoded.
* @see #decode(Object)
* @see javax.websocket.Decoder.Text#willDecode(String)
* @see javax.websocket.Decoder.Binary#willDecode(ByteBuffer)
* @see jakarta.websocket.Decoder.Text#willDecode(String)
* @see jakarta.websocket.Decoder.Binary#willDecode(ByteBuffer)
*/
public boolean willDecode(M bytes) {
return getConversionService().canConvert(getType(), getMessageType());
@@ -184,8 +184,8 @@ public abstract class ConvertingEncoderDecoderSupport<T, M> {
/**
* Decode the message into an object.
* @see javax.websocket.Decoder.Text#decode(String)
* @see javax.websocket.Decoder.Binary#decode(ByteBuffer)
* @see jakarta.websocket.Decoder.Text#decode(String)
* @see jakarta.websocket.Decoder.Binary#decode(ByteBuffer)
*/
@SuppressWarnings("unchecked")
@Nullable
@@ -208,7 +208,7 @@ public abstract class ConvertingEncoderDecoderSupport<T, M> {
/**
* A binary {@link javax.websocket.Encoder.Binary javax.websocket.Encoder} that delegates
* A binary {@link jakarta.websocket.Encoder.Binary jakarta.websocket.Encoder} that delegates
* to Spring's conversion service. See {@link ConvertingEncoderDecoderSupport} for details.
* @param <T> the type that this Encoder can convert to
*/
@@ -218,7 +218,7 @@ public abstract class ConvertingEncoderDecoderSupport<T, M> {
/**
* A binary {@link javax.websocket.Encoder.Binary javax.websocket.Encoder} that delegates
* A binary {@link jakarta.websocket.Encoder.Binary jakarta.websocket.Encoder} that delegates
* to Spring's conversion service. See {@link ConvertingEncoderDecoderSupport} for details.
* @param <T> the type that this Decoder can convert from
*/
@@ -228,7 +228,7 @@ public abstract class ConvertingEncoderDecoderSupport<T, M> {
/**
* A text {@link javax.websocket.Encoder.Text javax.websocket.Encoder} that delegates
* A text {@link jakarta.websocket.Encoder.Text jakarta.websocket.Encoder} that delegates
* to Spring's conversion service. See {@link ConvertingEncoderDecoderSupport} for
* details.
* @param <T> the type that this Encoder can convert to
@@ -239,7 +239,7 @@ public abstract class ConvertingEncoderDecoderSupport<T, M> {
/**
* A Text {@link javax.websocket.Encoder.Text javax.websocket.Encoder} that delegates
* A Text {@link jakarta.websocket.Encoder.Text jakarta.websocket.Encoder} that delegates
* to Spring's conversion service. See {@link ConvertingEncoderDecoderSupport} for details.
* @param <T> the type that this Decoder can convert from
*/

View File

@@ -20,14 +20,14 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.websocket.Extension;
import jakarta.websocket.Extension;
import org.springframework.util.LinkedCaseInsensitiveMap;
import org.springframework.web.socket.WebSocketExtension;
/**
* A sub-class of {@link org.springframework.web.socket.WebSocketExtension} that
* can be constructed from an {@link javax.websocket.Extension}.
* can be constructed from an {@link jakarta.websocket.Extension}.
*
* @author Rossen Stoyanchev
* @since 4.0

View File

@@ -18,11 +18,10 @@ package org.springframework.web.socket.adapter.standard;
import java.nio.ByteBuffer;
import javax.websocket.CloseReason;
import javax.websocket.Endpoint;
import javax.websocket.EndpointConfig;
import javax.websocket.MessageHandler;
import jakarta.websocket.CloseReason;
import jakarta.websocket.Endpoint;
import jakarta.websocket.EndpointConfig;
import jakarta.websocket.MessageHandler;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -58,7 +57,7 @@ public class StandardWebSocketHandlerAdapter extends Endpoint {
@Override
public void onOpen(final javax.websocket.Session session, EndpointConfig config) {
public void onOpen(final jakarta.websocket.Session session, EndpointConfig config) {
this.wsSession.initializeNativeSession(session);
// The following inner classes need to remain since lambdas would not retain their
@@ -93,9 +92,9 @@ public class StandardWebSocketHandlerAdapter extends Endpoint {
});
}
session.addMessageHandler(new MessageHandler.Whole<javax.websocket.PongMessage>() {
session.addMessageHandler(new MessageHandler.Whole<jakarta.websocket.PongMessage>() {
@Override
public void onMessage(javax.websocket.PongMessage message) {
public void onMessage(jakarta.websocket.PongMessage message) {
handlePongMessage(session, message.getApplicationData());
}
});
@@ -108,7 +107,7 @@ public class StandardWebSocketHandlerAdapter extends Endpoint {
}
}
private void handleTextMessage(javax.websocket.Session session, String payload, boolean isLast) {
private void handleTextMessage(jakarta.websocket.Session session, String payload, boolean isLast) {
TextMessage textMessage = new TextMessage(payload, isLast);
try {
this.handler.handleMessage(this.wsSession, textMessage);
@@ -118,7 +117,7 @@ public class StandardWebSocketHandlerAdapter extends Endpoint {
}
}
private void handleBinaryMessage(javax.websocket.Session session, ByteBuffer payload, boolean isLast) {
private void handleBinaryMessage(jakarta.websocket.Session session, ByteBuffer payload, boolean isLast) {
BinaryMessage binaryMessage = new BinaryMessage(payload, isLast);
try {
this.handler.handleMessage(this.wsSession, binaryMessage);
@@ -128,7 +127,7 @@ public class StandardWebSocketHandlerAdapter extends Endpoint {
}
}
private void handlePongMessage(javax.websocket.Session session, ByteBuffer payload) {
private void handlePongMessage(jakarta.websocket.Session session, ByteBuffer payload) {
PongMessage pongMessage = new PongMessage(payload);
try {
this.handler.handleMessage(this.wsSession, pongMessage);
@@ -139,7 +138,7 @@ public class StandardWebSocketHandlerAdapter extends Endpoint {
}
@Override
public void onClose(javax.websocket.Session session, CloseReason reason) {
public void onClose(jakarta.websocket.Session session, CloseReason reason) {
CloseStatus closeStatus = new CloseStatus(reason.getCloseCode().getCode(), reason.getReasonPhrase());
try {
this.handler.afterConnectionClosed(this.wsSession, closeStatus);
@@ -152,7 +151,7 @@ public class StandardWebSocketHandlerAdapter extends Endpoint {
}
@Override
public void onError(javax.websocket.Session session, Throwable exception) {
public void onError(jakarta.websocket.Session session, Throwable exception) {
try {
this.handler.handleTransportError(this.wsSession, exception);
}

View File

@@ -25,10 +25,10 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.websocket.CloseReason;
import javax.websocket.CloseReason.CloseCodes;
import javax.websocket.Extension;
import javax.websocket.Session;
import jakarta.websocket.CloseReason;
import jakarta.websocket.CloseReason.CloseCodes;
import jakarta.websocket.Extension;
import jakarta.websocket.Session;
import org.springframework.http.HttpHeaders;
import org.springframework.lang.Nullable;

View File

@@ -19,13 +19,13 @@ package org.springframework.web.socket.adapter.standard;
import java.util.ArrayList;
import java.util.List;
import javax.websocket.Extension;
import jakarta.websocket.Extension;
import org.springframework.web.socket.WebSocketExtension;
/**
* Adapt an instance of {@link org.springframework.web.socket.WebSocketExtension} to
* the {@link javax.websocket.Extension} interface.
* the {@link jakarta.websocket.Extension} interface.
*
* @author Rossen Stoyanchev
* @since 4.0

View File

@@ -16,8 +16,6 @@
package org.springframework.web.socket.client.jetty;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URI;
import java.security.Principal;
import java.util.List;
@@ -36,14 +34,11 @@ import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.core.task.TaskExecutor;
import org.springframework.http.HttpHeaders;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.util.concurrent.ListenableFutureTask;
import org.springframework.web.socket.WebSocketExtension;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.adapter.jetty.Jetty10WebSocketHandlerAdapter;
import org.springframework.web.socket.adapter.jetty.JettyWebSocketHandlerAdapter;
import org.springframework.web.socket.adapter.jetty.JettyWebSocketSession;
import org.springframework.web.socket.adapter.jetty.WebSocketToJettyExtensionConfigAdapter;
@@ -61,36 +56,16 @@ import org.springframework.web.util.UriComponentsBuilder;
* WebSocketConnectionManager} instead to auto-start a WebSocket connection.
*
* @author Rossen Stoyanchev
* @author Juergen Hoeller
* @since 4.0
*/
public class JettyWebSocketClient extends AbstractWebSocketClient implements Lifecycle {
private static ClassLoader loader = JettyWebSocketClient.class.getClassLoader();
private static final boolean jetty10Present;
private static final Method setHeadersMethod;
static {
jetty10Present = ClassUtils.isPresent(
"org.eclipse.jetty.websocket.client.JettyUpgradeListener", loader);
try {
setHeadersMethod = ClientUpgradeRequest.class.getMethod("setHeaders", Map.class);
}
catch (NoSuchMethodException ex) {
throw new IllegalStateException("No compatible Jetty version found", ex);
}
}
private final org.eclipse.jetty.websocket.client.WebSocketClient client;
@Nullable
private AsyncListenableTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor();
private final UpgradeHelper upgradeHelper =
(jetty10Present ? new Jetty10UpgradeHelper() : new Jetty9UpgradeHelper());
/**
* Default constructor that creates an instance of
@@ -170,19 +145,18 @@ public class JettyWebSocketClient extends AbstractWebSocketClient implements Lif
final ClientUpgradeRequest request = new ClientUpgradeRequest();
request.setSubProtocols(protocols);
for (WebSocketExtension e : extensions) {
request.addExtensions(new WebSocketToJettyExtensionConfigAdapter(e));
for (WebSocketExtension extension : extensions) {
request.addExtensions(new WebSocketToJettyExtensionConfigAdapter(extension));
}
// Jetty 9: setHeaders declared in UpgradeRequestAdapter base class
// Jetty 10: setHeaders declared in ClientUpgradeRequest
ReflectionUtils.invokeMethod(setHeadersMethod, request, headers);
request.setHeaders(headers);
Principal user = getUser();
JettyWebSocketSession wsSession = new JettyWebSocketSession(attributes, user);
Callable<WebSocketSession> connectTask = () -> {
Future<Session> future = this.upgradeHelper.connect(this.client, uri, request, wsHandler, wsSession);
JettyWebSocketHandlerAdapter adapter = new JettyWebSocketHandlerAdapter(wsHandler, wsSession);
Future<Session> future = this.client.connect(adapter, uri, request);
future.get(this.client.getConnectTimeout() + 2000, TimeUnit.MILLISECONDS);
return wsSession;
};
@@ -206,55 +180,4 @@ public class JettyWebSocketClient extends AbstractWebSocketClient implements Lif
return null;
}
/**
* Encapsulate incompatible changes between Jetty 9.4 and 10.
*/
private interface UpgradeHelper {
Future<Session> connect(WebSocketClient client, URI url, ClientUpgradeRequest request,
WebSocketHandler handler, JettyWebSocketSession session) throws IOException;
}
private static class Jetty9UpgradeHelper implements UpgradeHelper {
@Override
public Future<Session> connect(WebSocketClient client, URI url, ClientUpgradeRequest request,
WebSocketHandler handler, JettyWebSocketSession session) throws IOException {
JettyWebSocketHandlerAdapter adapter = new JettyWebSocketHandlerAdapter(handler, session);
return client.connect(adapter, url, request);
}
}
private static class Jetty10UpgradeHelper implements UpgradeHelper {
// On Jetty 9 returns Future, on Jetty 10 returns CompletableFuture
private static final Method connectMethod;
static {
try {
Class<?> type = loader.loadClass("org.eclipse.jetty.websocket.client.WebSocketClient");
connectMethod = type.getMethod("connect", Object.class, URI.class, ClientUpgradeRequest.class);
}
catch (ClassNotFoundException | NoSuchMethodException ex) {
throw new IllegalStateException("No compatible Jetty version found", ex);
}
}
@Override
@SuppressWarnings({"ConstantConditions", "unchecked"})
public Future<Session> connect(WebSocketClient client, URI url, ClientUpgradeRequest request,
WebSocketHandler handler, JettyWebSocketSession session) {
Jetty10WebSocketHandlerAdapter adapter = new Jetty10WebSocketHandlerAdapter(handler, session);
// TODO: pass JettyUpgradeListener argument to set headers from HttpHeaders (like we do for Jetty 9)
// which would require a JDK Proxy since it is new in Jetty 10
return (Future<Session>) ReflectionUtils.invokeMethod(connectMethod, client, adapter, url, request);
}
}
}

View File

@@ -16,9 +16,9 @@
package org.springframework.web.socket.client.standard;
import javax.websocket.ContainerProvider;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;
import jakarta.websocket.ContainerProvider;
import jakarta.websocket.Session;
import jakarta.websocket.WebSocketContainer;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
@@ -32,7 +32,7 @@ import org.springframework.web.socket.handler.BeanCreatingHandlerProvider;
/**
* A WebSocket connection manager that is given a URI, a
* {@link javax.websocket.ClientEndpoint}-annotated endpoint, connects to a
* {@link jakarta.websocket.ClientEndpoint}-annotated endpoint, connects to a
* WebSocket server through the {@link #start()} and {@link #stop()} methods.
* If {@link #setAutoStartup(boolean)} is set to {@code true} this will be
* done automatically when the Spring ApplicationContext is refreshed.

View File

@@ -19,15 +19,15 @@ package org.springframework.web.socket.client.standard;
import java.util.Arrays;
import java.util.List;
import javax.websocket.ClientEndpointConfig;
import javax.websocket.ClientEndpointConfig.Configurator;
import javax.websocket.ContainerProvider;
import javax.websocket.Decoder;
import javax.websocket.Encoder;
import javax.websocket.Endpoint;
import javax.websocket.Extension;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;
import jakarta.websocket.ClientEndpointConfig;
import jakarta.websocket.ClientEndpointConfig.Configurator;
import jakarta.websocket.ContainerProvider;
import jakarta.websocket.Decoder;
import jakarta.websocket.Encoder;
import jakarta.websocket.Endpoint;
import jakarta.websocket.Extension;
import jakarta.websocket.Session;
import jakarta.websocket.WebSocketContainer;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;

View File

@@ -27,13 +27,13 @@ import java.util.Locale;
import java.util.Map;
import java.util.concurrent.Callable;
import javax.websocket.ClientEndpointConfig;
import javax.websocket.ClientEndpointConfig.Configurator;
import javax.websocket.ContainerProvider;
import javax.websocket.Endpoint;
import javax.websocket.Extension;
import javax.websocket.HandshakeResponse;
import javax.websocket.WebSocketContainer;
import jakarta.websocket.ClientEndpointConfig;
import jakarta.websocket.ClientEndpointConfig.Configurator;
import jakarta.websocket.ContainerProvider;
import jakarta.websocket.Endpoint;
import jakarta.websocket.Extension;
import jakarta.websocket.HandshakeResponse;
import jakarta.websocket.WebSocketContainer;
import org.springframework.core.task.AsyncListenableTaskExecutor;
import org.springframework.core.task.SimpleAsyncTaskExecutor;

View File

@@ -16,13 +16,13 @@
package org.springframework.web.socket.client.standard;
import javax.websocket.ContainerProvider;
import javax.websocket.WebSocketContainer;
import jakarta.websocket.ContainerProvider;
import jakarta.websocket.WebSocketContainer;
import org.springframework.beans.factory.FactoryBean;
/**
* A FactoryBean for creating and configuring a {@link javax.websocket.WebSocketContainer}
* A FactoryBean for creating and configuring a {@link jakarta.websocket.WebSocketContainer}
* through Spring XML configuration. In Java configuration, ignore this class and use
* {@code ContainerProvider.getWebSocketContainer()} instead.
*

View File

@@ -127,8 +127,8 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser {
jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) &&
ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader);
gsonPresent = ClassUtils.isPresent("com.google.gson.Gson", classLoader);
jsonbPresent = ClassUtils.isPresent("javax.json.bind.Jsonb", classLoader);
javaxValidationPresent = ClassUtils.isPresent("javax.validation.Validator", classLoader);
jsonbPresent = ClassUtils.isPresent("jakarta.json.bind.Jsonb", classLoader);
javaxValidationPresent = ClassUtils.isPresent("jakarta.validation.Validator", classLoader);
}

View File

@@ -1,167 +0,0 @@
/*
* Copyright 2002-2021 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
*
* https://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.web.socket.server.jetty;
import java.lang.reflect.Method;
import java.lang.reflect.UndeclaredThrowableException;
import java.security.Principal;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.target.EmptyTargetSource;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.socket.WebSocketExtension;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.adapter.jetty.Jetty10WebSocketHandlerAdapter;
import org.springframework.web.socket.adapter.jetty.JettyWebSocketSession;
import org.springframework.web.socket.server.HandshakeFailureException;
import org.springframework.web.socket.server.RequestUpgradeStrategy;
/**
* A {@link RequestUpgradeStrategy} for Jetty 10.
*
* @author Rossen Stoyanchev
* @since 5.3.4
*/
public class Jetty10RequestUpgradeStrategy implements RequestUpgradeStrategy {
private static final String[] SUPPORTED_VERSIONS = new String[] { String.valueOf(13) };
private static final Class<?> webSocketCreatorClass;
private static final Method getContainerMethod;
private static final Method upgradeMethod;
private static final Method setAcceptedSubProtocol;
static {
ClassLoader loader = Jetty10RequestUpgradeStrategy.class.getClassLoader();
try {
webSocketCreatorClass = loader.loadClass("org.eclipse.jetty.websocket.server.JettyWebSocketCreator");
Class<?> type = loader.loadClass("org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer");
getContainerMethod = type.getMethod("getContainer", ServletContext.class);
Method upgrade = ReflectionUtils.findMethod(type, "upgrade", (Class<?>[]) null);
Assert.state(upgrade != null, "Upgrade method not found");
upgradeMethod = upgrade;
type = loader.loadClass("org.eclipse.jetty.websocket.server.JettyServerUpgradeResponse");
setAcceptedSubProtocol = type.getMethod("setAcceptedSubProtocol", String.class);
}
catch (Exception ex) {
throw new IllegalStateException("No compatible Jetty version found", ex);
}
}
@Override
public String[] getSupportedVersions() {
return SUPPORTED_VERSIONS;
}
@Override
public List<WebSocketExtension> getSupportedExtensions(ServerHttpRequest request) {
return Collections.emptyList();
}
@Override
public void upgrade(ServerHttpRequest request, ServerHttpResponse response,
@Nullable String selectedProtocol, List<WebSocketExtension> selectedExtensions,
@Nullable Principal user, WebSocketHandler handler, Map<String, Object> attributes)
throws HandshakeFailureException {
Assert.isInstanceOf(ServletServerHttpRequest.class, request, "ServletServerHttpRequest required");
HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest();
ServletContext servletContext = servletRequest.getServletContext();
Assert.isInstanceOf(ServletServerHttpResponse.class, response, "ServletServerHttpResponse required");
HttpServletResponse servletResponse = ((ServletServerHttpResponse) response).getServletResponse();
JettyWebSocketSession session = new JettyWebSocketSession(attributes, user);
Jetty10WebSocketHandlerAdapter handlerAdapter = new Jetty10WebSocketHandlerAdapter(handler, session);
try {
Object creator = createJettyWebSocketCreator(handlerAdapter, selectedProtocol);
Object container = ReflectionUtils.invokeMethod(getContainerMethod, null, servletContext);
ReflectionUtils.invokeMethod(upgradeMethod, container, creator, servletRequest, servletResponse);
}
catch (UndeclaredThrowableException ex) {
throw new HandshakeFailureException("Failed to upgrade", ex.getUndeclaredThrowable());
}
catch (Exception ex) {
throw new HandshakeFailureException("Failed to upgrade", ex);
}
}
private static Object createJettyWebSocketCreator(
Jetty10WebSocketHandlerAdapter adapter, @Nullable String protocol) {
ProxyFactory factory = new ProxyFactory(EmptyTargetSource.INSTANCE);
factory.addInterface(webSocketCreatorClass);
factory.addAdvice(new WebSocketCreatorInterceptor(adapter, protocol));
return factory.getProxy();
}
/**
* Proxy for a JettyWebSocketCreator to supply the WebSocket handler and set the sub-protocol.
*/
private static class WebSocketCreatorInterceptor implements MethodInterceptor {
private final Jetty10WebSocketHandlerAdapter adapter;
@Nullable
private final String protocol;
public WebSocketCreatorInterceptor(
Jetty10WebSocketHandlerAdapter adapter, @Nullable String protocol) {
this.adapter = adapter;
this.protocol = protocol;
}
@Nullable
@Override
public Object invoke(@NonNull MethodInvocation invocation) {
if (this.protocol != null) {
ReflectionUtils.invokeMethod(
setAcceptedSubProtocol, invocation.getArguments()[2], this.protocol);
}
return this.adapter;
}
}
}

View File

@@ -16,268 +16,149 @@
package org.springframework.web.socket.server.jetty;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.UndeclaredThrowableException;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
import org.eclipse.jetty.websocket.server.WebSocketServerFactory;
import org.springframework.context.Lifecycle;
import org.springframework.core.NamedThreadLocal;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.target.EmptyTargetSource;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.socket.WebSocketExtension;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.adapter.jetty.JettyWebSocketHandlerAdapter;
import org.springframework.web.socket.adapter.jetty.JettyWebSocketSession;
import org.springframework.web.socket.adapter.jetty.WebSocketToJettyExtensionConfigAdapter;
import org.springframework.web.socket.server.HandshakeFailureException;
import org.springframework.web.socket.server.RequestUpgradeStrategy;
/**
* A {@link RequestUpgradeStrategy} for use with Jetty 9.4. Based on Jetty's
* internal {@code org.eclipse.jetty.websocket.server.WebSocketHandler} class.
* A {@link RequestUpgradeStrategy} for Jetty 11.
*
* @author Phillip Webb
* @author Rossen Stoyanchev
* @author Brian Clozel
* @author Juergen Hoeller
* @since 4.0
* @since 5.3.4
*/
public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, ServletContextAware, Lifecycle {
public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy {
private static final ThreadLocal<WebSocketHandlerContainer> containerHolder =
new NamedThreadLocal<>("WebSocketHandlerContainer");
private static final String[] SUPPORTED_VERSIONS = new String[] { String.valueOf(13) };
@Nullable
private WebSocketPolicy policy;
private static final Class<?> webSocketCreatorClass;
@Nullable
private volatile WebSocketServerFactory factory;
private static final Method getContainerMethod;
@Nullable
private ServletContext servletContext;
private static final Method upgradeMethod;
private volatile boolean running;
private static final Method setAcceptedSubProtocol;
@Nullable
private volatile List<WebSocketExtension> supportedExtensions;
static {
// TODO: can switch to non-reflective implementation now
ClassLoader loader = JettyRequestUpgradeStrategy.class.getClassLoader();
try {
webSocketCreatorClass = loader.loadClass("org.eclipse.jetty.websocket.server.JettyWebSocketCreator");
/**
* Default constructor that creates {@link WebSocketServerFactory} through
* its default constructor thus using a default {@link WebSocketPolicy}.
*/
public JettyRequestUpgradeStrategy() {
this.policy = WebSocketPolicy.newServerPolicy();
}
Class<?> type = loader.loadClass("org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer");
getContainerMethod = type.getMethod("getContainer", ServletContext.class);
Method upgrade = ReflectionUtils.findMethod(type, "upgrade", (Class<?>[]) null);
Assert.state(upgrade != null, "Upgrade method not found");
upgradeMethod = upgrade;
/**
* A constructor accepting a {@link WebSocketPolicy} to be used when
* creating the {@link WebSocketServerFactory} instance.
* @param policy the policy to use
* @since 4.3.5
*/
public JettyRequestUpgradeStrategy(WebSocketPolicy policy) {
Assert.notNull(policy, "WebSocketPolicy must not be null");
this.policy = policy;
}
/**
* A constructor accepting a {@link WebSocketServerFactory}.
* @param factory the pre-configured factory to use
*/
public JettyRequestUpgradeStrategy(WebSocketServerFactory factory) {
Assert.notNull(factory, "WebSocketServerFactory must not be null");
this.factory = factory;
}
@Override
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
@Override
public void start() {
if (!isRunning()) {
this.running = true;
try {
WebSocketServerFactory factory = this.factory;
if (factory == null) {
Assert.state(this.servletContext != null, "No ServletContext set");
factory = new WebSocketServerFactory(this.servletContext, this.policy);
this.factory = factory;
}
factory.setCreator((request, response) -> {
WebSocketHandlerContainer container = containerHolder.get();
Assert.state(container != null, "Expected WebSocketHandlerContainer");
response.setAcceptedSubProtocol(container.getSelectedProtocol());
response.setExtensions(container.getExtensionConfigs());
return container.getHandler();
});
factory.start();
}
catch (Throwable ex) {
throw new IllegalStateException("Unable to start Jetty WebSocketServerFactory", ex);
}
type = loader.loadClass("org.eclipse.jetty.websocket.server.JettyServerUpgradeResponse");
setAcceptedSubProtocol = type.getMethod("setAcceptedSubProtocol", String.class);
}
}
@Override
public void stop() {
if (isRunning()) {
this.running = false;
WebSocketServerFactory factory = this.factory;
if (factory != null) {
try {
factory.stop();
}
catch (Throwable ex) {
throw new IllegalStateException("Unable to stop Jetty WebSocketServerFactory", ex);
}
}
catch (Exception ex) {
throw new IllegalStateException("No compatible Jetty version found", ex);
}
}
@Override
public boolean isRunning() {
return this.running;
}
@Override
public String[] getSupportedVersions() {
return new String[] { String.valueOf(13) };
return SUPPORTED_VERSIONS;
}
@Override
public List<WebSocketExtension> getSupportedExtensions(ServerHttpRequest request) {
List<WebSocketExtension> extensions = this.supportedExtensions;
if (extensions == null) {
extensions = buildWebSocketExtensions();
this.supportedExtensions = extensions;
}
return extensions;
return Collections.emptyList();
}
private List<WebSocketExtension> buildWebSocketExtensions() {
Set<String> names = getExtensionNames();
List<WebSocketExtension> result = new ArrayList<>(names.size());
for (String name : names) {
result.add(new WebSocketExtension(name));
}
return result;
}
@SuppressWarnings({"unchecked", "deprecation"})
private Set<String> getExtensionNames() {
WebSocketServerFactory factory = this.factory;
Assert.state(factory != null, "No WebSocketServerFactory available");
try {
return factory.getAvailableExtensionNames();
}
catch (IncompatibleClassChangeError ex) {
// Fallback for versions prior to 9.4.21:
// 9.4.20.v20190813: ExtensionFactory (abstract class -> interface)
// 9.4.21.v20190926: ExtensionFactory (interface -> abstract class) + deprecated
Class<?> clazz = org.eclipse.jetty.websocket.api.extensions.ExtensionFactory.class;
Method method = ClassUtils.getMethod(clazz, "getExtensionNames");
Set<String> result = (Set<String>) ReflectionUtils.invokeMethod(method, factory.getExtensionFactory());
return (result != null ? result : Collections.emptySet());
}
}
@Override
public void upgrade(ServerHttpRequest request, ServerHttpResponse response,
@Nullable String selectedProtocol, List<WebSocketExtension> selectedExtensions, @Nullable Principal user,
WebSocketHandler wsHandler, Map<String, Object> attributes) throws HandshakeFailureException {
@Nullable String selectedProtocol, List<WebSocketExtension> selectedExtensions,
@Nullable Principal user, WebSocketHandler handler, Map<String, Object> attributes)
throws HandshakeFailureException {
Assert.isInstanceOf(ServletServerHttpRequest.class, request, "ServletServerHttpRequest required");
HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest();
ServletContext servletContext = servletRequest.getServletContext();
Assert.isInstanceOf(ServletServerHttpResponse.class, response, "ServletServerHttpResponse required");
HttpServletResponse servletResponse = ((ServletServerHttpResponse) response).getServletResponse();
WebSocketServerFactory factory = this.factory;
Assert.state(factory != null, "No WebSocketServerFactory available");
Assert.isTrue(factory.isUpgradeRequest(servletRequest, servletResponse), "Not a WebSocket handshake");
JettyWebSocketSession session = new JettyWebSocketSession(attributes, user);
JettyWebSocketHandlerAdapter handlerAdapter = new JettyWebSocketHandlerAdapter(wsHandler, session);
WebSocketHandlerContainer container =
new WebSocketHandlerContainer(handlerAdapter, selectedProtocol, selectedExtensions);
JettyWebSocketHandlerAdapter handlerAdapter = new JettyWebSocketHandlerAdapter(handler, session);
try {
containerHolder.set(container);
factory.acceptWebSocket(servletRequest, servletResponse);
Object creator = createJettyWebSocketCreator(handlerAdapter, selectedProtocol);
Object container = ReflectionUtils.invokeMethod(getContainerMethod, null, servletContext);
ReflectionUtils.invokeMethod(upgradeMethod, container, creator, servletRequest, servletResponse);
}
catch (IOException ex) {
throw new HandshakeFailureException(
"Response update failed during upgrade to WebSocket: " + request.getURI(), ex);
catch (UndeclaredThrowableException ex) {
throw new HandshakeFailureException("Failed to upgrade", ex.getUndeclaredThrowable());
}
finally {
containerHolder.remove();
catch (Exception ex) {
throw new HandshakeFailureException("Failed to upgrade", ex);
}
}
private static Object createJettyWebSocketCreator(
JettyWebSocketHandlerAdapter adapter, @Nullable String protocol) {
private static class WebSocketHandlerContainer {
ProxyFactory factory = new ProxyFactory(EmptyTargetSource.INSTANCE);
factory.addInterface(webSocketCreatorClass);
factory.addAdvice(new WebSocketCreatorInterceptor(adapter, protocol));
return factory.getProxy();
}
private final JettyWebSocketHandlerAdapter handler;
/**
* Proxy for a JettyWebSocketCreator to supply the WebSocket handler and set the sub-protocol.
*/
private static class WebSocketCreatorInterceptor implements MethodInterceptor {
private final JettyWebSocketHandlerAdapter adapter;
@Nullable
private final String selectedProtocol;
private final String protocol;
private final List<ExtensionConfig> extensionConfigs;
public WebSocketHandlerContainer(JettyWebSocketHandlerAdapter handler,
@Nullable String protocol, List<WebSocketExtension> extensions) {
this.handler = handler;
this.selectedProtocol = protocol;
if (CollectionUtils.isEmpty(extensions)) {
this.extensionConfigs = new ArrayList<>(0);
}
else {
this.extensionConfigs = new ArrayList<>(extensions.size());
for (WebSocketExtension extension : extensions) {
this.extensionConfigs.add(new WebSocketToJettyExtensionConfigAdapter(extension));
}
}
}
public JettyWebSocketHandlerAdapter getHandler() {
return this.handler;
public WebSocketCreatorInterceptor(JettyWebSocketHandlerAdapter adapter, @Nullable String protocol) {
this.adapter = adapter;
this.protocol = protocol;
}
@Nullable
public String getSelectedProtocol() {
return this.selectedProtocol;
}
public List<ExtensionConfig> getExtensionConfigs() {
return this.extensionConfigs;
@Override
public Object invoke(@NonNull MethodInvocation invocation) {
if (this.protocol != null) {
ReflectionUtils.invokeMethod(
setAcceptedSubProtocol, invocation.getArguments()[2], this.protocol);
}
return this.adapter;
}
}

View File

@@ -22,14 +22,13 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.websocket.Endpoint;
import javax.websocket.Extension;
import javax.websocket.WebSocketContainer;
import javax.websocket.server.ServerContainer;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.websocket.Endpoint;
import jakarta.websocket.Extension;
import jakarta.websocket.WebSocketContainer;
import jakarta.websocket.server.ServerContainer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -66,9 +65,9 @@ public abstract class AbstractStandardUpgradeStrategy implements RequestUpgradeS
protected ServerContainer getContainer(HttpServletRequest request) {
ServletContext servletContext = request.getServletContext();
String attrName = "javax.websocket.server.ServerContainer";
String attrName = "jakarta.websocket.server.ServerContainer";
ServerContainer container = (ServerContainer) servletContext.getAttribute(attrName);
Assert.notNull(container, "No 'javax.websocket.server.ServerContainer' ServletContext attribute. " +
Assert.notNull(container, "No 'jakarta.websocket.server.ServerContainer' ServletContext attribute. " +
"Are you running in a Servlet container that supports JSR-356?");
return container;
}

View File

@@ -25,15 +25,14 @@ import java.util.Collections;
import java.util.List;
import java.util.Random;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.websocket.DeploymentException;
import javax.websocket.Endpoint;
import javax.websocket.EndpointConfig;
import javax.websocket.Extension;
import javax.websocket.WebSocketContainer;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.websocket.DeploymentException;
import jakarta.websocket.Endpoint;
import jakarta.websocket.EndpointConfig;
import jakarta.websocket.Extension;
import jakarta.websocket.WebSocketContainer;
import org.glassfish.tyrus.core.ComponentProviderService;
import org.glassfish.tyrus.core.RequestContext;
import org.glassfish.tyrus.core.TyrusEndpointWrapper;

View File

@@ -19,10 +19,9 @@ package org.springframework.web.socket.server.standard;
import java.io.IOException;
import java.lang.reflect.Constructor;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.glassfish.tyrus.core.TyrusUpgradeResponse;
import org.glassfish.tyrus.core.Utils;
import org.glassfish.tyrus.servlet.TyrusHttpUpgradeHandler;

View File

@@ -22,11 +22,11 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletContext;
import javax.websocket.DeploymentException;
import javax.websocket.server.ServerContainer;
import javax.websocket.server.ServerEndpoint;
import javax.websocket.server.ServerEndpointConfig;
import jakarta.servlet.ServletContext;
import jakarta.websocket.DeploymentException;
import jakarta.websocket.server.ServerContainer;
import jakarta.websocket.server.ServerEndpoint;
import jakarta.websocket.server.ServerEndpointConfig;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.SmartInitializingSingleton;
@@ -36,7 +36,7 @@ import org.springframework.util.Assert;
import org.springframework.web.context.support.WebApplicationObjectSupport;
/**
* Detects beans of type {@link javax.websocket.server.ServerEndpointConfig} and registers
* Detects beans of type {@link jakarta.websocket.server.ServerEndpointConfig} and registers
* with the standard Java WebSocket runtime. Also detects beans annotated with
* {@link ServerEndpoint} and registers them as well. Although not required, it is likely
* annotated endpoints should have their {@code configurator} property set to
@@ -93,7 +93,7 @@ public class ServerEndpointExporter extends WebApplicationObjectSupport
protected void initServletContext(ServletContext servletContext) {
if (this.serverContainer == null) {
this.serverContainer =
(ServerContainer) servletContext.getAttribute("javax.websocket.server.ServerContainer");
(ServerContainer) servletContext.getAttribute("jakarta.websocket.server.ServerContainer");
}
}
@@ -104,7 +104,7 @@ public class ServerEndpointExporter extends WebApplicationObjectSupport
@Override
public void afterPropertiesSet() {
Assert.state(getServerContainer() != null, "javax.websocket.server.ServerContainer not available");
Assert.state(getServerContainer() != null, "jakarta.websocket.server.ServerContainer not available");
}
@Override

View File

@@ -21,13 +21,13 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.websocket.Decoder;
import javax.websocket.Encoder;
import javax.websocket.Endpoint;
import javax.websocket.Extension;
import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;
import jakarta.websocket.Decoder;
import jakarta.websocket.Encoder;
import jakarta.websocket.Endpoint;
import jakarta.websocket.Extension;
import jakarta.websocket.HandshakeResponse;
import jakarta.websocket.server.HandshakeRequest;
import jakarta.websocket.server.ServerEndpointConfig;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
@@ -36,17 +36,17 @@ import org.springframework.util.Assert;
import org.springframework.web.socket.handler.BeanCreatingHandlerProvider;
/**
* An implementation of {@link javax.websocket.server.ServerEndpointConfig} for use in
* An implementation of {@link jakarta.websocket.server.ServerEndpointConfig} for use in
* Spring-based applications. A {@link ServerEndpointRegistration} bean is detected by
* {@link ServerEndpointExporter} and registered with a Java WebSocket runtime at startup.
*
* <p>Class constructors accept a singleton {@link javax.websocket.Endpoint} instance
* <p>Class constructors accept a singleton {@link jakarta.websocket.Endpoint} instance
* or an Endpoint specified by type {@link Class}. When specified by type, the endpoint
* will be instantiated and initialized through the Spring ApplicationContext before
* each client WebSocket connection.
*
* <p>This class also extends
* {@link javax.websocket.server.ServerEndpointConfig.Configurator} to make it easier
* {@link jakarta.websocket.server.ServerEndpointConfig.Configurator} to make it easier
* to override methods for customizing the handshake process.
*
* @author Rossen Stoyanchev
@@ -78,7 +78,7 @@ public class ServerEndpointRegistration extends ServerEndpointConfig.Configurato
/**
* Create a new {@link ServerEndpointRegistration} instance from an
* {@code javax.websocket.Endpoint} instance.
* {@code jakarta.websocket.Endpoint} instance.
* @param path the endpoint path
* @param endpoint the endpoint instance
*/
@@ -92,7 +92,7 @@ public class ServerEndpointRegistration extends ServerEndpointConfig.Configurato
/**
* Create a new {@link ServerEndpointRegistration} instance from an
* {@code javax.websocket.Endpoint} class.
* {@code jakarta.websocket.Endpoint} class.
* @param path the endpoint path
* @param endpointClass the endpoint class
*/

View File

@@ -16,9 +16,9 @@
package org.springframework.web.socket.server.standard;
import javax.servlet.ServletContext;
import javax.websocket.WebSocketContainer;
import javax.websocket.server.ServerContainer;
import jakarta.servlet.ServletContext;
import jakarta.websocket.WebSocketContainer;
import jakarta.websocket.server.ServerContainer;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
@@ -27,9 +27,9 @@ import org.springframework.util.Assert;
import org.springframework.web.context.ServletContextAware;
/**
* A {@link FactoryBean} for configuring {@link javax.websocket.server.ServerContainer}.
* A {@link FactoryBean} for configuring {@link jakarta.websocket.server.ServerContainer}.
* Since there is usually only one {@code ServerContainer} instance accessible under a
* well-known {@code javax.servlet.ServletContext} attribute, simply declaring this
* well-known {@code jakarta.servlet.ServletContext} attribute, simply declaring this
* FactoryBean and using its setters allows for configuring the {@code ServerContainer}
* through Spring configuration.
*
@@ -111,11 +111,11 @@ public class ServletServerContainerFactoryBean
@Override
public void afterPropertiesSet() {
Assert.state(this.servletContext != null,
"A ServletContext is required to access the javax.websocket.server.ServerContainer instance");
"A ServletContext is required to access the jakarta.websocket.server.ServerContainer instance");
this.serverContainer = (ServerContainer) this.servletContext.getAttribute(
"javax.websocket.server.ServerContainer");
"jakarta.websocket.server.ServerContainer");
Assert.state(this.serverContainer != null,
"Attribute 'javax.websocket.server.ServerContainer' not found in ServletContext");
"Attribute 'jakarta.websocket.server.ServerContainer' not found in ServletContext");
if (this.asyncSendTimeout != null) {
this.serverContainer.setAsyncSendTimeout(this.asyncSendTimeout);

View File

@@ -20,9 +20,8 @@ import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.websocket.server.ServerEndpoint;
import javax.websocket.server.ServerEndpointConfig.Configurator;
import jakarta.websocket.server.ServerEndpoint;
import jakarta.websocket.server.ServerEndpointConfig.Configurator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -35,7 +34,7 @@ import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
/**
* A {@link javax.websocket.server.ServerEndpointConfig.Configurator} for initializing
* A {@link jakarta.websocket.server.ServerEndpointConfig.Configurator} for initializing
* {@link ServerEndpoint}-annotated classes through Spring.
*
* <p>

View File

@@ -21,12 +21,11 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.websocket.Endpoint;
import javax.websocket.Extension;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.websocket.Endpoint;
import jakarta.websocket.Extension;
import org.apache.tomcat.websocket.server.WsServerContainer;
import org.springframework.http.server.ServerHttpRequest;
@@ -38,10 +37,10 @@ import org.springframework.web.socket.server.HandshakeFailureException;
* A WebSocket {@code RequestUpgradeStrategy} for Apache Tomcat. Compatible with
* all versions of Tomcat that support JSR-356, i.e. Tomcat 7.0.47+ and higher.
*
* <p>To modify properties of the underlying {@link javax.websocket.server.ServerContainer}
* <p>To modify properties of the underlying {@link jakarta.websocket.server.ServerContainer}
* you can use {@link ServletServerContainerFactoryBean} in XML configuration or,
* when using Java configuration, access the container instance through the
* "javax.websocket.server.ServerContainer" ServletContext attribute.
* "jakarta.websocket.server.ServerContainer" ServletContext attribute.
*
* @author Rossen Stoyanchev
* @since 4.0

View File

@@ -21,14 +21,13 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.websocket.Endpoint;
import javax.websocket.Extension;
import io.undertow.websockets.core.WebSocketVersion;
import io.undertow.websockets.jsr.ServerWebSocketContainer;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.websocket.Endpoint;
import jakarta.websocket.Extension;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;

View File

@@ -20,14 +20,13 @@ import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import javax.servlet.AsyncContext;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestWrapper;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jakarta.servlet.AsyncContext;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletRequestWrapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.glassfish.tyrus.core.TyrusUpgradeResponse;
import org.glassfish.tyrus.core.Utils;
import org.glassfish.tyrus.spi.Connection;

View File

@@ -21,12 +21,12 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.websocket.Endpoint;
import javax.websocket.Extension;
import javax.websocket.server.ServerContainer;
import javax.websocket.server.ServerEndpointConfig;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.websocket.Endpoint;
import jakarta.websocket.Extension;
import jakarta.websocket.server.ServerContainer;
import jakarta.websocket.server.ServerEndpointConfig;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;

View File

@@ -67,7 +67,6 @@ import org.springframework.web.socket.server.RequestUpgradeStrategy;
* @see org.springframework.web.socket.server.standard.TomcatRequestUpgradeStrategy
* @see org.springframework.web.socket.server.standard.UndertowRequestUpgradeStrategy
* @see org.springframework.web.socket.server.standard.GlassFishRequestUpgradeStrategy
* @see org.springframework.web.socket.server.standard.WebLogicRequestUpgradeStrategy
*/
public abstract class AbstractHandshakeHandler implements HandshakeHandler, Lifecycle {
@@ -75,8 +74,6 @@ public abstract class AbstractHandshakeHandler implements HandshakeHandler, Life
private static final boolean jettyWsPresent;
private static final boolean jetty10WsPresent;
private static final boolean undertowWsPresent;
private static final boolean glassfishWsPresent;
@@ -89,10 +86,8 @@ public abstract class AbstractHandshakeHandler implements HandshakeHandler, Life
ClassLoader classLoader = AbstractHandshakeHandler.class.getClassLoader();
tomcatWsPresent = ClassUtils.isPresent(
"org.apache.tomcat.websocket.server.WsHttpUpgradeHandler", classLoader);
jetty10WsPresent = ClassUtils.isPresent(
"org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer", classLoader);
jettyWsPresent = ClassUtils.isPresent(
"org.eclipse.jetty.websocket.server.WebSocketServerFactory", classLoader);
"org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer", classLoader);
undertowWsPresent = ClassUtils.isPresent(
"io.undertow.websockets.jsr.ServerWebSocketContainer", classLoader);
glassfishWsPresent = ClassUtils.isPresent(
@@ -140,9 +135,6 @@ public abstract class AbstractHandshakeHandler implements HandshakeHandler, Life
else if (jettyWsPresent) {
className = "org.springframework.web.socket.server.jetty.JettyRequestUpgradeStrategy";
}
else if (jetty10WsPresent) {
className = "org.springframework.web.socket.server.jetty.Jetty10RequestUpgradeStrategy";
}
else if (undertowWsPresent) {
className = "org.springframework.web.socket.server.standard.UndertowRequestUpgradeStrategy";
}

View File

@@ -16,7 +16,7 @@
package org.springframework.web.socket.server.support;
import javax.servlet.ServletContext;
import jakarta.servlet.ServletContext;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.socket.server.RequestUpgradeStrategy;

View File

@@ -21,7 +21,7 @@ import java.util.Collections;
import java.util.Enumeration;
import java.util.Map;
import javax.servlet.http.HttpSession;
import jakarta.servlet.http.HttpSession;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
@@ -128,7 +128,7 @@ public class HttpSessionHandshakeInterceptor implements HandshakeInterceptor {
/**
* Whether to allow the HTTP session to be created while accessing it.
* <p>By default set to {@code false}.
* @see javax.servlet.http.HttpServletRequest#getSession(boolean)
* @see jakarta.servlet.http.HttpServletRequest#getSession(boolean)
*/
public void setCreateSession(boolean createSession) {
this.createSession = createSession;

View File

@@ -16,8 +16,8 @@
package org.springframework.web.socket.server.support;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.context.Lifecycle;
import org.springframework.context.SmartLifecycle;

View File

@@ -22,11 +22,10 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 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.
@@ -25,7 +25,7 @@ import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.client.util.StringContentProvider;
import org.eclipse.jetty.client.util.StringRequestContent;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpMethod;
@@ -142,7 +142,7 @@ public class JettyXhrTransport extends AbstractXhrTransport implements Lifecycle
Request httpRequest = this.httpClient.newRequest(url).method(method);
addHttpHeaders(httpRequest, headers);
if (body != null) {
httpRequest.content(new StringContentProvider(body));
httpRequest.body(new StringRequestContent(body));
}
ContentResponse response;
try {
@@ -160,10 +160,12 @@ public class JettyXhrTransport extends AbstractXhrTransport implements Lifecycle
private static void addHttpHeaders(Request request, HttpHeaders headers) {
headers.forEach((key, values) -> {
for (String value : values) {
request.header(key, value);
}
request.headers(fields -> {
headers.forEach((key, values) -> {
for (String value : values) {
fields.add(key, value);
}
});
});
}

View File

@@ -27,8 +27,7 @@ import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

View File

@@ -18,10 +18,10 @@ package org.springframework.web.socket.sockjs.support;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.context.Lifecycle;
import org.springframework.http.server.ServerHttpRequest;

View File

@@ -21,8 +21,7 @@ import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;
import javax.servlet.ServletContext;
import jakarta.servlet.ServletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

View File

@@ -18,7 +18,7 @@ package org.springframework.web.socket.sockjs.transport.handler;
import java.util.Map;
import javax.servlet.ServletContext;
import jakarta.servlet.ServletContext;
import org.springframework.context.Lifecycle;
import org.springframework.http.server.ServerHttpRequest;

View File

@@ -26,7 +26,7 @@ import java.util.Map;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
import javax.servlet.ServletRequest;
import jakarta.servlet.ServletRequest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.ServerHttpAsyncRequestControl;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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.

View File

@@ -18,10 +18,9 @@ package org.springframework.web.socket;
import java.util.EnumSet;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.ServletContext;
import jakarta.servlet.DispatcherType;
import jakarta.servlet.Filter;
import jakarta.servlet.ServletContext;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.NetworkConnector;
import org.eclipse.jetty.server.Server;

View File

@@ -19,9 +19,8 @@ package org.springframework.web.socket;
import java.io.File;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.ServletContext;
import jakarta.servlet.Filter;
import jakarta.servlet.ServletContext;
import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;

View File

@@ -19,12 +19,6 @@ package org.springframework.web.socket;
import java.io.IOException;
import java.net.InetSocketAddress;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import io.undertow.Undertow;
import io.undertow.server.HttpHandler;
import io.undertow.servlet.api.DeploymentInfo;
@@ -34,6 +28,11 @@ import io.undertow.servlet.api.InstanceFactory;
import io.undertow.servlet.api.InstanceHandle;
import io.undertow.servlet.api.ServletInfo;
import io.undertow.websockets.jsr.WebSocketDeploymentInfo;
import jakarta.servlet.DispatcherType;
import jakarta.servlet.Filter;
import jakarta.servlet.Servlet;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import org.xnio.OptionMap;
import org.xnio.Xnio;

View File

@@ -16,8 +16,8 @@
package org.springframework.web.socket;
import javax.servlet.Filter;
import javax.servlet.ServletContext;
import jakarta.servlet.Filter;
import jakarta.servlet.ServletContext;
import org.springframework.web.context.WebApplicationContext;

View File

@@ -18,11 +18,10 @@ package org.springframework.web.socket.adapter.standard;
import java.nio.ByteBuffer;
import javax.websocket.DecodeException;
import javax.websocket.Decoder;
import javax.websocket.EncodeException;
import javax.websocket.Encoder;
import jakarta.websocket.DecodeException;
import jakarta.websocket.Decoder;
import jakarta.websocket.EncodeException;
import jakarta.websocket.Encoder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

View File

@@ -18,11 +18,10 @@ package org.springframework.web.socket.adapter.standard;
import java.net.URI;
import javax.websocket.CloseReason;
import javax.websocket.CloseReason.CloseCodes;
import javax.websocket.MessageHandler;
import javax.websocket.Session;
import jakarta.websocket.CloseReason;
import jakarta.websocket.CloseReason.CloseCodes;
import jakarta.websocket.MessageHandler;
import jakarta.websocket.Session;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

View File

@@ -19,8 +19,7 @@ package org.springframework.web.socket.adapter.standard;
import java.util.HashMap;
import java.util.Map;
import javax.websocket.Session;
import jakarta.websocket.Session;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

View File

@@ -16,36 +16,14 @@
package org.springframework.web.socket.client.jetty;
import java.net.URI;
import java.util.Arrays;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.util.CollectionUtils;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketHttpHeaders;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.adapter.jetty.JettyWebSocketHandlerAdapter;
import org.springframework.web.socket.adapter.jetty.JettyWebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link JettyWebSocketClient}.
*
* @author Rossen Stoyanchev
*/
public class JettyWebSocketClientTests {
/* TODO: complete upgrade to Jetty 11
private JettyWebSocketClient client;
private TestJettyWebSocketServer server;
@@ -113,12 +91,12 @@ public class JettyWebSocketClientTests {
connector.setPort(0);
this.server.addConnector(connector);
this.server.setHandler(new org.eclipse.jetty.websocket.server.WebSocketHandler() {
this.server.setHandler(new WebSocketUpgradeHandler() {
@Override
public void configure(WebSocketServletFactory factory) {
factory.setCreator(new WebSocketCreator() {
public void configure(JettyWebSocketServletFactory factory) {
factory.setCreator(new JettyWebSocketCreator() {
@Override
public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp) {
public Object createWebSocket(JettyServerUpgradeRequest req, JettyServerUpgradeResponse resp) {
if (!CollectionUtils.isEmpty(req.getSubProtocols())) {
resp.setAcceptedSubProtocol(req.getSubProtocols().get(0));
}
@@ -142,5 +120,6 @@ public class JettyWebSocketClientTests {
return ((ServerConnector) this.server.getConnectors()[0]).getLocalPort();
}
}
*/
}

View File

@@ -22,10 +22,9 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.websocket.ClientEndpointConfig;
import javax.websocket.Endpoint;
import javax.websocket.WebSocketContainer;
import jakarta.websocket.ClientEndpointConfig;
import jakarta.websocket.Endpoint;
import jakarta.websocket.WebSocketContainer;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;

View File

@@ -16,13 +16,12 @@
package org.springframework.web.socket.server.standard;
import javax.servlet.ServletContext;
import javax.websocket.Endpoint;
import javax.websocket.EndpointConfig;
import javax.websocket.Session;
import javax.websocket.server.ServerContainer;
import javax.websocket.server.ServerEndpoint;
import jakarta.servlet.ServletContext;
import jakarta.websocket.Endpoint;
import jakarta.websocket.EndpointConfig;
import jakarta.websocket.Session;
import jakarta.websocket.server.ServerContainer;
import jakarta.websocket.server.ServerEndpoint;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -56,7 +55,7 @@ public class ServerEndpointExporterTests {
this.serverContainer = mock(ServerContainer.class);
this.servletContext = new MockServletContext();
this.servletContext.setAttribute("javax.websocket.server.ServerContainer", this.serverContainer);
this.servletContext.setAttribute("jakarta.websocket.server.ServerContainer", this.serverContainer);
this.webAppContext = new AnnotationConfigWebApplicationContext();
this.webAppContext.register(Config.class);
@@ -129,7 +128,7 @@ public class ServerEndpointExporterTests {
public void addServerEndpointConfigBeanWithExplicitServerContainer() throws Exception {
ServerEndpointRegistration endpointRegistration = new ServerEndpointRegistration("/dummy", new DummyEndpoint());
this.webAppContext.getBeanFactory().registerSingleton("dummyEndpoint", endpointRegistration);
this.servletContext.removeAttribute("javax.websocket.server.ServerContainer");
this.servletContext.removeAttribute("jakarta.websocket.server.ServerContainer");
this.exporter.setServerContainer(this.serverContainer);
this.exporter.setApplicationContext(this.webAppContext);

View File

@@ -16,10 +16,9 @@
package org.springframework.web.socket.server.standard;
import javax.websocket.Endpoint;
import javax.websocket.EndpointConfig;
import javax.websocket.Session;
import jakarta.websocket.Endpoint;
import jakarta.websocket.EndpointConfig;
import jakarta.websocket.Session;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;

View File

@@ -16,8 +16,7 @@
package org.springframework.web.socket.server.standard;
import javax.websocket.server.ServerEndpoint;
import jakarta.websocket.server.ServerEndpoint;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

View File

@@ -20,8 +20,7 @@ import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import javax.servlet.ServletException;
import jakarta.servlet.ServletException;
import org.junit.jupiter.api.Test;
import org.springframework.http.server.ServerHttpRequest;

View File

@@ -29,15 +29,14 @@ import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.function.BooleanSupplier;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.jupiter.api.AfterEach;

View File

@@ -20,9 +20,8 @@ import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;