diff --git a/spring-web/src/main/java/org/springframework/http/client/OkHttpAsyncClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/OkHttpAsyncClientHttpRequest.java deleted file mode 100644 index 21350d6cc8..0000000000 --- a/spring-web/src/main/java/org/springframework/http/client/OkHttpAsyncClientHttpRequest.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2002-2016 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.http.client; - -import java.io.IOException; -import java.net.URI; - -import com.squareup.okhttp.Call; -import com.squareup.okhttp.Callback; -import com.squareup.okhttp.OkHttpClient; -import com.squareup.okhttp.Request; -import com.squareup.okhttp.Response; - -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.SettableListenableFuture; - -/** - * {@link AsyncClientHttpRequest} implementation based on OkHttp 2.x. - * - *

Created via the {@link OkHttpClientHttpRequestFactory}. - * - * @author Luciano Leggieri - * @author Arjen Poutsma - * @since 4.3 - * @see org.springframework.http.client.OkHttp3AsyncClientHttpRequest - * @deprecated as of Spring 5.0, in favor of OkHttp 3.x - */ -@Deprecated -class OkHttpAsyncClientHttpRequest extends AbstractBufferingAsyncClientHttpRequest { - - private final OkHttpClient client; - - private final URI uri; - - private final HttpMethod method; - - - public OkHttpAsyncClientHttpRequest(OkHttpClient client, URI uri, HttpMethod method) { - this.client = client; - this.uri = uri; - this.method = method; - } - - - @Override - public HttpMethod getMethod() { - return this.method; - } - - @Override - public URI getURI() { - return this.uri; - } - - @Override - protected ListenableFuture executeInternal(HttpHeaders headers, byte[] content) - throws IOException { - - Request request = OkHttpClientHttpRequestFactory.buildRequest(headers, content, this.uri, this.method); - return new OkHttpListenableFuture(this.client.newCall(request)); - } - - - @Deprecated - private static class OkHttpListenableFuture extends SettableListenableFuture { - - private final Call call; - - public OkHttpListenableFuture(Call call) { - this.call = call; - this.call.enqueue(new Callback() { - @Override - public void onResponse(Response response) { - set(new OkHttpClientHttpResponse(response)); - } - @Override - public void onFailure(Request request, IOException ex) { - setException(ex); - } - }); - } - - @Override - protected void interruptTask() { - this.call.cancel(); - } - } - -} diff --git a/spring-web/src/main/java/org/springframework/http/client/OkHttpClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/OkHttpClientHttpRequest.java deleted file mode 100644 index b1c197e03d..0000000000 --- a/spring-web/src/main/java/org/springframework/http/client/OkHttpClientHttpRequest.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2002-2016 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.http.client; - -import java.io.IOException; -import java.net.URI; - -import com.squareup.okhttp.OkHttpClient; -import com.squareup.okhttp.Request; - -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; - -/** - * {@link ClientHttpRequest} implementation based on OkHttp 2.x. - * - *

Created via the {@link OkHttpClientHttpRequestFactory}. - * - * @author Luciano Leggieri - * @author Arjen Poutsma - * @since 4.2 - * @see org.springframework.http.client.OkHttp3ClientHttpRequest - * @deprecated as of Spring 5.0, in favor of OkHttp 3.x - */ -@Deprecated -class OkHttpClientHttpRequest extends AbstractBufferingClientHttpRequest { - - private final OkHttpClient client; - - private final URI uri; - - private final HttpMethod method; - - - public OkHttpClientHttpRequest(OkHttpClient client, URI uri, HttpMethod method) { - this.client = client; - this.uri = uri; - this.method = method; - } - - - @Override - public HttpMethod getMethod() { - return this.method; - } - - @Override - public URI getURI() { - return this.uri; - } - - - @Override - protected ClientHttpResponse executeInternal(HttpHeaders headers, byte[] content) throws IOException { - Request request = OkHttpClientHttpRequestFactory.buildRequest(headers, content, this.uri, this.method); - return new OkHttpClientHttpResponse(this.client.newCall(request).execute()); - } - -} diff --git a/spring-web/src/main/java/org/springframework/http/client/OkHttpClientHttpRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/OkHttpClientHttpRequestFactory.java deleted file mode 100644 index ce9e8c39ad..0000000000 --- a/spring-web/src/main/java/org/springframework/http/client/OkHttpClientHttpRequestFactory.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2002-2016 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.http.client; - -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URI; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import com.squareup.okhttp.OkHttpClient; -import com.squareup.okhttp.Request; -import com.squareup.okhttp.RequestBody; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * {@link ClientHttpRequestFactory} implementation that uses - * OkHttp 2.x to create requests. - * - * @author Luciano Leggieri - * @author Arjen Poutsma - * @since 4.2 - * @see org.springframework.http.client.OkHttp3ClientHttpRequestFactory - * @deprecated as of Spring 5.0, in favor of OkHttp 3.x - */ -@Deprecated -public class OkHttpClientHttpRequestFactory - implements ClientHttpRequestFactory, AsyncClientHttpRequestFactory, DisposableBean { - - private final OkHttpClient client; - - private final boolean defaultClient; - - - /** - * Create a factory with a default {@link OkHttpClient} instance. - */ - public OkHttpClientHttpRequestFactory() { - this.client = new OkHttpClient(); - this.defaultClient = true; - } - - /** - * Create a factory with the given {@link OkHttpClient} instance. - * @param client the client to use - */ - public OkHttpClientHttpRequestFactory(OkHttpClient client) { - Assert.notNull(client, "OkHttpClient must not be null"); - this.client = client; - this.defaultClient = false; - } - - - /** - * Sets the underlying read timeout in milliseconds. - * A value of 0 specifies an infinite timeout. - * @see OkHttpClient#setReadTimeout(long, TimeUnit) - */ - public void setReadTimeout(int readTimeout) { - this.client.setReadTimeout(readTimeout, TimeUnit.MILLISECONDS); - } - - /** - * Sets the underlying write timeout in milliseconds. - * A value of 0 specifies an infinite timeout. - * @see OkHttpClient#setWriteTimeout(long, TimeUnit) - */ - public void setWriteTimeout(int writeTimeout) { - this.client.setWriteTimeout(writeTimeout, TimeUnit.MILLISECONDS); - } - - /** - * Sets the underlying connect timeout in milliseconds. - * A value of 0 specifies an infinite timeout. - * @see OkHttpClient#setConnectTimeout(long, TimeUnit) - */ - public void setConnectTimeout(int connectTimeout) { - this.client.setConnectTimeout(connectTimeout, TimeUnit.MILLISECONDS); - } - - - @Override - public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) { - return new OkHttpClientHttpRequest(this.client, uri, httpMethod); - } - - @Override - public AsyncClientHttpRequest createAsyncRequest(URI uri, HttpMethod httpMethod) { - return new OkHttpAsyncClientHttpRequest(this.client, uri, httpMethod); - } - - - @Override - public void destroy() throws IOException { - if (this.defaultClient) { - // Clean up the client if we created it in the constructor - if (this.client.getCache() != null) { - this.client.getCache().close(); - } - this.client.getDispatcher().getExecutorService().shutdown(); - } - } - - - static Request buildRequest(HttpHeaders headers, byte[] content, URI uri, HttpMethod method) - throws MalformedURLException { - - com.squareup.okhttp.MediaType contentType = getContentType(headers); - RequestBody body = (content.length > 0 || - com.squareup.okhttp.internal.http.HttpMethod.requiresRequestBody(method.name()) ? - RequestBody.create(contentType, content) : null); - - Request.Builder builder = new Request.Builder().url(uri.toURL()).method(method.name(), body); - for (Map.Entry> entry : headers.entrySet()) { - String headerName = entry.getKey(); - for (String headerValue : entry.getValue()) { - builder.addHeader(headerName, headerValue); - } - } - return builder.build(); - } - - private static com.squareup.okhttp.MediaType getContentType(HttpHeaders headers) { - String rawContentType = headers.getFirst(HttpHeaders.CONTENT_TYPE); - return (StringUtils.hasText(rawContentType) ? - com.squareup.okhttp.MediaType.parse(rawContentType) : null); - } - -} diff --git a/spring-web/src/main/java/org/springframework/http/client/OkHttpClientHttpResponse.java b/spring-web/src/main/java/org/springframework/http/client/OkHttpClientHttpResponse.java deleted file mode 100644 index 9d5e2a0e98..0000000000 --- a/spring-web/src/main/java/org/springframework/http/client/OkHttpClientHttpResponse.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2002-2016 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.http.client; - -import java.io.IOException; -import java.io.InputStream; - -import com.squareup.okhttp.Response; - -import org.springframework.http.HttpHeaders; -import org.springframework.util.Assert; - -/** - * {@link ClientHttpResponse} implementation based on OkHttp 2.x. - * - * @author Luciano Leggieri - * @author Arjen Poutsma - * @since 4.2 - * @see org.springframework.http.client.OkHttp3ClientHttpResponse - * @deprecated as of Spring 5.0, in favor of OkHttp 3.x - */ -@Deprecated -class OkHttpClientHttpResponse extends AbstractClientHttpResponse { - - private final Response response; - - private HttpHeaders headers; - - - public OkHttpClientHttpResponse(Response response) { - Assert.notNull(response, "Response must not be null"); - this.response = response; - } - - - @Override - public int getRawStatusCode() { - return this.response.code(); - } - - @Override - public String getStatusText() { - return this.response.message(); - } - - @Override - public InputStream getBody() throws IOException { - return this.response.body().byteStream(); - } - - @Override - public HttpHeaders getHeaders() { - if (this.headers == null) { - HttpHeaders headers = new HttpHeaders(); - for (String headerName : this.response.headers().names()) { - for (String headerValue : this.response.headers(headerName)) { - headers.add(headerName, headerValue); - } - } - this.headers = headers; - } - return this.headers; - } - - @Override - public void close() { - try { - this.response.body().close(); - } - catch (IOException ex) { - // ignore - } - } - -} diff --git a/spring-web/src/test/java/org/springframework/http/client/OkHttpAsyncClientHttpRequestFactoryTests.java b/spring-web/src/test/java/org/springframework/http/client/OkHttpAsyncClientHttpRequestFactoryTests.java deleted file mode 100644 index b07a33f211..0000000000 --- a/spring-web/src/test/java/org/springframework/http/client/OkHttpAsyncClientHttpRequestFactoryTests.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2002-2016 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.http.client; - -import org.junit.Test; - -import org.springframework.http.HttpMethod; - -/** - * @author Luciano Leggieri - */ -public class OkHttpAsyncClientHttpRequestFactoryTests extends AbstractAsyncHttpRequestFactoryTestCase { - - @Override - @SuppressWarnings("deprecation") - protected AsyncClientHttpRequestFactory createRequestFactory() { - return new OkHttpClientHttpRequestFactory(); - } - - @Override - @Test - public void httpMethods() throws Exception { - super.httpMethods(); - assertHttpMethod("patch", HttpMethod.PATCH); - } - -} diff --git a/spring-web/src/test/java/org/springframework/http/client/OkHttpClientHttpRequestFactoryTests.java b/spring-web/src/test/java/org/springframework/http/client/OkHttpClientHttpRequestFactoryTests.java deleted file mode 100644 index acfb0fe28d..0000000000 --- a/spring-web/src/test/java/org/springframework/http/client/OkHttpClientHttpRequestFactoryTests.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2002-2016 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.http.client; - -import org.junit.Test; - -import org.springframework.http.HttpMethod; - -/** - * @author Luciano Leggieri - */ -public class OkHttpClientHttpRequestFactoryTests extends AbstractHttpRequestFactoryTestCase { - - @Override - @SuppressWarnings("deprecation") - protected ClientHttpRequestFactory createRequestFactory() { - return new OkHttpClientHttpRequestFactory(); - } - - @Override - @Test - public void httpMethods() throws Exception { - super.httpMethods(); - assertHttpMethod("patch", HttpMethod.PATCH); - } - -} diff --git a/spring-web/src/test/java/org/springframework/web/client/RestTemplateIntegrationTests.java b/spring-web/src/test/java/org/springframework/web/client/RestTemplateIntegrationTests.java index 28f1d71d3c..0dea59e6cb 100644 --- a/spring-web/src/test/java/org/springframework/web/client/RestTemplateIntegrationTests.java +++ b/spring-web/src/test/java/org/springframework/web/client/RestTemplateIntegrationTests.java @@ -78,16 +78,17 @@ public class RestTemplateIntegrationTests extends AbstractMockWebServerTestCase new SimpleClientHttpRequestFactory(), new HttpComponentsClientHttpRequestFactory(), new Netty4ClientHttpRequestFactory(), - new OkHttp3ClientHttpRequestFactory(), - new org.springframework.http.client.OkHttpClientHttpRequestFactory() + new OkHttp3ClientHttpRequestFactory() ); } + @Before - public void setUpClient() { + public void setupClient() { this.template = new RestTemplate(this.clientHttpRequestFactory); } + @Test public void getString() { String s = template.getForObject(baseUrl + "/{method}", String.class, "get"); diff --git a/spring-web/src/test/java/org/springframework/web/client/RestTemplateTests.java b/spring-web/src/test/java/org/springframework/web/client/RestTemplateTests.java index f153174f57..a1daae3806 100644 --- a/spring-web/src/test/java/org/springframework/web/client/RestTemplateTests.java +++ b/spring-web/src/test/java/org/springframework/web/client/RestTemplateTests.java @@ -44,17 +44,8 @@ import org.springframework.http.converter.GenericHttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.web.util.DefaultUriBuilderFactory; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.fail; -import static org.mockito.BDDMockito.any; -import static org.mockito.BDDMockito.eq; -import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.mock; -import static org.mockito.BDDMockito.verify; -import static org.mockito.BDDMockito.willThrow; +import static org.junit.Assert.*; +import static org.mockito.BDDMockito.*; /** * @author Arjen Poutsma @@ -76,8 +67,9 @@ public class RestTemplateTests { @SuppressWarnings("rawtypes") private HttpMessageConverter converter; + @Before - public void setUp() { + public void setup() { requestFactory = mock(ClientHttpRequestFactory.class); request = mock(ClientHttpRequest.class); response = mock(ClientHttpResponse.class); @@ -88,6 +80,7 @@ public class RestTemplateTests { template.setErrorHandler(errorHandler); } + @Test public void varArgsTemplateVariables() throws Exception { given(requestFactory.createRequest(new URI("http://example.com/hotels/42/bookings/21"), HttpMethod.GET)) @@ -816,4 +809,5 @@ public class RestTemplateTests { verify(response).close(); } + } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/adapter/jetty/JettyWebSocketSession.java b/spring-websocket/src/main/java/org/springframework/web/socket/adapter/jetty/JettyWebSocketSession.java index 092da8d80b..f36ebe5bac 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/adapter/jetty/JettyWebSocketSession.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/adapter/jetty/JettyWebSocketSession.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -17,7 +17,6 @@ package org.springframework.web.socket.adapter.jetty; import java.io.IOException; -import java.lang.reflect.Method; import java.net.InetSocketAddress; import java.net.URI; import java.security.Principal; @@ -28,15 +27,12 @@ import java.util.Map; import org.eclipse.jetty.websocket.api.RemoteEndpoint; import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.UpgradeRequest; -import org.eclipse.jetty.websocket.api.UpgradeResponse; import org.eclipse.jetty.websocket.api.WebSocketException; import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig; import org.springframework.http.HttpHeaders; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; -import org.springframework.util.ReflectionUtils; import org.springframework.web.socket.BinaryMessage; import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.PingMessage; @@ -47,7 +43,7 @@ import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.adapter.AbstractWebSocketSession; /** - * A {@link WebSocketSession} for use with the Jetty 9.3/9.4 WebSocket API. + * A {@link WebSocketSession} for use with the Jetty 9.4 WebSocket API. * * @author Phillip Webb * @author Rossen Stoyanchev @@ -57,36 +53,6 @@ import org.springframework.web.socket.adapter.AbstractWebSocketSession; */ public class JettyWebSocketSession extends AbstractWebSocketSession { - // As of Jetty 9.4, UpgradeRequest and UpgradeResponse are interfaces instead of classes - private static final boolean directInterfaceCalls; - - private static Method getUpgradeRequest; - private static Method getUpgradeResponse; - private static Method getRequestURI; - private static Method getHeaders; - private static Method getUserPrincipal; - private static Method getAcceptedSubProtocol; - private static Method getExtensions; - - static { - directInterfaceCalls = UpgradeRequest.class.isInterface(); - if (!directInterfaceCalls) { - try { - getUpgradeRequest = Session.class.getMethod("getUpgradeRequest"); - getUpgradeResponse = Session.class.getMethod("getUpgradeResponse"); - getRequestURI = UpgradeRequest.class.getMethod("getRequestURI"); - getHeaders = UpgradeRequest.class.getMethod("getHeaders"); - getUserPrincipal = UpgradeRequest.class.getMethod("getUserPrincipal"); - getAcceptedSubProtocol = UpgradeResponse.class.getMethod("getAcceptedSubProtocol"); - getExtensions = UpgradeResponse.class.getMethod("getExtensions"); - } - catch (NoSuchMethodException ex) { - throw new IllegalStateException("Incompatible Jetty API", ex); - } - } - } - - private String id; private URI uri; @@ -201,31 +167,23 @@ public class JettyWebSocketSession extends AbstractWebSocketSession { @Override public void initializeNativeSession(Session session) { super.initializeNativeSession(session); - if (directInterfaceCalls) { - initializeJettySessionDirectly(session); - } - else { - initializeJettySessionReflectively(session); - } - } - private void initializeJettySessionDirectly(Session session) { this.id = ObjectUtils.getIdentityHexString(getNativeSession()); this.uri = session.getUpgradeRequest().getRequestURI(); - this.headers = new HttpHeaders(); - this.headers.putAll(session.getUpgradeRequest().getHeaders()); - this.headers = HttpHeaders.readOnlyHttpHeaders(this.headers); + HttpHeaders headers = new HttpHeaders(); + headers.putAll(session.getUpgradeRequest().getHeaders()); + this.headers = HttpHeaders.readOnlyHttpHeaders(headers); this.acceptedProtocol = session.getUpgradeResponse().getAcceptedSubProtocol(); List jettyExtensions = session.getUpgradeResponse().getExtensions(); if (!CollectionUtils.isEmpty(jettyExtensions)) { - this.extensions = new ArrayList<>(jettyExtensions.size()); + List extensions = new ArrayList<>(jettyExtensions.size()); for (ExtensionConfig jettyExtension : jettyExtensions) { - this.extensions.add(new WebSocketExtension(jettyExtension.getName(), jettyExtension.getParameters())); + extensions.add(new WebSocketExtension(jettyExtension.getName(), jettyExtension.getParameters())); } - this.extensions = Collections.unmodifiableList(this.extensions); + this.extensions = Collections.unmodifiableList(extensions); } else { this.extensions = Collections.emptyList(); @@ -236,37 +194,6 @@ public class JettyWebSocketSession extends AbstractWebSocketSession { } } - @SuppressWarnings("unchecked") - private void initializeJettySessionReflectively(Session session) { - Object request = ReflectionUtils.invokeMethod(getUpgradeRequest, session); - Object response = ReflectionUtils.invokeMethod(getUpgradeResponse, session); - - this.id = ObjectUtils.getIdentityHexString(getNativeSession()); - this.uri = (URI) ReflectionUtils.invokeMethod(getRequestURI, request); - - this.headers = new HttpHeaders(); - this.headers.putAll((Map>) ReflectionUtils.invokeMethod(getHeaders, request)); - this.headers = HttpHeaders.readOnlyHttpHeaders(this.headers); - - this.acceptedProtocol = (String) ReflectionUtils.invokeMethod(getAcceptedSubProtocol, response); - - List extensions = (List) ReflectionUtils.invokeMethod(getExtensions, response); - if (!CollectionUtils.isEmpty(extensions)) { - this.extensions = new ArrayList<>(extensions.size()); - for (ExtensionConfig extension : extensions) { - this.extensions.add(new WebSocketExtension(extension.getName(), extension.getParameters())); - } - this.extensions = Collections.unmodifiableList(this.extensions); - } - else { - this.extensions = Collections.emptyList(); - } - - if (this.user == null) { - this.user = (Principal) ReflectionUtils.invokeMethod(getUserPrincipal, request); - } - } - @Override protected void sendTextMessage(TextMessage message) throws IOException { diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/JettyRequestUpgradeStrategy.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/JettyRequestUpgradeStrategy.java index 45963cd830..bde7859e32 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/JettyRequestUpgradeStrategy.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/JettyRequestUpgradeStrategy.java @@ -41,7 +41,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.util.ClassUtils; import org.springframework.util.CollectionUtils; import org.springframework.web.context.ServletContextAware; import org.springframework.web.socket.WebSocketExtension; @@ -53,8 +52,8 @@ import org.springframework.web.socket.server.HandshakeFailureException; import org.springframework.web.socket.server.RequestUpgradeStrategy; /** - * A {@link RequestUpgradeStrategy} for use with Jetty 9.3 and 9.4. Based on - * Jetty's internal {@code org.eclipse.jetty.websocket.server.WebSocketHandler} class. + * A {@link RequestUpgradeStrategy} for use with Jetty 9.4. Based on Jetty's + * internal {@code org.eclipse.jetty.websocket.server.WebSocketHandler} class. * * @author Phillip Webb * @author Rossen Stoyanchev @@ -68,11 +67,9 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Serv new NamedThreadLocal<>("WebSocketHandlerContainer"); - // Configurable factory adapter due to Jetty 9.3.15+ API differences: - // using WebSocketServerFactory(ServletContext) as a version indicator - private final WebSocketServerFactoryAdapter factoryAdapter = - (ClassUtils.hasConstructor(WebSocketServerFactory.class, ServletContext.class) ? - new ModernJettyWebSocketServerFactoryAdapter() : new LegacyJettyWebSocketServerFactoryAdapter()); + private WebSocketPolicy policy; + + private WebSocketServerFactory factory; private ServletContext servletContext; @@ -86,7 +83,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Serv * its default constructor thus using a default {@link WebSocketPolicy}. */ public JettyRequestUpgradeStrategy() { - this.factoryAdapter.setPolicy(WebSocketPolicy.newServerPolicy()); + this.policy = WebSocketPolicy.newServerPolicy(); } /** @@ -97,7 +94,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Serv */ public JettyRequestUpgradeStrategy(WebSocketPolicy policy) { Assert.notNull(policy, "WebSocketPolicy must not be null"); - this.factoryAdapter.setPolicy(policy); + this.policy = policy; } /** @@ -106,7 +103,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Serv */ public JettyRequestUpgradeStrategy(WebSocketServerFactory factory) { Assert.notNull(factory, "WebSocketServerFactory must not be null"); - this.factoryAdapter.setFactory(factory); + this.factory = factory; } @@ -120,7 +117,20 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Serv if (!isRunning()) { this.running = true; try { - this.factoryAdapter.start(); + if (this.factory == null) { + this.factory = new WebSocketServerFactory(servletContext, this.policy); + } + this.factory.setCreator(new WebSocketCreator() { + @Override + public Object createWebSocket(ServletUpgradeRequest request, ServletUpgradeResponse response) { + WebSocketHandlerContainer container = containerHolder.get(); + Assert.state(container != null, "Expected WebSocketHandlerContainer"); + response.setAcceptedSubProtocol(container.getSelectedProtocol()); + response.setExtensions(container.getExtensionConfigs()); + return container.getHandler(); + } + }); + this.factory.start(); } catch (Throwable ex) { throw new IllegalStateException("Unable to start Jetty WebSocketServerFactory", ex); @@ -132,11 +142,13 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Serv public void stop() { if (isRunning()) { this.running = false; - try { - this.factoryAdapter.stop(); - } - catch (Throwable ex) { - throw new IllegalStateException("Unable to stop Jetty WebSocketServerFactory", ex); + if (this.factory != null) { + try { + this.factory.stop(); + } + catch (Throwable ex) { + throw new IllegalStateException("Unable to stop Jetty WebSocketServerFactory", ex); + } } } } @@ -161,7 +173,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Serv } private List buildWebSocketExtensions() { - Set names = this.factoryAdapter.getFactory().getExtensionFactory().getExtensionNames(); + Set names = this.factory.getExtensionFactory().getExtensionNames(); List result = new ArrayList<>(names.size()); for (String name : names) { result.add(new WebSocketExtension(name)); @@ -180,8 +192,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Serv Assert.isInstanceOf(ServletServerHttpResponse.class, response, "ServletServerHttpResponse required"); HttpServletResponse servletResponse = ((ServletServerHttpResponse) response).getServletResponse(); - Assert.isTrue(this.factoryAdapter.getFactory().isUpgradeRequest(servletRequest, servletResponse), - "Not a WebSocket handshake"); + Assert.isTrue(this.factory.isUpgradeRequest(servletRequest, servletResponse), "Not a WebSocket handshake"); JettyWebSocketSession session = new JettyWebSocketSession(attributes, user); JettyWebSocketHandlerAdapter handlerAdapter = new JettyWebSocketHandlerAdapter(wsHandler, session); @@ -191,7 +202,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Serv try { containerHolder.set(container); - this.factoryAdapter.getFactory().acceptWebSocket(servletRequest, servletResponse); + this.factory.acceptWebSocket(servletRequest, servletResponse); } catch (IOException ex) { throw new HandshakeFailureException( @@ -240,93 +251,4 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Serv } } - - private static abstract class WebSocketServerFactoryAdapter { - - private WebSocketPolicy policy; - - private WebSocketServerFactory factory; - - public void setPolicy(WebSocketPolicy policy) { - this.policy = policy; - } - - public void setFactory(WebSocketServerFactory factory) { - this.factory = factory; - } - - public WebSocketServerFactory getFactory() { - return this.factory; - } - - public void start() throws Exception { - if (this.factory == null) { - this.factory = createFactory(this.policy); - } - this.factory.setCreator(new WebSocketCreator() { - @Override - public Object createWebSocket(ServletUpgradeRequest request, ServletUpgradeResponse response) { - WebSocketHandlerContainer container = containerHolder.get(); - Assert.state(container != null, "Expected WebSocketHandlerContainer"); - response.setAcceptedSubProtocol(container.getSelectedProtocol()); - response.setExtensions(container.getExtensionConfigs()); - return container.getHandler(); - } - }); - startFactory(this.factory); - } - - public void stop() throws Exception { - if (this.factory != null) { - stopFactory(this.factory); - } - } - - protected abstract WebSocketServerFactory createFactory(WebSocketPolicy policy) throws Exception; - - protected abstract void startFactory(WebSocketServerFactory factory) throws Exception; - - protected abstract void stopFactory(WebSocketServerFactory factory) throws Exception; - } - - - // Jetty 9.3.15+ - private class ModernJettyWebSocketServerFactoryAdapter extends WebSocketServerFactoryAdapter { - - @Override - protected WebSocketServerFactory createFactory(WebSocketPolicy policy) throws Exception { - return new WebSocketServerFactory(servletContext, policy); - } - - @Override - protected void startFactory(WebSocketServerFactory factory) throws Exception { - factory.start(); - } - - @Override - protected void stopFactory(WebSocketServerFactory factory) throws Exception { - factory.stop(); - } - } - - - // Jetty <9.3.15 - private class LegacyJettyWebSocketServerFactoryAdapter extends WebSocketServerFactoryAdapter { - - @Override - protected WebSocketServerFactory createFactory(WebSocketPolicy policy) throws Exception { - return WebSocketServerFactory.class.getConstructor(WebSocketPolicy.class).newInstance(policy); - } - - @Override - protected void startFactory(WebSocketServerFactory factory) throws Exception { - WebSocketServerFactory.class.getMethod("init", ServletContext.class).invoke(factory, servletContext); - } - - @Override - protected void stopFactory(WebSocketServerFactory factory) throws Exception { - WebSocketServerFactory.class.getMethod("cleanup").invoke(factory); - } - } - }