Merge branch '3.2.x' into master
Conflicts: gradle.properties spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheManagerFactoryBean.java spring-core/src/main/java/org/springframework/core/convert/support/StringToEnumConverterFactory.java spring-core/src/main/java/org/springframework/core/env/ReadOnlySystemAttributesMap.java spring-jdbc/src/main/java/org/springframework/jdbc/datasource/LazyConnectionDataSourceProxy.java spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/AbstractLobHandler.java spring-web/src/main/java/org/springframework/http/client/BufferingClientHttpRequestWrapper.java spring-web/src/main/java/org/springframework/http/client/SimpleBufferingClientHttpRequest.java spring-web/src/main/java/org/springframework/http/converter/BufferedImageHttpMessageConverter.java spring-web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -125,7 +125,9 @@ public enum HttpStatus {
|
||||
/**
|
||||
* {@code 302 Moved Temporarily}.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc1945#section-9.3">HTTP/1.0</a>
|
||||
* @deprecated In favor of {@link #FOUND} which will be returned from {@code HttpStatus.valueOf(302)}
|
||||
*/
|
||||
@Deprecated
|
||||
MOVED_TEMPORARILY(302, "Moved Temporarily"),
|
||||
/**
|
||||
* {@code 303 See Other}.
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.http;
|
||||
|
||||
/**
|
||||
* Exception thrown from {@link MediaType#parseMediaType(String)} in case of
|
||||
* encountering an invalid media type specification String.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.2.2
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class InvalidMediaTypeException extends IllegalArgumentException {
|
||||
|
||||
private String mediaType;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new InvalidMediaTypeException for the given media type.
|
||||
* @param mediaType the offending media type
|
||||
* @param msg a detail message indicating the invalid part
|
||||
*/
|
||||
public InvalidMediaTypeException(String mediaType, String msg) {
|
||||
super("Invalid media type \"" + mediaType + "\": " + msg);
|
||||
this.mediaType = mediaType;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the offending media type.
|
||||
*/
|
||||
public String getMediaType() {
|
||||
return this.mediaType;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.http;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.UnsupportedCharsetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.Collection;
|
||||
@@ -321,8 +322,8 @@ public class MediaType implements Comparable<MediaType> {
|
||||
* @throws IllegalArgumentException if any of the parameters contain illegal characters
|
||||
*/
|
||||
public MediaType(String type, String subtype, Map<String, String> parameters) {
|
||||
Assert.hasLength(type, "'type' must not be empty");
|
||||
Assert.hasLength(subtype, "'subtype' must not be empty");
|
||||
Assert.hasLength(type, "type must not be empty");
|
||||
Assert.hasLength(subtype, "subtype must not be empty");
|
||||
checkToken(type);
|
||||
checkToken(subtype);
|
||||
this.type = type.toLowerCase(Locale.ENGLISH);
|
||||
@@ -347,11 +348,11 @@ public class MediaType implements Comparable<MediaType> {
|
||||
* @throws IllegalArgumentException in case of illegal characters
|
||||
* @see <a href="http://tools.ietf.org/html/rfc2616#section-2.2">HTTP 1.1, section 2.2</a>
|
||||
*/
|
||||
private void checkToken(String s) {
|
||||
for (int i=0; i < s.length(); i++ ) {
|
||||
char ch = s.charAt(i);
|
||||
private void checkToken(String token) {
|
||||
for (int i=0; i < token.length(); i++ ) {
|
||||
char ch = token.charAt(i);
|
||||
if (!TOKEN.get(ch)) {
|
||||
throw new IllegalArgumentException("Invalid token character '" + ch + "' in token \"" + s + "\"");
|
||||
throw new IllegalArgumentException("Invalid token character '" + ch + "' in token \"" + token + "\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -681,7 +682,7 @@ public class MediaType implements Comparable<MediaType> {
|
||||
* Parse the given String into a single {@code MediaType}.
|
||||
* @param mediaType the string to parse
|
||||
* @return the media type
|
||||
* @throws IllegalArgumentException if the string cannot be parsed
|
||||
* @throws InvalidMediaTypeException if the string cannot be parsed
|
||||
*/
|
||||
public static MediaType parseMediaType(String mediaType) {
|
||||
Assert.hasLength(mediaType, "'mediaType' must not be empty");
|
||||
@@ -694,15 +695,15 @@ public class MediaType implements Comparable<MediaType> {
|
||||
}
|
||||
int subIndex = fullType.indexOf('/');
|
||||
if (subIndex == -1) {
|
||||
throw new IllegalArgumentException("\"" + mediaType + "\" does not contain '/'");
|
||||
throw new InvalidMediaTypeException(mediaType, "does not contain '/'");
|
||||
}
|
||||
if (subIndex == fullType.length() - 1) {
|
||||
throw new IllegalArgumentException("\"" + mediaType + "\" does not contain subtype after '/'");
|
||||
throw new InvalidMediaTypeException(mediaType, "does not contain subtype after '/'");
|
||||
}
|
||||
String type = fullType.substring(0, subIndex);
|
||||
String subtype = fullType.substring(subIndex + 1, fullType.length());
|
||||
if (WILDCARD_TYPE.equals(type) && !WILDCARD_TYPE.equals(subtype)) {
|
||||
throw new IllegalArgumentException("A wildcard type is legal only in '*/*' (all media types).");
|
||||
throw new InvalidMediaTypeException(mediaType, "wildcard type is legal only in '*/*' (all media types)");
|
||||
}
|
||||
|
||||
Map<String, String> parameters = null;
|
||||
@@ -719,7 +720,15 @@ public class MediaType implements Comparable<MediaType> {
|
||||
}
|
||||
}
|
||||
|
||||
return new MediaType(type, subtype, parameters);
|
||||
try {
|
||||
return new MediaType(type, subtype, parameters);
|
||||
}
|
||||
catch (UnsupportedCharsetException ex) {
|
||||
throw new InvalidMediaTypeException(mediaType, "unsupported charset '" + ex.getCharsetName() + "'");
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
throw new InvalidMediaTypeException(mediaType, ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,7 +23,7 @@ import java.net.URI;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
/**
|
||||
* Simple implementation of {@link ClientHttpRequest} that wraps another request.
|
||||
@@ -53,8 +53,7 @@ final class BufferingClientHttpRequestWrapper extends AbstractBufferingClientHtt
|
||||
@Override
|
||||
protected ClientHttpResponse executeInternal(HttpHeaders headers, byte[] bufferedOutput) throws IOException {
|
||||
this.request.getHeaders().putAll(headers);
|
||||
OutputStream body = this.request.getBody();
|
||||
FileCopyUtils.copy(bufferedOutput, body);
|
||||
StreamUtils.copy(bufferedOutput, this.request.getBody());
|
||||
ClientHttpResponse response = this.request.execute();
|
||||
return new BufferingClientHttpResponseWrapper(response);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,6 +23,7 @@ import java.io.InputStream;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
/**
|
||||
* Simple implementation of {@link ClientHttpResponse} that reads the request's body into memory,
|
||||
@@ -61,7 +62,7 @@ final class BufferingClientHttpResponseWrapper implements ClientHttpResponse {
|
||||
|
||||
public InputStream getBody() throws IOException {
|
||||
if (this.body == null) {
|
||||
this.body = FileCopyUtils.copyToByteArray(this.response.getBody());
|
||||
this.body = StreamUtils.copyToByteArray(this.response.getBody());
|
||||
}
|
||||
return new ByteArrayInputStream(this.body);
|
||||
}
|
||||
|
||||
@@ -74,4 +74,4 @@ final class CommonsClientHttpResponse extends AbstractClientHttpResponse {
|
||||
this.httpMethod.releaseConnection();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,7 +24,7 @@ import java.util.List;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpRequest;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
/**
|
||||
* Wrapper for a {@link ClientHttpRequest} that has support for {@link ClientHttpRequestInterceptor}s.
|
||||
@@ -86,7 +86,7 @@ class InterceptingClientHttpRequest extends AbstractBufferingClientHttpRequest {
|
||||
delegate.getHeaders().putAll(request.getHeaders());
|
||||
|
||||
if (body.length > 0) {
|
||||
FileCopyUtils.copy(body, delegate.getBody());
|
||||
StreamUtils.copy(body, delegate.getBody());
|
||||
}
|
||||
return delegate.execute();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -39,9 +39,12 @@ final class SimpleBufferingClientHttpRequest extends AbstractBufferingClientHttp
|
||||
|
||||
private final HttpURLConnection connection;
|
||||
|
||||
private final boolean outputStreaming;
|
||||
|
||||
SimpleBufferingClientHttpRequest(HttpURLConnection connection) {
|
||||
|
||||
SimpleBufferingClientHttpRequest(HttpURLConnection connection, boolean outputStreaming) {
|
||||
this.connection = connection;
|
||||
this.outputStreaming = outputStreaming;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +70,7 @@ final class SimpleBufferingClientHttpRequest extends AbstractBufferingClientHttp
|
||||
}
|
||||
}
|
||||
|
||||
if (this.connection.getDoOutput()) {
|
||||
if (this.connection.getDoOutput() && this.outputStreaming) {
|
||||
this.connection.setFixedLengthStreamingMode(bufferedOutput.length);
|
||||
}
|
||||
this.connection.connect();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -50,6 +50,8 @@ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory
|
||||
|
||||
private int readTimeout = -1;
|
||||
|
||||
private boolean outputStreaming = true;
|
||||
|
||||
|
||||
/**
|
||||
* Set the {@link Proxy} to use for this request factory.
|
||||
@@ -104,15 +106,31 @@ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory
|
||||
this.readTimeout = readTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if the underlying URLConnection can be set to 'output streaming' mode. When
|
||||
* output streaming is enabled, authentication and redirection cannot be handled
|
||||
* automatically. If output streaming is disabled the
|
||||
* {@link HttpURLConnection#setFixedLengthStreamingMode(int)
|
||||
* setFixedLengthStreamingMode} and
|
||||
* {@link HttpURLConnection#setChunkedStreamingMode(int) setChunkedStreamingMode}
|
||||
* methods of the underlying connection will never be called.
|
||||
* <p>Default is {@code true}.
|
||||
* @param outputStreaming if output streaming is enabled
|
||||
*/
|
||||
public void setOutputStreaming(boolean outputStreaming) {
|
||||
this.outputStreaming = outputStreaming;
|
||||
}
|
||||
|
||||
|
||||
public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
|
||||
HttpURLConnection connection = openConnection(uri.toURL(), this.proxy);
|
||||
prepareConnection(connection, httpMethod.name());
|
||||
if (this.bufferRequestBody) {
|
||||
return new SimpleBufferingClientHttpRequest(connection);
|
||||
return new SimpleBufferingClientHttpRequest(connection, this.outputStreaming);
|
||||
}
|
||||
else {
|
||||
return new SimpleStreamingClientHttpRequest(connection, this.chunkSize);
|
||||
return new SimpleStreamingClientHttpRequest(connection, this.chunkSize,
|
||||
this.outputStreaming);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.http.client;
|
||||
|
||||
import java.io.FilterOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
@@ -27,6 +26,7 @@ import java.util.Map;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
/**
|
||||
* {@link ClientHttpRequest} implementation that uses standard J2SE facilities to execute streaming requests.
|
||||
@@ -44,10 +44,14 @@ final class SimpleStreamingClientHttpRequest extends AbstractClientHttpRequest {
|
||||
|
||||
private OutputStream body;
|
||||
|
||||
private final boolean outputStreaming;
|
||||
|
||||
SimpleStreamingClientHttpRequest(HttpURLConnection connection, int chunkSize) {
|
||||
|
||||
SimpleStreamingClientHttpRequest(HttpURLConnection connection, int chunkSize,
|
||||
boolean outputStreaming) {
|
||||
this.connection = connection;
|
||||
this.chunkSize = chunkSize;
|
||||
this.outputStreaming = outputStreaming;
|
||||
}
|
||||
|
||||
public HttpMethod getMethod() {
|
||||
@@ -66,18 +70,20 @@ final class SimpleStreamingClientHttpRequest extends AbstractClientHttpRequest {
|
||||
@Override
|
||||
protected OutputStream getBodyInternal(HttpHeaders headers) throws IOException {
|
||||
if (this.body == null) {
|
||||
int contentLength = (int) headers.getContentLength();
|
||||
if (contentLength >= 0) {
|
||||
this.connection.setFixedLengthStreamingMode(contentLength);
|
||||
}
|
||||
else {
|
||||
this.connection.setChunkedStreamingMode(this.chunkSize);
|
||||
if(this.outputStreaming) {
|
||||
int contentLength = (int) headers.getContentLength();
|
||||
if (contentLength >= 0) {
|
||||
this.connection.setFixedLengthStreamingMode(contentLength);
|
||||
}
|
||||
else {
|
||||
this.connection.setChunkedStreamingMode(this.chunkSize);
|
||||
}
|
||||
}
|
||||
writeHeaders(headers);
|
||||
this.connection.connect();
|
||||
this.body = this.connection.getOutputStream();
|
||||
}
|
||||
return new NonClosingOutputStream(this.body);
|
||||
return StreamUtils.nonClosing(this.body);
|
||||
}
|
||||
|
||||
private void writeHeaders(HttpHeaders headers) {
|
||||
@@ -106,26 +112,4 @@ final class SimpleStreamingClientHttpRequest extends AbstractClientHttpRequest {
|
||||
return new SimpleClientHttpResponse(this.connection);
|
||||
}
|
||||
|
||||
|
||||
private static class NonClosingOutputStream extends FilterOutputStream {
|
||||
|
||||
private NonClosingOutputStream(OutputStream out) {
|
||||
super(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b) throws IOException {
|
||||
super.write(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b, int off, int let) throws IOException {
|
||||
out.write(b, off, let);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -132,7 +132,7 @@ public class BufferedImageHttpMessageConverter implements HttpMessageConverter<B
|
||||
}
|
||||
|
||||
private boolean isWritable(MediaType mediaType) {
|
||||
if (mediaType == null) {
|
||||
if (mediaType == null || MediaType.ALL.equals(mediaType)) {
|
||||
return true;
|
||||
}
|
||||
Iterator<ImageWriter> imageWriters = ImageIO.getImageWritersByMIMEType(mediaType.toString());
|
||||
@@ -191,7 +191,7 @@ public class BufferedImageHttpMessageConverter implements HttpMessageConverter<B
|
||||
public void write(BufferedImage image, MediaType contentType, HttpOutputMessage outputMessage)
|
||||
throws IOException, HttpMessageNotWritableException {
|
||||
|
||||
if (contentType == null) {
|
||||
if (contentType == null || contentType.isWildcardType() || contentType.isWildcardSubtype()) {
|
||||
contentType = getDefaultContentType();
|
||||
}
|
||||
Assert.notNull(contentType,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,7 +22,7 @@ import java.io.IOException;
|
||||
import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.http.HttpOutputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
/**
|
||||
* Implementation of {@link HttpMessageConverter} that can read and write byte arrays.
|
||||
@@ -49,14 +49,9 @@ public class ByteArrayHttpMessageConverter extends AbstractHttpMessageConverter<
|
||||
@Override
|
||||
public byte[] readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException {
|
||||
long contentLength = inputMessage.getHeaders().getContentLength();
|
||||
if (contentLength >= 0) {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream((int) contentLength);
|
||||
FileCopyUtils.copy(inputMessage.getBody(), bos);
|
||||
return bos.toByteArray();
|
||||
}
|
||||
else {
|
||||
return FileCopyUtils.copyToByteArray(inputMessage.getBody());
|
||||
}
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream(contentLength >= 0 ? (int) contentLength : StreamUtils.BUFFER_SIZE);
|
||||
StreamUtils.copy(inputMessage.getBody(), bos);
|
||||
return bos.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -66,7 +61,7 @@ public class ByteArrayHttpMessageConverter extends AbstractHttpMessageConverter<
|
||||
|
||||
@Override
|
||||
protected void writeInternal(byte[] bytes, HttpOutputMessage outputMessage) throws IOException {
|
||||
FileCopyUtils.copy(bytes, outputMessage.getBody());
|
||||
StreamUtils.copy(bytes, outputMessage.getBody());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.springframework.http.converter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
@@ -37,9 +36,9 @@ import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.http.HttpOutputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.StreamUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -170,7 +169,7 @@ public class FormHttpMessageConverter implements HttpMessageConverter<MultiValue
|
||||
|
||||
MediaType contentType = inputMessage.getHeaders().getContentType();
|
||||
Charset charset = contentType.getCharSet() != null ? contentType.getCharSet() : this.charset;
|
||||
String body = FileCopyUtils.copyToString(new InputStreamReader(inputMessage.getBody(), charset));
|
||||
String body = StreamUtils.copyToString(inputMessage.getBody(), charset);
|
||||
|
||||
String[] pairs = StringUtils.tokenizeToStringArray(body, "&");
|
||||
|
||||
@@ -246,7 +245,7 @@ public class FormHttpMessageConverter implements HttpMessageConverter<MultiValue
|
||||
}
|
||||
byte[] bytes = builder.toString().getBytes(charset.name());
|
||||
outputMessage.getHeaders().setContentLength(bytes.length);
|
||||
FileCopyUtils.copy(bytes, outputMessage.getBody());
|
||||
StreamUtils.copy(bytes, outputMessage.getBody());
|
||||
}
|
||||
|
||||
private void writeMultipart(MultiValueMap<String, Object> parts, HttpOutputMessage outputMessage)
|
||||
@@ -265,10 +264,12 @@ public class FormHttpMessageConverter implements HttpMessageConverter<MultiValue
|
||||
for (Map.Entry<String, List<Object>> entry : parts.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
for (Object part : entry.getValue()) {
|
||||
writeBoundary(boundary, os);
|
||||
HttpEntity entity = getEntity(part);
|
||||
writePart(name, entity, os);
|
||||
writeNewLine(os);
|
||||
if (part != null) {
|
||||
writeBoundary(boundary, os);
|
||||
HttpEntity entity = getEntity(part);
|
||||
writePart(name, entity, os);
|
||||
writeNewLine(os);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,7 @@ package org.springframework.http.converter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.activation.FileTypeMap;
|
||||
import javax.activation.MimetypesFileTypeMap;
|
||||
|
||||
@@ -28,7 +29,7 @@ import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.http.HttpOutputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.StreamUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -61,7 +62,7 @@ public class ResourceHttpMessageConverter extends AbstractHttpMessageConverter<R
|
||||
protected Resource readInternal(Class<? extends Resource> clazz, HttpInputMessage inputMessage)
|
||||
throws IOException, HttpMessageNotReadableException {
|
||||
|
||||
byte[] body = FileCopyUtils.copyToByteArray(inputMessage.getBody());
|
||||
byte[] body = StreamUtils.copyToByteArray(inputMessage.getBody());
|
||||
return new ByteArrayResource(body);
|
||||
}
|
||||
|
||||
@@ -84,7 +85,7 @@ public class ResourceHttpMessageConverter extends AbstractHttpMessageConverter<R
|
||||
protected void writeInternal(Resource resource, HttpOutputMessage outputMessage)
|
||||
throws IOException, HttpMessageNotWritableException {
|
||||
|
||||
FileCopyUtils.copy(resource.getInputStream(), outputMessage.getBody());
|
||||
StreamUtils.copy(resource.getInputStream(), outputMessage.getBody());
|
||||
outputMessage.getBody().flush();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,8 +17,6 @@
|
||||
package org.springframework.http.converter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
@@ -27,7 +25,7 @@ import java.util.List;
|
||||
import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.http.HttpOutputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
/**
|
||||
* Implementation of {@link HttpMessageConverter} that can read and write strings.
|
||||
@@ -84,7 +82,7 @@ public class StringHttpMessageConverter extends AbstractHttpMessageConverter<Str
|
||||
@Override
|
||||
protected String readInternal(Class<? extends String> clazz, HttpInputMessage inputMessage) throws IOException {
|
||||
Charset charset = getContentTypeCharset(inputMessage.getHeaders().getContentType());
|
||||
return FileCopyUtils.copyToString(new InputStreamReader(inputMessage.getBody(), charset));
|
||||
return StreamUtils.copyToString(inputMessage.getBody(), charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -105,7 +103,7 @@ public class StringHttpMessageConverter extends AbstractHttpMessageConverter<Str
|
||||
outputMessage.getHeaders().setAcceptCharset(getAcceptedCharsets());
|
||||
}
|
||||
Charset charset = getContentTypeCharset(outputMessage.getHeaders().getContentType());
|
||||
FileCopyUtils.copy(s, new OutputStreamWriter(outputMessage.getBody(), charset));
|
||||
StreamUtils.copy(s, charset, outputMessage.getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -43,5 +43,4 @@ public class RssChannelHttpMessageConverter extends AbstractWireFeedHttpMessageC
|
||||
return Channel.class.isAssignableFrom(clazz);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,7 @@ package org.springframework.web.accept;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
@@ -55,6 +56,7 @@ public class ContentNegotiationManager implements ContentNegotiationStrategy, Me
|
||||
private final Set<MediaTypeFileExtensionResolver> fileExtensionResolvers =
|
||||
new LinkedHashSet<MediaTypeFileExtensionResolver>();
|
||||
|
||||
|
||||
/**
|
||||
* Create an instance with the given ContentNegotiationStrategy instances.
|
||||
* <p>Each instance is checked to see if it is also an implementation of
|
||||
@@ -72,12 +74,29 @@ public class ContentNegotiationManager implements ContentNegotiationStrategy, Me
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance with a {@link HeaderContentNegotiationStrategy}.
|
||||
* Create an instance with the given ContentNegotiationStrategy instances.
|
||||
* <p>Each instance is checked to see if it is also an implementation of
|
||||
* MediaTypeFileExtensionResolver, and if so it is registered as such.
|
||||
* @param strategies one more more ContentNegotiationStrategy instances
|
||||
*/
|
||||
public ContentNegotiationManager(Collection<ContentNegotiationStrategy> strategies) {
|
||||
Assert.notEmpty(strategies, "At least one ContentNegotiationStrategy is expected");
|
||||
this.contentNegotiationStrategies.addAll(strategies);
|
||||
for (ContentNegotiationStrategy strategy : this.contentNegotiationStrategies) {
|
||||
if (strategy instanceof MediaTypeFileExtensionResolver) {
|
||||
this.fileExtensionResolvers.add((MediaTypeFileExtensionResolver) strategy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a default instance with a {@link HeaderContentNegotiationStrategy}.
|
||||
*/
|
||||
public ContentNegotiationManager() {
|
||||
this(new HeaderContentNegotiationStrategy());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add MediaTypeFileExtensionResolver instances.
|
||||
* <p>Note that some {@link ContentNegotiationStrategy} implementations also
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.accept;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -22,7 +23,6 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
@@ -39,13 +39,13 @@ import org.springframework.web.context.ServletContextAware;
|
||||
* <p>By default strategies for checking the extension of the request path and
|
||||
* the {@code Accept} header are registered. The path extension check will perform
|
||||
* lookups through the {@link ServletContext} and the Java Activation Framework
|
||||
* (if present) unless {@linkplain #setMediaTypes(Properties) media types} are configured.
|
||||
* (if present) unless {@linkplain #setMediaTypes media types} are configured.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.2
|
||||
*/
|
||||
public class ContentNegotiationManagerFactoryBean
|
||||
implements FactoryBean<ContentNegotiationManager>, InitializingBean, ServletContextAware {
|
||||
implements FactoryBean<ContentNegotiationManager>, ServletContextAware, InitializingBean {
|
||||
|
||||
private boolean favorPathExtension = true;
|
||||
|
||||
@@ -65,6 +65,7 @@ public class ContentNegotiationManagerFactoryBean
|
||||
|
||||
private ServletContext servletContext;
|
||||
|
||||
|
||||
/**
|
||||
* Indicate whether the extension of the request path should be used to determine
|
||||
* the requested media type with the <em>highest priority</em>.
|
||||
@@ -81,7 +82,6 @@ public class ContentNegotiationManagerFactoryBean
|
||||
* <p>When this mapping is not set or when an extension is not found, the Java
|
||||
* Action Framework, if available, may be used if enabled via
|
||||
* {@link #setFavorPathExtension(boolean)}.
|
||||
*
|
||||
* @see #addMediaType(String, MediaType)
|
||||
* @see #addMediaTypes(Map)
|
||||
*/
|
||||
@@ -121,9 +121,8 @@ public class ContentNegotiationManagerFactoryBean
|
||||
* to map from file extensions to media types. This is used only when
|
||||
* {@link #setFavorPathExtension(boolean)} is set to {@code true}.
|
||||
* <p>The default value is {@code true}.
|
||||
*
|
||||
* @see #parameterName
|
||||
* @see #setMediaTypes(Properties)
|
||||
* @see #setParameterName
|
||||
* @see #setMediaTypes
|
||||
*/
|
||||
public void setUseJaf(boolean useJaf) {
|
||||
this.useJaf = useJaf;
|
||||
@@ -138,8 +137,7 @@ public class ContentNegotiationManagerFactoryBean
|
||||
* {@code "application/pdf"} regardless of the {@code Accept} header.
|
||||
* <p>To use this option effectively you must also configure the MediaType
|
||||
* type mappings via {@link #setMediaTypes(Properties)}.
|
||||
*
|
||||
* @see #setParameterName(String)
|
||||
* @see #setParameterName
|
||||
*/
|
||||
public void setFavorParameter(boolean favorParameter) {
|
||||
this.favorParameter = favorParameter;
|
||||
@@ -180,7 +178,8 @@ public class ContentNegotiationManagerFactoryBean
|
||||
this.servletContext = servletContext;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
|
||||
public void afterPropertiesSet() {
|
||||
List<ContentNegotiationStrategy> strategies = new ArrayList<ContentNegotiationStrategy>();
|
||||
|
||||
if (this.favorPathExtension) {
|
||||
@@ -210,8 +209,12 @@ public class ContentNegotiationManagerFactoryBean
|
||||
strategies.add(new FixedContentNegotiationStrategy(this.defaultContentType));
|
||||
}
|
||||
|
||||
ContentNegotiationStrategy[] array = strategies.toArray(new ContentNegotiationStrategy[strategies.size()]);
|
||||
this.contentNegotiationManager = new ContentNegotiationManager(array);
|
||||
this.contentNegotiationManager = new ContentNegotiationManager(strategies);
|
||||
}
|
||||
|
||||
|
||||
public ContentNegotiationManager getObject() {
|
||||
return this.contentNegotiationManager;
|
||||
}
|
||||
|
||||
public Class<?> getObjectType() {
|
||||
@@ -222,8 +225,4 @@ public class ContentNegotiationManagerFactoryBean
|
||||
return true;
|
||||
}
|
||||
|
||||
public ContentNegotiationManager getObject() throws Exception {
|
||||
return this.contentNegotiationManager;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -55,14 +55,14 @@ public @interface CookieValue {
|
||||
* in case the header is missing in the request. Switch this to
|
||||
* {@code false} if you prefer a {@code null} in case of the
|
||||
* missing header.
|
||||
* <p>Alternatively, provide a {@link #defaultValue() defaultValue},
|
||||
* which implicitly sets this flag to {@code false}.
|
||||
* <p>Alternatively, provide a {@link #defaultValue}, which implicitly sets
|
||||
* this flag to {@code false}.
|
||||
*/
|
||||
boolean required() default true;
|
||||
|
||||
/**
|
||||
* The default value to use as a fallback. Supplying a default value implicitly
|
||||
* sets {@link #required()} to false.
|
||||
* sets {@link #required} to {@code false}.
|
||||
*/
|
||||
String defaultValue() default ValueConstants.DEFAULT_NONE;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -49,14 +49,14 @@ public @interface RequestHeader {
|
||||
* <p>Default is {@code true}, leading to an exception thrown in case
|
||||
* of the header missing in the request. Switch this to {@code false}
|
||||
* if you prefer a {@code null} in case of the header missing.
|
||||
* <p>Alternatively, provide a {@link #defaultValue() defaultValue},
|
||||
* which implicitely sets this flag to {@code false}.
|
||||
* <p>Alternatively, provide a {@link #defaultValue}, which implicitly sets
|
||||
* this flag to {@code false}.
|
||||
*/
|
||||
boolean required() default true;
|
||||
|
||||
/**
|
||||
* The default value to use as a fallback. Supplying a default value implicitely
|
||||
* sets {@link #required()} to false.
|
||||
* The default value to use as a fallback. Supplying a default value implicitly
|
||||
* sets {@link #required} to {@code false}.
|
||||
*/
|
||||
String defaultValue() default ValueConstants.DEFAULT_NONE;
|
||||
|
||||
|
||||
@@ -266,6 +266,7 @@ public @interface RequestMapping {
|
||||
* Ant-style path patterns are also supported (e.g. "/myPath/*.do").
|
||||
* At the method level, relative paths (e.g. "edit.do") are supported
|
||||
* within the primary mapping expressed at the type level.
|
||||
* Path mapping URIs may contain placeholders (e.g. "/${connect}")
|
||||
* <p>In a Portlet environment: the mapped portlet modes
|
||||
* (i.e. "EDIT", "VIEW", "HELP" or any custom modes).
|
||||
* <p><b>Supported at the type level as well as at the method level!</b>
|
||||
|
||||
@@ -68,8 +68,9 @@ public @interface RequestParam {
|
||||
boolean required() default true;
|
||||
|
||||
/**
|
||||
* The default value to use as a fallback. Supplying a default value implicitly
|
||||
* sets {@link #required()} to false.
|
||||
* The default value to use as a fallback when the request parameter value
|
||||
* is not provided or empty. Supplying a default value implicitly sets
|
||||
* {@link #required()} to false.
|
||||
*/
|
||||
String defaultValue() default ValueConstants.DEFAULT_NONE;
|
||||
|
||||
|
||||
@@ -36,4 +36,4 @@ import java.lang.annotation.Target;
|
||||
@Documented
|
||||
public @interface ResponseBody {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,4 +37,4 @@ public interface WebDataBinderFactory {
|
||||
*/
|
||||
WebDataBinder createBinder(NativeWebRequest webRequest, Object target, String objectName) throws Exception;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -71,11 +71,6 @@ public interface ConfigurableWebApplicationContext extends WebApplicationContext
|
||||
*/
|
||||
ServletConfig getServletConfig();
|
||||
|
||||
/**
|
||||
* Return the {@link ConfigurableWebEnvironment} used by this web application context.
|
||||
*/
|
||||
ConfigurableWebEnvironment getEnvironment();
|
||||
|
||||
/**
|
||||
* Set the namespace for this web application context,
|
||||
* to be used for building a default context config location.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,11 +23,11 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.access.BeanFactoryLocator;
|
||||
import org.springframework.beans.factory.access.BeanFactoryReference;
|
||||
@@ -38,6 +38,7 @@ import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.access.ContextSingletonBeanFactoryLocator;
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.support.PropertiesLoaderUtils;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -280,7 +281,18 @@ public class ContextLoader {
|
||||
this.context = createWebApplicationContext(servletContext);
|
||||
}
|
||||
if (this.context instanceof ConfigurableWebApplicationContext) {
|
||||
configureAndRefreshWebApplicationContext((ConfigurableWebApplicationContext)this.context, servletContext);
|
||||
ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;
|
||||
if (!cwac.isActive()) {
|
||||
// The context has not yet been refreshed -> provide services such as
|
||||
// setting the parent context, setting the application context id, etc
|
||||
if (cwac.getParent() == null) {
|
||||
// The context instance was injected without an explicit parent ->
|
||||
// determine parent for root web application context, if any.
|
||||
ApplicationContext parent = loadParentContext(servletContext);
|
||||
cwac.setParent(parent);
|
||||
}
|
||||
configureAndRefreshWebApplicationContext(cwac, servletContext);
|
||||
}
|
||||
}
|
||||
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
|
||||
|
||||
@@ -333,9 +345,7 @@ public class ContextLoader {
|
||||
throw new ApplicationContextException("Custom context class [" + contextClass.getName() +
|
||||
"] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]");
|
||||
}
|
||||
ConfigurableWebApplicationContext wac =
|
||||
(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
|
||||
return wac;
|
||||
return (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -370,10 +380,6 @@ public class ContextLoader {
|
||||
}
|
||||
}
|
||||
|
||||
// Determine parent for root web application context, if any.
|
||||
ApplicationContext parent = loadParentContext(sc);
|
||||
|
||||
wac.setParent(parent);
|
||||
wac.setServletContext(sc);
|
||||
String initParameter = sc.getInitParameter(CONFIG_LOCATION_PARAM);
|
||||
if (initParameter != null) {
|
||||
@@ -472,11 +478,11 @@ public class ContextLoader {
|
||||
|
||||
Class<?> contextClass = applicationContext.getClass();
|
||||
ArrayList<ApplicationContextInitializer<ConfigurableApplicationContext>> initializerInstances =
|
||||
new ArrayList<ApplicationContextInitializer<ConfigurableApplicationContext>>();
|
||||
new ArrayList<ApplicationContextInitializer<ConfigurableApplicationContext>>();
|
||||
|
||||
for (Class<ApplicationContextInitializer<ConfigurableApplicationContext>> initializerClass : initializerClasses) {
|
||||
Class<?> initializerContextClass =
|
||||
GenericTypeResolver.resolveTypeArgument(initializerClass, ApplicationContextInitializer.class);
|
||||
GenericTypeResolver.resolveTypeArgument(initializerClass, ApplicationContextInitializer.class);
|
||||
Assert.isAssignable(initializerContextClass, contextClass, String.format(
|
||||
"Could not add context initializer [%s] as its generic parameter [%s] " +
|
||||
"is not assignable from the type of application context used by this " +
|
||||
@@ -485,7 +491,10 @@ public class ContextLoader {
|
||||
initializerInstances.add(BeanUtils.instantiateClass(initializerClass));
|
||||
}
|
||||
|
||||
applicationContext.getEnvironment().initPropertySources(servletContext, null);
|
||||
ConfigurableEnvironment env = applicationContext.getEnvironment();
|
||||
if (env instanceof ConfigurableWebEnvironment) {
|
||||
((ConfigurableWebEnvironment)env).initPropertySources(servletContext, null);
|
||||
}
|
||||
|
||||
Collections.sort(initializerInstances, new AnnotationAwareOrderComparator());
|
||||
for (ApplicationContextInitializer<ConfigurableApplicationContext> initializer : initializerInstances) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,13 +32,13 @@ import org.springframework.web.context.request.NativeWebRequest;
|
||||
* <p>Subclasses can extend this class to easily associate additional data or
|
||||
* behavior with the {@link DeferredResult}. For example, one might want to
|
||||
* associate the user used to create the {@link DeferredResult} by extending the
|
||||
* class and adding an addition property for the user. In this way, the user
|
||||
* class and adding an additional property for the user. In this way, the user
|
||||
* could easily be accessed later without the need to use a data structure to do
|
||||
* the mapping.
|
||||
*
|
||||
* <p>An example of associating additional behavior to this class might be
|
||||
* realized by extending the class to implement an additional interface. For
|
||||
* example, one might want to implement a {@link Comparable} so that when the
|
||||
* example, one might want to implement {@link Comparable} so that when the
|
||||
* {@link DeferredResult} is added to a {@link PriorityQueue} it is handled in
|
||||
* the correct order.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,9 +37,9 @@ import org.springframework.web.util.UrlPathHelper;
|
||||
* as an SPI and not typically used directly by application classes.
|
||||
*
|
||||
* <p>An async scenario starts with request processing as usual in a thread (T1).
|
||||
* Concurrent request handling can be innitiated by calling
|
||||
* {@linkplain #startCallableProcessing(Callable, Object...) startCallableProcessing} or
|
||||
* {@linkplain #startDeferredResultProcessing(DeferredResult, Object...) startDeferredResultProcessing}
|
||||
* Concurrent request handling can be initiated by calling
|
||||
* {@link #startCallableProcessing(Callable, Object...) startCallableProcessing} or
|
||||
* {@link #startDeferredResultProcessing(DeferredResult, Object...) startDeferredResultProcessing},
|
||||
* both of which produce a result in a separate thread (T2). The result is saved
|
||||
* and the request dispatched to the container, to resume processing with the saved
|
||||
* result in a third thread (T3). Within the dispatched thread (T3), the saved
|
||||
@@ -263,7 +263,7 @@ public final class WebAsyncManager {
|
||||
* the timeout value of the {@code AsyncWebRequest} before delegating to
|
||||
* {@link #startCallableProcessing(Callable, Object...)}.
|
||||
*
|
||||
* @param webAsyncTask an WebAsyncTask containing the target {@code Callable}
|
||||
* @param webAsyncTask a WebAsyncTask containing the target {@code Callable}
|
||||
* @param processingContext additional context to save that can be accessed
|
||||
* via {@link #getConcurrentResultContext()}
|
||||
* @throws Exception If concurrent processing failed to start
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -46,7 +46,7 @@ public class WebAsyncTask<V> {
|
||||
|
||||
|
||||
/**
|
||||
* Create an {@code WebAsyncTask} wrapping the given {@link Callable}.
|
||||
* Create a {@code WebAsyncTask} wrapping the given {@link Callable}.
|
||||
* @param callable the callable for concurrent handling
|
||||
*/
|
||||
public WebAsyncTask(Callable<V> callable) {
|
||||
@@ -54,7 +54,7 @@ public class WebAsyncTask<V> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an {@code WebAsyncTask} with a timeout value and a {@link Callable}.
|
||||
* Create a {@code WebAsyncTask} with a timeout value and a {@link Callable}.
|
||||
* @param timeout timeout value in milliseconds
|
||||
* @param callable the callable for concurrent handling
|
||||
*/
|
||||
@@ -63,7 +63,7 @@ public class WebAsyncTask<V> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an {@code WebAsyncTask} with a timeout value, an executor name, and a {@link Callable}.
|
||||
* Create a {@code WebAsyncTask} with a timeout value, an executor name, and a {@link Callable}.
|
||||
* @param timeout timeout value in milliseconds; ignored if {@code null}
|
||||
* @param callable the callable for concurrent handling
|
||||
*/
|
||||
@@ -73,7 +73,7 @@ public class WebAsyncTask<V> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an {@code WebAsyncTask} with a timeout value, an executor instance, and a Callable.
|
||||
* Create a {@code WebAsyncTask} with a timeout value, an executor instance, and a Callable.
|
||||
* @param timeout timeout value in milliseconds; ignored if {@code null}
|
||||
* @param callable the callable for concurrent handling
|
||||
*/
|
||||
@@ -113,7 +113,7 @@ public class WebAsyncTask<V> {
|
||||
return this.executor;
|
||||
}
|
||||
else if (this.executorName != null) {
|
||||
Assert.state(this.beanFactory != null, "A BeanFactory is required to look up an task executor bean");
|
||||
Assert.state(this.beanFactory != null, "A BeanFactory is required to look up a task executor bean");
|
||||
return this.beanFactory.getBean(this.executorName, AsyncTaskExecutor.class);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,7 +27,6 @@ import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
import org.springframework.ui.context.Theme;
|
||||
import org.springframework.ui.context.ThemeSource;
|
||||
import org.springframework.ui.context.support.UiApplicationContextUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.context.ConfigurableWebApplicationContext;
|
||||
import org.springframework.web.context.ConfigurableWebEnvironment;
|
||||
import org.springframework.web.context.ServletConfigAware;
|
||||
@@ -157,15 +156,6 @@ public abstract class AbstractRefreshableWebApplicationContext extends AbstractR
|
||||
return new StandardServletEnvironment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurableWebEnvironment getEnvironment() {
|
||||
ConfigurableEnvironment env = super.getEnvironment();
|
||||
Assert.isInstanceOf(ConfigurableWebEnvironment.class, env,
|
||||
"ConfigurableWebApplicationContext environment must be of type " +
|
||||
"ConfigurableWebEnvironment");
|
||||
return (ConfigurableWebEnvironment) env;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register request/session scopes, a {@link ServletContextAwareProcessor}, etc.
|
||||
*/
|
||||
@@ -212,7 +202,11 @@ public abstract class AbstractRefreshableWebApplicationContext extends AbstractR
|
||||
@Override
|
||||
protected void initPropertySources() {
|
||||
super.initPropertySources();
|
||||
this.getEnvironment().initPropertySources(this.servletContext, this.servletConfig);
|
||||
ConfigurableEnvironment env = this.getEnvironment();
|
||||
if (env instanceof ConfigurableWebEnvironment) {
|
||||
((ConfigurableWebEnvironment)env).initPropertySources(
|
||||
this.servletContext, this.servletConfig);
|
||||
}
|
||||
}
|
||||
|
||||
public Theme getTheme(String themeName) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -147,15 +147,6 @@ public class GenericWebApplicationContext extends GenericApplicationContext
|
||||
return new StandardServletEnvironment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurableWebEnvironment getEnvironment() {
|
||||
ConfigurableEnvironment env = super.getEnvironment();
|
||||
Assert.isInstanceOf(ConfigurableWebEnvironment.class, env,
|
||||
"ConfigurableWebApplicationContext environment must be of type " +
|
||||
"ConfigurableWebEnvironment");
|
||||
return (ConfigurableWebEnvironment) env;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register ServletContextAwareProcessor.
|
||||
* @see ServletContextAwareProcessor
|
||||
@@ -202,7 +193,11 @@ public class GenericWebApplicationContext extends GenericApplicationContext
|
||||
@Override
|
||||
protected void initPropertySources() {
|
||||
super.initPropertySources();
|
||||
this.getEnvironment().initPropertySources(this.servletContext, null);
|
||||
ConfigurableEnvironment env = this.getEnvironment();
|
||||
if (env instanceof ConfigurableWebEnvironment) {
|
||||
((ConfigurableWebEnvironment)env).initPropertySources(
|
||||
this.servletContext, null);
|
||||
}
|
||||
}
|
||||
|
||||
public Theme getTheme(String themeName) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,9 +27,7 @@ import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
import org.springframework.ui.context.Theme;
|
||||
import org.springframework.ui.context.ThemeSource;
|
||||
import org.springframework.ui.context.support.UiApplicationContextUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.context.ConfigurableWebApplicationContext;
|
||||
import org.springframework.web.context.ConfigurableWebEnvironment;
|
||||
import org.springframework.web.context.ServletConfigAware;
|
||||
import org.springframework.web.context.ServletContextAware;
|
||||
|
||||
@@ -169,15 +167,6 @@ public class StaticWebApplicationContext extends StaticApplicationContext
|
||||
return new StandardServletEnvironment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurableWebEnvironment getEnvironment() {
|
||||
ConfigurableEnvironment env = super.getEnvironment();
|
||||
Assert.isInstanceOf(ConfigurableWebEnvironment.class, env,
|
||||
"ConfigurableWebApplication environment must be of type " +
|
||||
"ConfigurableWebEnvironment");
|
||||
return (ConfigurableWebEnvironment) env;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the theme capability.
|
||||
*/
|
||||
|
||||
@@ -69,4 +69,4 @@ public abstract class HandlerMethodSelector {
|
||||
return handlerMethods;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,4 +71,4 @@ public abstract class AbstractCookieValueMethodArgumentResolver extends Abstract
|
||||
super(annotation.value(), annotation.required(), annotation.defaultValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +92,9 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
|
||||
}
|
||||
arg = handleNullValue(namedValueInfo.name, arg, paramType);
|
||||
}
|
||||
else if ("".equals(arg) && (namedValueInfo.defaultValue != null)) {
|
||||
arg = resolveDefaultValue(namedValueInfo.defaultValue);
|
||||
}
|
||||
|
||||
if (binderFactory != null) {
|
||||
WebDataBinder binder = binderFactory.createBinder(webRequest, null, namedValueInfo.name);
|
||||
|
||||
@@ -76,4 +76,4 @@ public class ExpressionValueMethodArgumentResolver extends AbstractNamedValueMet
|
||||
super("@Value", false, annotation.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,4 +243,4 @@ public final class ModelFactory {
|
||||
!(value instanceof Map) && !BeanUtils.isSimpleValueType(value.getClass()));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,4 +87,4 @@ public class RequestHeaderMethodArgumentResolver extends AbstractNamedValueMetho
|
||||
super(annotation.value(), annotation.required(), annotation.defaultValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,4 +212,4 @@ public class RequestParamMethodArgumentResolver extends AbstractNamedValueMethod
|
||||
super(annotation.value(), annotation.required(), annotation.defaultValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,4 +62,4 @@ public interface HandlerMethodArgumentResolver {
|
||||
NativeWebRequest webRequest,
|
||||
WebDataBinderFactory binderFactory) throws Exception;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,4 +58,4 @@ public interface HandlerMethodReturnValueHandler {
|
||||
ModelAndViewContainer mavContainer,
|
||||
NativeWebRequest webRequest) throws Exception;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.web.util;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
@@ -38,9 +39,11 @@ import org.springframework.util.StringUtils;
|
||||
* Extension of {@link UriComponents} for hierarchical URIs.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Phillip Webb
|
||||
* @since 3.1.3
|
||||
* @see <a href="http://tools.ietf.org/html/rfc3986#section-1.2.3">Hierarchical URIs</a>
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
final class HierarchicalUriComponents extends UriComponents {
|
||||
|
||||
private static final char PATH_DELIMITER = '/';
|
||||
@@ -405,7 +408,10 @@ final class HierarchicalUriComponents extends UriComponents {
|
||||
else {
|
||||
String path = getPath();
|
||||
if (StringUtils.hasLength(path) && path.charAt(0) != PATH_DELIMITER) {
|
||||
path = PATH_DELIMITER + path;
|
||||
// Only prefix the path delimiter if something exists before it
|
||||
if(getScheme() != null || getUserInfo() != null || getHost() != null || getPort() != -1) {
|
||||
path = PATH_DELIMITER + path;
|
||||
}
|
||||
}
|
||||
return new URI(getScheme(), getUserInfo(), getHost(), getPort(), path, getQuery(),
|
||||
getFragment());
|
||||
@@ -425,28 +431,15 @@ final class HierarchicalUriComponents extends UriComponents {
|
||||
return false;
|
||||
}
|
||||
HierarchicalUriComponents other = (HierarchicalUriComponents) obj;
|
||||
if (ObjectUtils.nullSafeEquals(getScheme(), other.getScheme())) {
|
||||
return false;
|
||||
}
|
||||
if (ObjectUtils.nullSafeEquals(getUserInfo(), other.getUserInfo())) {
|
||||
return false;
|
||||
}
|
||||
if (ObjectUtils.nullSafeEquals(getHost(), other.getHost())) {
|
||||
return false;
|
||||
}
|
||||
if (this.port != other.port) {
|
||||
return false;
|
||||
}
|
||||
if (!this.path.equals(other.path)) {
|
||||
return false;
|
||||
}
|
||||
if (!this.queryParams.equals(other.queryParams)) {
|
||||
return false;
|
||||
}
|
||||
if (ObjectUtils.nullSafeEquals(getFragment(), other.getFragment())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
boolean rtn = true;
|
||||
rtn &= ObjectUtils.nullSafeEquals(getScheme(), other.getScheme());
|
||||
rtn &= ObjectUtils.nullSafeEquals(getUserInfo(), other.getUserInfo());
|
||||
rtn &= ObjectUtils.nullSafeEquals(getHost(), other.getHost());
|
||||
rtn &= getPort() == other.getPort();
|
||||
rtn &= this.path.equals(other.path);
|
||||
rtn &= this.queryParams.equals(other.queryParams);
|
||||
rtn &= ObjectUtils.nullSafeEquals(getFragment(), other.getFragment());
|
||||
return rtn;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -614,7 +607,7 @@ final class HierarchicalUriComponents extends UriComponents {
|
||||
/**
|
||||
* Defines the contract for path (segments).
|
||||
*/
|
||||
interface PathComponent {
|
||||
interface PathComponent extends Serializable {
|
||||
|
||||
String getPath();
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,21 +21,21 @@ package org.springframework.web.util;
|
||||
* Escapes based on the JavaScript 1.5 recommendation.
|
||||
*
|
||||
* <p>Reference:
|
||||
* <a href="http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide:Literals#String_Literals">
|
||||
* Core JavaScript 1.5 Guide
|
||||
* </a>
|
||||
* <a href="https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Values,_variables,_and_literals#String_literals">
|
||||
* JavaScript Guide</a> on Mozilla Developer Network.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Rob Harrop
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.1.1
|
||||
*/
|
||||
public class JavaScriptUtils {
|
||||
|
||||
/**
|
||||
* Turn special characters into escaped characters conforming to JavaScript.
|
||||
* Handles complete character set defined in HTML 4.01 recommendation.
|
||||
* Turn JavaScript special characters into escaped characters.
|
||||
*
|
||||
* @param input the input string
|
||||
* @return the escaped string
|
||||
* @return the string with escaped characters
|
||||
*/
|
||||
public static String javaScriptEscape(String input) {
|
||||
if (input == null) {
|
||||
@@ -73,6 +73,27 @@ public class JavaScriptUtils {
|
||||
else if (c == '\f') {
|
||||
filtered.append("\\f");
|
||||
}
|
||||
else if (c == '\b') {
|
||||
filtered.append("\\b");
|
||||
}
|
||||
// No '\v' in Java, use octal value for VT ascii char
|
||||
else if (c == '\013') {
|
||||
filtered.append("\\v");
|
||||
}
|
||||
else if (c == '<') {
|
||||
filtered.append("\\u003C");
|
||||
}
|
||||
else if (c == '>') {
|
||||
filtered.append("\\u003E");
|
||||
}
|
||||
// Unicode for PS (line terminator in ECMA-262)
|
||||
else if (c == '\u2028') {
|
||||
filtered.append("\\u2028");
|
||||
}
|
||||
// Unicode for LS (line terminator in ECMA-262)
|
||||
else if (c == '\u2029') {
|
||||
filtered.append("\\u2029");
|
||||
}
|
||||
else {
|
||||
filtered.append(c);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,12 +17,10 @@
|
||||
package org.springframework.web.util;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.springframework.util.Log4jConfigurer;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
import org.springframework.util.SystemPropertyUtils;
|
||||
|
||||
/**
|
||||
* Convenience class that performs custom log4j initialization for web environments,
|
||||
@@ -90,6 +88,7 @@ import org.springframework.util.SystemPropertyUtils;
|
||||
* context-param at all) without worrying.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Marten Deinum
|
||||
* @since 12.08.2003
|
||||
* @see org.springframework.util.Log4jConfigurer
|
||||
* @see Log4jConfigListener
|
||||
@@ -122,9 +121,8 @@ public abstract class Log4jWebConfigurer {
|
||||
if (location != null) {
|
||||
// Perform actual log4j initialization; else rely on log4j's default initialization.
|
||||
try {
|
||||
// Resolve system property placeholders before potentially
|
||||
// resolving a real path.
|
||||
location = SystemPropertyUtils.resolvePlaceholders(location);
|
||||
// Resolve property placeholders before potentially resolving a real path.
|
||||
location = ServletContextPropertyUtils.resolvePlaceholders(location, servletContext);
|
||||
|
||||
// Leave a URL (e.g. "classpath:" or "file:") as-is.
|
||||
if (!ResourceUtils.isUrl(location)) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,9 +30,11 @@ import org.springframework.util.ObjectUtils;
|
||||
* Extension of {@link UriComponents} for opaque URIs.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Phillip Webb
|
||||
* @since 3.2
|
||||
* @see <a href="http://tools.ietf.org/html/rfc3986#section-1.2.3">Hierarchical vs Opaque URIs</a>
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
final class OpaqueUriComponents extends UriComponents {
|
||||
|
||||
private static final MultiValueMap<String, String> QUERY_PARAMS_NONE = new LinkedMultiValueMap<String, String>(0);
|
||||
@@ -144,18 +146,11 @@ final class OpaqueUriComponents extends UriComponents {
|
||||
}
|
||||
|
||||
OpaqueUriComponents other = (OpaqueUriComponents) obj;
|
||||
|
||||
if (ObjectUtils.nullSafeEquals(getScheme(), other.getScheme())) {
|
||||
return false;
|
||||
}
|
||||
if (ObjectUtils.nullSafeEquals(this.ssp, other.ssp)) {
|
||||
return false;
|
||||
}
|
||||
if (ObjectUtils.nullSafeEquals(getFragment(), other.getFragment())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
boolean rtn = true;
|
||||
rtn &= ObjectUtils.nullSafeEquals(getScheme(), other.getScheme());
|
||||
rtn &= ObjectUtils.nullSafeEquals(this.ssp, other.ssp);
|
||||
rtn &= ObjectUtils.nullSafeEquals(getFragment(), other.getFragment());
|
||||
return rtn;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.web.util;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.springframework.util.PropertyPlaceholderHelper;
|
||||
import org.springframework.util.SystemPropertyUtils;
|
||||
|
||||
/**
|
||||
* Helper class for resolving placeholders in texts. Usually applied to file paths.
|
||||
*
|
||||
* <p>A text may contain {@code ${...}} placeholders, to be resolved as servlet context
|
||||
* init parameters or system properties: e.g. {@code ${user.dir}}. Default values can
|
||||
* be supplied using the ":" separator between key and value.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Marten Deinum
|
||||
* @since 3.2.2
|
||||
* @see SystemPropertyUtils
|
||||
* @see ServletContext#getInitParameter(String)
|
||||
*/
|
||||
public abstract class ServletContextPropertyUtils {
|
||||
|
||||
private static final PropertyPlaceholderHelper strictHelper =
|
||||
new PropertyPlaceholderHelper(SystemPropertyUtils.PLACEHOLDER_PREFIX,
|
||||
SystemPropertyUtils.PLACEHOLDER_SUFFIX, SystemPropertyUtils.VALUE_SEPARATOR, false);
|
||||
|
||||
private static final PropertyPlaceholderHelper nonStrictHelper =
|
||||
new PropertyPlaceholderHelper(SystemPropertyUtils.PLACEHOLDER_PREFIX,
|
||||
SystemPropertyUtils.PLACEHOLDER_SUFFIX, SystemPropertyUtils.VALUE_SEPARATOR, true);
|
||||
|
||||
|
||||
/**
|
||||
* Resolve ${...} placeholders in the given text, replacing them with corresponding
|
||||
* servlet context init parameter or system property values.
|
||||
* @param text the String to resolve
|
||||
* @param servletContext the servletContext to use for lookups.
|
||||
* @return the resolved String
|
||||
* @see SystemPropertyUtils#PLACEHOLDER_PREFIX
|
||||
* @see SystemPropertyUtils#PLACEHOLDER_SUFFIX
|
||||
* @see SystemPropertyUtils#resolvePlaceholders(String, boolean)
|
||||
* @throws IllegalArgumentException if there is an unresolvable placeholder
|
||||
*/
|
||||
public static String resolvePlaceholders(String text, ServletContext servletContext) {
|
||||
return resolvePlaceholders(text, servletContext, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve ${...} placeholders in the given text, replacing them with corresponding
|
||||
* servlet context init parameter or system property values. Unresolvable placeholders
|
||||
* with no default value are ignored and passed through unchanged if the flag is set to true.
|
||||
* @param text the String to resolve
|
||||
* @param servletContext the servletContext to use for lookups.
|
||||
* @param ignoreUnresolvablePlaceholders flag to determine is unresolved placeholders are ignored
|
||||
* @return the resolved String
|
||||
* @see SystemPropertyUtils#PLACEHOLDER_PREFIX
|
||||
* @see SystemPropertyUtils#PLACEHOLDER_SUFFIX
|
||||
* @see SystemPropertyUtils#resolvePlaceholders(String, boolean)
|
||||
* @throws IllegalArgumentException if there is an unresolvable placeholder and the flag is false
|
||||
*/
|
||||
public static String resolvePlaceholders(String text, ServletContext servletContext, boolean ignoreUnresolvablePlaceholders) {
|
||||
PropertyPlaceholderHelper helper = (ignoreUnresolvablePlaceholders ? nonStrictHelper : strictHelper);
|
||||
return helper.replacePlaceholders(text, new ServletContextPlaceholderResolver(text, servletContext));
|
||||
}
|
||||
|
||||
|
||||
private static class ServletContextPlaceholderResolver implements PropertyPlaceholderHelper.PlaceholderResolver {
|
||||
|
||||
private final String text;
|
||||
|
||||
private final ServletContext servletContext;
|
||||
|
||||
public ServletContextPlaceholderResolver(String text, ServletContext servletContext) {
|
||||
this.text = text;
|
||||
this.servletContext = servletContext;
|
||||
}
|
||||
|
||||
public String resolvePlaceholder(String placeholderName) {
|
||||
try {
|
||||
String propVal = this.servletContext.getInitParameter(placeholderName);
|
||||
if (propVal == null) {
|
||||
// Fall back to system properties.
|
||||
propVal = System.getProperty(placeholderName);
|
||||
if (propVal == null) {
|
||||
// Fall back to searching the system environment.
|
||||
propVal = System.getenv(placeholderName);
|
||||
}
|
||||
}
|
||||
return propVal;
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
System.err.println("Could not resolve placeholder '" + placeholderName + "' in [" +
|
||||
this.text + "] as ServletContext init-parameter or system property: " + ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.web.util;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
@@ -38,7 +39,7 @@ import org.springframework.util.MultiValueMap;
|
||||
* @since 3.1
|
||||
* @see UriComponentsBuilder
|
||||
*/
|
||||
public abstract class UriComponents {
|
||||
public abstract class UriComponents implements Serializable {
|
||||
|
||||
private static final String DEFAULT_ENCODING = "UTF-8";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,7 +18,7 @@ package org.springframework.web.util;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
@@ -29,6 +29,7 @@ import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.util.HierarchicalUriComponents.PathComponent;
|
||||
|
||||
/**
|
||||
* Builder for {@link UriComponents}.
|
||||
@@ -46,6 +47,7 @@ import org.springframework.util.StringUtils;
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Phillip Webb
|
||||
* @since 3.1
|
||||
* @see #newInstance()
|
||||
* @see #fromPath(String)
|
||||
@@ -53,7 +55,7 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class UriComponentsBuilder {
|
||||
|
||||
private static final Pattern QUERY_PARAM_PATTERN = Pattern.compile("([^&=]+)=?([^&]+)?");
|
||||
private static final Pattern QUERY_PARAM_PATTERN = Pattern.compile("([^&=]+)(=?)([^&]+)?");
|
||||
|
||||
private static final String SCHEME_PATTERN = "([^:/?#]+):";
|
||||
|
||||
@@ -91,7 +93,7 @@ public class UriComponentsBuilder {
|
||||
|
||||
private int port = -1;
|
||||
|
||||
private PathComponentBuilder pathBuilder = NULL_PATH_COMPONENT_BUILDER;
|
||||
private CompositePathComponentBuilder pathBuilder = new CompositePathComponentBuilder();
|
||||
|
||||
private final MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<String, String>();
|
||||
|
||||
@@ -334,7 +336,7 @@ public class UriComponentsBuilder {
|
||||
this.port = uri.getPort();
|
||||
}
|
||||
if (StringUtils.hasLength(uri.getRawPath())) {
|
||||
this.pathBuilder = new FullPathComponentBuilder(uri.getRawPath());
|
||||
this.pathBuilder = new CompositePathComponentBuilder(uri.getRawPath());
|
||||
}
|
||||
if (StringUtils.hasLength(uri.getRawQuery())) {
|
||||
this.queryParams.clear();
|
||||
@@ -352,7 +354,7 @@ public class UriComponentsBuilder {
|
||||
this.userInfo = null;
|
||||
this.host = null;
|
||||
this.port = -1;
|
||||
this.pathBuilder = NULL_PATH_COMPONENT_BUILDER;
|
||||
this.pathBuilder = new CompositePathComponentBuilder();
|
||||
this.queryParams.clear();
|
||||
}
|
||||
|
||||
@@ -436,12 +438,7 @@ public class UriComponentsBuilder {
|
||||
* @return this UriComponentsBuilder
|
||||
*/
|
||||
public UriComponentsBuilder path(String path) {
|
||||
if (path != null) {
|
||||
this.pathBuilder = this.pathBuilder.appendPath(path);
|
||||
}
|
||||
else {
|
||||
this.pathBuilder = NULL_PATH_COMPONENT_BUILDER;
|
||||
}
|
||||
this.pathBuilder.addPath(path);
|
||||
resetSchemeSpecificPart();
|
||||
return this;
|
||||
}
|
||||
@@ -453,22 +450,21 @@ public class UriComponentsBuilder {
|
||||
* @return this UriComponentsBuilder
|
||||
*/
|
||||
public UriComponentsBuilder replacePath(String path) {
|
||||
this.pathBuilder = NULL_PATH_COMPONENT_BUILDER;
|
||||
path(path);
|
||||
this.pathBuilder = new CompositePathComponentBuilder(path);
|
||||
resetSchemeSpecificPart();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the given path segments to the existing path of this builder. Each given path segments may contain URI
|
||||
* template variables.
|
||||
* Appends the given path segments to the existing path of this builder. Each given
|
||||
* path segments may contain URI template variables.
|
||||
*
|
||||
* @param pathSegments the URI path segments
|
||||
* @return this UriComponentsBuilder
|
||||
*/
|
||||
public UriComponentsBuilder pathSegment(String... pathSegments) throws IllegalArgumentException {
|
||||
Assert.notNull(pathSegments, "'segments' must not be null");
|
||||
this.pathBuilder = this.pathBuilder.appendPathSegments(pathSegments);
|
||||
this.pathBuilder.addPathSegments(pathSegments);
|
||||
resetSchemeSpecificPart();
|
||||
return this;
|
||||
}
|
||||
@@ -496,8 +492,10 @@ public class UriComponentsBuilder {
|
||||
Matcher m = QUERY_PARAM_PATTERN.matcher(query);
|
||||
while (m.find()) {
|
||||
String name = m.group(1);
|
||||
String value = m.group(2);
|
||||
queryParam(name, value);
|
||||
String eq = m.group(2);
|
||||
String value = m.group(3);
|
||||
queryParam(name, (value != null ? value :
|
||||
(StringUtils.hasLength(eq) ? "" : null)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -588,131 +586,122 @@ public class UriComponentsBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a builder for {@link HierarchicalUriComponents.PathComponent}
|
||||
*/
|
||||
|
||||
private interface PathComponentBuilder {
|
||||
|
||||
HierarchicalUriComponents.PathComponent build();
|
||||
|
||||
PathComponentBuilder appendPath(String path);
|
||||
|
||||
PathComponentBuilder appendPathSegments(String... pathSegments);
|
||||
PathComponent build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a builder for full string paths.
|
||||
*/
|
||||
private static class FullPathComponentBuilder implements PathComponentBuilder {
|
||||
private static class CompositePathComponentBuilder implements PathComponentBuilder {
|
||||
|
||||
private final StringBuilder path;
|
||||
private LinkedList<PathComponentBuilder> componentBuilders = new LinkedList<PathComponentBuilder>();
|
||||
|
||||
private FullPathComponentBuilder(String path) {
|
||||
this.path = new StringBuilder(path);
|
||||
public CompositePathComponentBuilder() {
|
||||
}
|
||||
|
||||
public HierarchicalUriComponents.PathComponent build() {
|
||||
return new HierarchicalUriComponents.FullPathComponent(path.toString());
|
||||
public CompositePathComponentBuilder(String path) {
|
||||
addPath(path);
|
||||
}
|
||||
|
||||
public PathComponentBuilder appendPath(String path) {
|
||||
this.path.append(path);
|
||||
return this;
|
||||
public void addPathSegments(String... pathSegments) {
|
||||
if (!ObjectUtils.isEmpty(pathSegments)) {
|
||||
PathSegmentComponentBuilder psBuilder = getLastBuilder(PathSegmentComponentBuilder.class);
|
||||
FullPathComponentBuilder fpBuilder = getLastBuilder(FullPathComponentBuilder.class);
|
||||
if (psBuilder == null) {
|
||||
psBuilder = new PathSegmentComponentBuilder();
|
||||
this.componentBuilders.add(psBuilder);
|
||||
if (fpBuilder != null) {
|
||||
fpBuilder.removeTrailingSlash();
|
||||
}
|
||||
}
|
||||
psBuilder.append(pathSegments);
|
||||
}
|
||||
}
|
||||
|
||||
public PathComponentBuilder appendPathSegments(String... pathSegments) {
|
||||
PathComponentCompositeBuilder builder = new PathComponentCompositeBuilder(this);
|
||||
builder.appendPathSegments(pathSegments);
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a builder for paths segment paths.
|
||||
*/
|
||||
private static class PathSegmentComponentBuilder implements PathComponentBuilder {
|
||||
|
||||
private final List<String> pathSegments = new ArrayList<String>();
|
||||
|
||||
private PathSegmentComponentBuilder(String... pathSegments) {
|
||||
this.pathSegments.addAll(removeEmptyPathSegments(pathSegments));
|
||||
public void addPath(String path) {
|
||||
if (StringUtils.hasText(path)) {
|
||||
PathSegmentComponentBuilder psBuilder = getLastBuilder(PathSegmentComponentBuilder.class);
|
||||
FullPathComponentBuilder fpBuilder = getLastBuilder(FullPathComponentBuilder.class);
|
||||
if (psBuilder != null) {
|
||||
path = path.startsWith("/") ? path : "/" + path;
|
||||
}
|
||||
if (fpBuilder == null) {
|
||||
fpBuilder = new FullPathComponentBuilder();
|
||||
this.componentBuilders.add(fpBuilder);
|
||||
}
|
||||
fpBuilder.append(path);
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<String> removeEmptyPathSegments(String... pathSegments) {
|
||||
List<String> result = new ArrayList<String>();
|
||||
for (String segment : pathSegments) {
|
||||
if (StringUtils.hasText(segment)) {
|
||||
result.add(segment);
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T getLastBuilder(Class<T> builderClass) {
|
||||
if (!this.componentBuilders.isEmpty()) {
|
||||
PathComponentBuilder last = this.componentBuilders.getLast();
|
||||
if (builderClass.isInstance(last)) {
|
||||
return (T) last;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return null;
|
||||
}
|
||||
|
||||
public HierarchicalUriComponents.PathComponent build() {
|
||||
return new HierarchicalUriComponents.PathSegmentComponent(pathSegments);
|
||||
}
|
||||
|
||||
public PathComponentBuilder appendPath(String path) {
|
||||
PathComponentCompositeBuilder builder = new PathComponentCompositeBuilder(this);
|
||||
builder.appendPath(path);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public PathComponentBuilder appendPathSegments(String... pathSegments) {
|
||||
this.pathSegments.addAll(removeEmptyPathSegments(pathSegments));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a builder for a collection of PathComponents.
|
||||
*/
|
||||
private static class PathComponentCompositeBuilder implements PathComponentBuilder {
|
||||
|
||||
private final List<PathComponentBuilder> pathComponentBuilders = new ArrayList<PathComponentBuilder>();
|
||||
|
||||
private PathComponentCompositeBuilder(PathComponentBuilder builder) {
|
||||
pathComponentBuilders.add(builder);
|
||||
}
|
||||
|
||||
public HierarchicalUriComponents.PathComponent build() {
|
||||
List<HierarchicalUriComponents.PathComponent> pathComponents =
|
||||
new ArrayList<HierarchicalUriComponents.PathComponent>(pathComponentBuilders.size());
|
||||
|
||||
for (PathComponentBuilder pathComponentBuilder : pathComponentBuilders) {
|
||||
pathComponents.add(pathComponentBuilder.build());
|
||||
public PathComponent build() {
|
||||
int size = this.componentBuilders.size();
|
||||
List<PathComponent> components = new ArrayList<PathComponent>(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
PathComponent pathComponent = this.componentBuilders.get(i).build();
|
||||
if (pathComponent != null) {
|
||||
components.add(pathComponent);
|
||||
}
|
||||
}
|
||||
return new HierarchicalUriComponents.PathComponentComposite(pathComponents);
|
||||
}
|
||||
|
||||
public PathComponentBuilder appendPath(String path) {
|
||||
this.pathComponentBuilders.add(new FullPathComponentBuilder(path));
|
||||
return this;
|
||||
}
|
||||
|
||||
public PathComponentBuilder appendPathSegments(String... pathSegments) {
|
||||
this.pathComponentBuilders.add(new PathSegmentComponentBuilder(pathSegments));
|
||||
return this;
|
||||
if (components.isEmpty()) {
|
||||
return HierarchicalUriComponents.NULL_PATH_COMPONENT;
|
||||
}
|
||||
if (components.size() == 1) {
|
||||
return components.get(0);
|
||||
}
|
||||
return new HierarchicalUriComponents.PathComponentComposite(components);
|
||||
}
|
||||
}
|
||||
|
||||
private static class FullPathComponentBuilder implements PathComponentBuilder {
|
||||
|
||||
/**
|
||||
* Represents a builder for an empty path.
|
||||
*/
|
||||
private static PathComponentBuilder NULL_PATH_COMPONENT_BUILDER = new PathComponentBuilder() {
|
||||
private StringBuilder path = new StringBuilder();
|
||||
|
||||
public HierarchicalUriComponents.PathComponent build() {
|
||||
return HierarchicalUriComponents.NULL_PATH_COMPONENT;
|
||||
public void append(String path) {
|
||||
this.path.append(path);
|
||||
}
|
||||
|
||||
public PathComponentBuilder appendPath(String path) {
|
||||
return new FullPathComponentBuilder(path);
|
||||
public PathComponent build() {
|
||||
if (this.path.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
String path = this.path.toString().replace("//", "/");
|
||||
return new HierarchicalUriComponents.FullPathComponent(path);
|
||||
}
|
||||
|
||||
public PathComponentBuilder appendPathSegments(String... pathSegments) {
|
||||
return new PathSegmentComponentBuilder(pathSegments);
|
||||
public void removeTrailingSlash() {
|
||||
int index = this.path.length() - 1;
|
||||
if (this.path.charAt(index) == '/') {
|
||||
this.path.deleteCharAt(index);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static class PathSegmentComponentBuilder implements PathComponentBuilder {
|
||||
|
||||
private List<String> pathSegments = new LinkedList<String>();
|
||||
|
||||
public void append(String... pathSegments) {
|
||||
for (String pathSegment : pathSegments) {
|
||||
if (StringUtils.hasText(pathSegment)) {
|
||||
this.pathSegments.add(pathSegment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public PathComponent build() {
|
||||
return this.pathSegments.isEmpty() ?
|
||||
null : new HierarchicalUriComponents.PathSegmentComponent(this.pathSegments);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,7 +32,7 @@ import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Represents a URI template. A URI template is a URI-like String that contains variables enclosed
|
||||
* by braces ({@code {}, {@code }}), which can be expanded to produce an actual URI.
|
||||
* by braces ({@code {}}), which can be expanded to produce an actual URI.
|
||||
*
|
||||
* <p>See {@link #expand(Map)}, {@link #expand(Object[])}, and {@link #match(String)} for example usages.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,6 +27,8 @@ import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -439,10 +441,8 @@ public class UrlPathHelper {
|
||||
* @return the updated URI string
|
||||
*/
|
||||
public String removeSemicolonContent(String requestUri) {
|
||||
if (this.removeSemicolonContent) {
|
||||
return removeSemicolonContentInternal(requestUri);
|
||||
}
|
||||
return removeJsessionid(requestUri);
|
||||
return this.removeSemicolonContent ?
|
||||
removeSemicolonContentInternal(requestUri) : removeJsessionid(requestUri);
|
||||
}
|
||||
|
||||
private String removeSemicolonContentInternal(String requestUri) {
|
||||
@@ -491,6 +491,33 @@ public class UrlPathHelper {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode the given matrix variables via
|
||||
* {@link #decodeRequestString(HttpServletRequest, String)} unless
|
||||
* {@link #setUrlDecode(boolean)} is set to {@code true} in which case it is
|
||||
* assumed the URL path from which the variables were extracted is already
|
||||
* decoded through a call to
|
||||
* {@link #getLookupPathForRequest(HttpServletRequest)}.
|
||||
*
|
||||
* @param request current HTTP request
|
||||
* @param vars URI variables extracted from the URL path
|
||||
* @return the same Map or a new Map instance
|
||||
*/
|
||||
public MultiValueMap<String, String> decodeMatrixVariables(HttpServletRequest request, MultiValueMap<String, String> vars) {
|
||||
if (this.urlDecode) {
|
||||
return vars;
|
||||
}
|
||||
else {
|
||||
MultiValueMap<String, String> decodedVars = new LinkedMultiValueMap <String, String>(vars.size());
|
||||
for (String key : vars.keySet()) {
|
||||
for (String value : vars.get(key)) {
|
||||
decodedVars.add(key, decodeInternal(request, value));
|
||||
}
|
||||
}
|
||||
return decodedVars;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldRemoveTrailingServletPathSlash(HttpServletRequest request) {
|
||||
if (request.getAttribute(WEBSPHERE_URI_ATTRIBUTE) == null) {
|
||||
// Regular servlet container: behaves as expected in any case,
|
||||
|
||||
Reference in New Issue
Block a user