Browse Source

Polishing

pull/23967/head
Juergen Hoeller 5 years ago
parent
commit
db48b546ac
  1. 7
      spring-core/src/main/java/org/springframework/util/MimeType.java
  2. 6
      spring-jms/src/main/java/org/springframework/jms/support/converter/MappingJackson2MessageConverter.java
  3. 42
      spring-messaging/src/main/java/org/springframework/messaging/converter/AbstractMessageConverter.java
  4. 8
      spring-messaging/src/main/java/org/springframework/messaging/converter/MappingJackson2MessageConverter.java
  5. 7
      spring-messaging/src/main/java/org/springframework/messaging/converter/MarshallingMessageConverter.java
  6. 18
      spring-messaging/src/test/java/org/springframework/messaging/converter/MappingJackson2MessageConverterTests.java
  7. 2
      spring-web/src/main/java/org/springframework/http/codec/json/AbstractJackson2Decoder.java
  8. 4
      spring-web/src/main/java/org/springframework/http/codec/json/Jackson2CodecSupport.java
  9. 6
      spring-web/src/main/java/org/springframework/http/converter/HttpMessageConverter.java
  10. 4
      spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java
  11. 12
      spring-web/src/main/java/org/springframework/web/client/RestTemplate.java
  12. 17
      spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java

7
spring-core/src/main/java/org/springframework/util/MimeType.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2019 the original author or authors. * Copyright 2002-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -194,7 +194,7 @@ public class MimeType implements Comparable<MimeType>, Serializable {
* @see <a href="https://tools.ietf.org/html/rfc2616#section-2.2">HTTP 1.1, section 2.2</a> * @see <a href="https://tools.ietf.org/html/rfc2616#section-2.2">HTTP 1.1, section 2.2</a>
*/ */
private void checkToken(String token) { private void checkToken(String token) {
for (int i = 0; i < token.length(); i++ ) { for (int i = 0; i < token.length(); i++) {
char ch = token.charAt(i); char ch = token.charAt(i);
if (!TOKEN.get(ch)) { if (!TOKEN.get(ch)) {
throw new IllegalArgumentException("Invalid token character '" + ch + "' in token \"" + token + "\""); throw new IllegalArgumentException("Invalid token character '" + ch + "' in token \"" + token + "\"");
@ -207,8 +207,7 @@ public class MimeType implements Comparable<MimeType>, Serializable {
Assert.hasLength(value, "'value' must not be empty"); Assert.hasLength(value, "'value' must not be empty");
checkToken(attribute); checkToken(attribute);
if (PARAM_CHARSET.equals(attribute)) { if (PARAM_CHARSET.equals(attribute)) {
value = unquote(value); Charset.forName(unquote(value));
Charset.forName(value);
} }
else if (!isQuotedString(value)) { else if (!isQuotedString(value)) {
checkToken(value); checkToken(value);

6
spring-jms/src/main/java/org/springframework/jms/support/converter/MappingJackson2MessageConverter.java

@ -123,7 +123,7 @@ public class MappingJackson2MessageConverter implements SmartMessageConverter, B
/** /**
* Specify the encoding to use when converting to and from text-based * Specify the encoding to use when converting to and from text-based
* message body content. The default encoding will be "UTF-8". * message body content. The default encoding will be "UTF-8".
* <p>When reading from a a text-based message, an encoding may have been * <p>When reading from a text-based message, an encoding may have been
* suggested through a special JMS property which will then be preferred * suggested through a special JMS property which will then be preferred
* over the encoding set on this MessageConverter instance. * over the encoding set on this MessageConverter instance.
* @see #setEncodingPropertyName * @see #setEncodingPropertyName
@ -457,11 +457,11 @@ public class MappingJackson2MessageConverter implements SmartMessageConverter, B
} }
Class<?> mappedClass = this.idClassMappings.get(typeId); Class<?> mappedClass = this.idClassMappings.get(typeId);
if (mappedClass != null) { if (mappedClass != null) {
return this.objectMapper.getTypeFactory().constructType(mappedClass); return this.objectMapper.constructType(mappedClass);
} }
try { try {
Class<?> typeClass = ClassUtils.forName(typeId, this.beanClassLoader); Class<?> typeClass = ClassUtils.forName(typeId, this.beanClassLoader);
return this.objectMapper.getTypeFactory().constructType(typeClass); return this.objectMapper.constructType(typeClass);
} }
catch (Throwable ex) { catch (Throwable ex) {
throw new MessageConversionException("Failed to resolve type id [" + typeId + "]", ex); throw new MessageConversionException("Failed to resolve type id [" + typeId + "]", ex);

42
spring-messaging/src/main/java/org/springframework/messaging/converter/AbstractMessageConverter.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2017 the original author or authors. * Copyright 2002-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -151,21 +151,6 @@ public abstract class AbstractMessageConverter implements SmartMessageConverter
} }
/**
* Returns the default content type for the payload. Called when
* {@link #toMessage(Object, MessageHeaders)} is invoked without message headers or
* without a content type header.
* <p>By default, this returns the first element of the {@link #getSupportedMimeTypes()
* supportedMimeTypes}, if any. Can be overridden in sub-classes.
* @param payload the payload being converted to message
* @return the content type, or {@code null} if not known
*/
@Nullable
protected MimeType getDefaultContentType(Object payload) {
List<MimeType> mimeTypes = getSupportedMimeTypes();
return (!mimeTypes.isEmpty() ? mimeTypes.get(0) : null);
}
@Override @Override
@Nullable @Nullable
public final Object fromMessage(Message<?> message, Class<?> targetClass) { public final Object fromMessage(Message<?> message, Class<?> targetClass) {
@ -181,10 +166,6 @@ public abstract class AbstractMessageConverter implements SmartMessageConverter
return convertFromInternal(message, targetClass, conversionHint); return convertFromInternal(message, targetClass, conversionHint);
} }
protected boolean canConvertFrom(Message<?> message, Class<?> targetClass) {
return (supports(targetClass) && supportsMimeType(message.getHeaders()));
}
@Override @Override
@Nullable @Nullable
public final Message<?> toMessage(Object payload, @Nullable MessageHeaders headers) { public final Message<?> toMessage(Object payload, @Nullable MessageHeaders headers) {
@ -224,6 +205,11 @@ public abstract class AbstractMessageConverter implements SmartMessageConverter
return builder.build(); return builder.build();
} }
protected boolean canConvertFrom(Message<?> message, Class<?> targetClass) {
return (supports(targetClass) && supportsMimeType(message.getHeaders()));
}
protected boolean canConvertTo(Object payload, @Nullable MessageHeaders headers) { protected boolean canConvertTo(Object payload, @Nullable MessageHeaders headers) {
return (supports(payload.getClass()) && supportsMimeType(headers)); return (supports(payload.getClass()) && supportsMimeType(headers));
} }
@ -249,6 +235,22 @@ public abstract class AbstractMessageConverter implements SmartMessageConverter
return (headers != null && this.contentTypeResolver != null ? this.contentTypeResolver.resolve(headers) : null); return (headers != null && this.contentTypeResolver != null ? this.contentTypeResolver.resolve(headers) : null);
} }
/**
* Return the default content type for the payload. Called when
* {@link #toMessage(Object, MessageHeaders)} is invoked without
* message headers or without a content type header.
* <p>By default, this returns the first element of the
* {@link #getSupportedMimeTypes() supportedMimeTypes}, if any.
* Can be overridden in subclasses.
* @param payload the payload being converted to a message
* @return the content type, or {@code null} if not known
*/
@Nullable
protected MimeType getDefaultContentType(Object payload) {
List<MimeType> mimeTypes = getSupportedMimeTypes();
return (!mimeTypes.isEmpty() ? mimeTypes.get(0) : null);
}
/** /**
* Whether the given class is supported by this converter. * Whether the given class is supported by this converter.

8
spring-messaging/src/main/java/org/springframework/messaging/converter/MappingJackson2MessageConverter.java

@ -43,6 +43,7 @@ import org.springframework.lang.Nullable;
import org.springframework.messaging.Message; import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders; import org.springframework.messaging.MessageHeaders;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.MimeType; import org.springframework.util.MimeType;
/** /**
@ -141,6 +142,7 @@ public class MappingJackson2MessageConverter extends AbstractMessageConverter {
} }
} }
@Override @Override
protected boolean canConvertFrom(Message<?> message, @Nullable Class<?> targetClass) { protected boolean canConvertFrom(Message<?> message, @Nullable Class<?> targetClass) {
if (targetClass == null || !supportsMimeType(message.getHeaders())) { if (targetClass == null || !supportsMimeType(message.getHeaders())) {
@ -212,7 +214,7 @@ public class MappingJackson2MessageConverter extends AbstractMessageConverter {
Object payload = message.getPayload(); Object payload = message.getPayload();
Class<?> view = getSerializationView(conversionHint); Class<?> view = getSerializationView(conversionHint);
try { try {
if (targetClass.isInstance(payload)) { if (ClassUtils.isAssignableValue(targetClass, payload)) {
return payload; return payload;
} }
else if (payload instanceof byte[]) { else if (payload instanceof byte[]) {
@ -248,7 +250,7 @@ public class MappingJackson2MessageConverter extends AbstractMessageConverter {
Type genericParameterType = param.getNestedGenericParameterType(); Type genericParameterType = param.getNestedGenericParameterType();
Class<?> contextClass = param.getContainingClass(); Class<?> contextClass = param.getContainingClass();
Type type = GenericTypeResolver.resolveType(genericParameterType, contextClass); Type type = GenericTypeResolver.resolveType(genericParameterType, contextClass);
return this.objectMapper.getTypeFactory().constructType(type); return this.objectMapper.constructType(type);
} }
return this.objectMapper.constructType(targetClass); return this.objectMapper.constructType(targetClass);
} }
@ -333,7 +335,7 @@ public class MappingJackson2MessageConverter extends AbstractMessageConverter {
* @return the JSON encoding to use (never {@code null}) * @return the JSON encoding to use (never {@code null})
*/ */
protected JsonEncoding getJsonEncoding(@Nullable MimeType contentType) { protected JsonEncoding getJsonEncoding(@Nullable MimeType contentType) {
if (contentType != null && (contentType.getCharset() != null)) { if (contentType != null && contentType.getCharset() != null) {
Charset charset = contentType.getCharset(); Charset charset = contentType.getCharset();
for (JsonEncoding encoding : JsonEncoding.values()) { for (JsonEncoding encoding : JsonEncoding.values()) {
if (charset.name().equals(encoding.getJavaName())) { if (charset.name().equals(encoding.getJavaName())) {

7
spring-messaging/src/main/java/org/springframework/messaging/converter/MarshallingMessageConverter.java

@ -47,6 +47,8 @@ import org.springframework.util.MimeType;
* *
* @author Arjen Poutsma * @author Arjen Poutsma
* @since 4.2 * @since 4.2
* @see Marshaller
* @see Unmarshaller
*/ */
public class MarshallingMessageConverter extends AbstractMessageConverter { public class MarshallingMessageConverter extends AbstractMessageConverter {
@ -62,7 +64,8 @@ public class MarshallingMessageConverter extends AbstractMessageConverter {
* {@link #setUnmarshaller(Unmarshaller)} to be invoked separately. * {@link #setUnmarshaller(Unmarshaller)} to be invoked separately.
*/ */
public MarshallingMessageConverter() { public MarshallingMessageConverter() {
this(new MimeType("application", "xml"), new MimeType("text", "xml"), new MimeType("application", "*+xml")); this(new MimeType("application", "xml"), new MimeType("text", "xml"),
new MimeType("application", "*+xml"));
} }
/** /**
@ -161,7 +164,7 @@ public class MarshallingMessageConverter extends AbstractMessageConverter {
return new StreamSource(new ByteArrayInputStream((byte[]) payload)); return new StreamSource(new ByteArrayInputStream((byte[]) payload));
} }
else { else {
return new StreamSource(new StringReader((String) payload)); return new StreamSource(new StringReader(payload.toString()));
} }
} }

18
spring-messaging/src/test/java/org/springframework/messaging/converter/MappingJackson2MessageConverterTests.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -75,13 +75,8 @@ public class MappingJackson2MessageConverterTests {
@Test @Test
public void fromMessage() { public void fromMessage() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(); MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
String payload = "{" + String payload = "{\"bytes\":\"AQI=\",\"array\":[\"Foo\",\"Bar\"]," +
"\"bytes\":\"AQI=\"," + "\"number\":42,\"string\":\"Foo\",\"bool\":true,\"fraction\":42.0}";
"\"array\":[\"Foo\",\"Bar\"]," +
"\"number\":42," +
"\"string\":\"Foo\"," +
"\"bool\":true," +
"\"fraction\":42.0}";
Message<?> message = MessageBuilder.withPayload(payload.getBytes(StandardCharsets.UTF_8)).build(); Message<?> message = MessageBuilder.withPayload(payload.getBytes(StandardCharsets.UTF_8)).build();
MyBean actual = (MyBean) converter.fromMessage(message, MyBean.class); MyBean actual = (MyBean) converter.fromMessage(message, MyBean.class);
@ -245,9 +240,12 @@ public class MappingJackson2MessageConverterTests {
public void jsonViewPayload(@JsonView(MyJacksonView2.class) JacksonViewBean payload) { public void jsonViewPayload(@JsonView(MyJacksonView2.class) JacksonViewBean payload) {
} }
void handleList(List<Long> payload) {} void handleList(List<Long> payload) {
}
void handleMessage(Message<MyBean> message) {
}
void handleMessage(Message<MyBean> message) {}
public static class MyBean { public static class MyBean {

2
spring-web/src/main/java/org/springframework/http/codec/json/AbstractJackson2Decoder.java

@ -105,7 +105,7 @@ public abstract class AbstractJackson2Decoder extends Jackson2CodecSupport imple
@Override @Override
public boolean canDecode(ResolvableType elementType, @Nullable MimeType mimeType) { public boolean canDecode(ResolvableType elementType, @Nullable MimeType mimeType) {
JavaType javaType = getObjectMapper().getTypeFactory().constructType(elementType.getType()); JavaType javaType = getObjectMapper().constructType(elementType.getType());
// Skip String: CharSequenceDecoder + "*/*" comes after // Skip String: CharSequenceDecoder + "*/*" comes after
return (!CharSequence.class.isAssignableFrom(elementType.toClass()) && return (!CharSequence.class.isAssignableFrom(elementType.toClass()) &&
getObjectMapper().canDeserialize(javaType) && supportsMimeType(mimeType)); getObjectMapper().canDeserialize(javaType) && supportsMimeType(mimeType));

4
spring-web/src/main/java/org/springframework/http/codec/json/Jackson2CodecSupport.java

@ -27,7 +27,6 @@ import java.util.Map;
import com.fasterxml.jackson.annotation.JsonView; import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.springframework.core.GenericTypeResolver; import org.springframework.core.GenericTypeResolver;
@ -100,8 +99,7 @@ public abstract class Jackson2CodecSupport {
} }
protected JavaType getJavaType(Type type, @Nullable Class<?> contextClass) { protected JavaType getJavaType(Type type, @Nullable Class<?> contextClass) {
TypeFactory typeFactory = this.objectMapper.getTypeFactory(); return this.objectMapper.constructType(GenericTypeResolver.resolveType(type, contextClass));
return typeFactory.constructType(GenericTypeResolver.resolveType(type, contextClass));
} }
protected Map<String, Object> getHints(ResolvableType resolvableType) { protected Map<String, Object> getHints(ResolvableType resolvableType) {

6
spring-web/src/main/java/org/springframework/http/converter/HttpMessageConverter.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -25,7 +25,7 @@ import org.springframework.http.MediaType;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
/** /**
* Strategy interface that specifies a converter that can convert from and to HTTP requests and responses. * Strategy interface for converting from and to HTTP requests and responses.
* *
* @author Arjen Poutsma * @author Arjen Poutsma
* @author Juergen Hoeller * @author Juergen Hoeller
@ -54,7 +54,7 @@ public interface HttpMessageConverter<T> {
/** /**
* Return the list of {@link MediaType} objects supported by this converter. * Return the list of {@link MediaType} objects supported by this converter.
* @return the list of supported media types * @return the list of supported media types, potentially an immutable copy
*/ */
List<MediaType> getSupportedMediaTypes(); List<MediaType> getSupportedMediaTypes();

4
spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java

@ -43,7 +43,6 @@ import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.exc.InvalidDefinitionException; import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
import com.fasterxml.jackson.databind.ser.FilterProvider; import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.type.TypeFactory;
import org.springframework.core.GenericTypeResolver; import org.springframework.core.GenericTypeResolver;
import org.springframework.http.HttpInputMessage; import org.springframework.http.HttpInputMessage;
@ -376,8 +375,7 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractGener
* @return the Jackson JavaType * @return the Jackson JavaType
*/ */
protected JavaType getJavaType(Type type, @Nullable Class<?> contextClass) { protected JavaType getJavaType(Type type, @Nullable Class<?> contextClass) {
TypeFactory typeFactory = this.objectMapper.getTypeFactory(); return this.objectMapper.constructType(GenericTypeResolver.resolveType(type, contextClass));
return typeFactory.constructType(GenericTypeResolver.resolveType(type, contextClass));
} }
/** /**

12
spring-web/src/main/java/org/springframework/web/client/RestTemplate.java

@ -21,7 +21,6 @@ import java.lang.reflect.Type;
import java.net.URI; import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -109,9 +108,8 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat
ClassLoader classLoader = RestTemplate.class.getClassLoader(); ClassLoader classLoader = RestTemplate.class.getClassLoader();
romePresent = ClassUtils.isPresent("com.rometools.rome.feed.WireFeed", classLoader); romePresent = ClassUtils.isPresent("com.rometools.rome.feed.WireFeed", classLoader);
jaxb2Present = ClassUtils.isPresent("javax.xml.bind.Binder", classLoader); jaxb2Present = ClassUtils.isPresent("javax.xml.bind.Binder", classLoader);
jackson2Present = jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) &&
ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) && ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader);
ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader);
jackson2XmlPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper", classLoader); jackson2XmlPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper", classLoader);
jackson2SmilePresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.smile.SmileFactory", classLoader); jackson2SmilePresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.smile.SmileFactory", classLoader);
jackson2CborPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.cbor.CBORFactory", classLoader); jackson2CborPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.cbor.CBORFactory", classLoader);
@ -912,7 +910,7 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat
HttpHeaders httpHeaders = httpRequest.getHeaders(); HttpHeaders httpHeaders = httpRequest.getHeaders();
HttpHeaders requestHeaders = this.requestEntity.getHeaders(); HttpHeaders requestHeaders = this.requestEntity.getHeaders();
if (!requestHeaders.isEmpty()) { if (!requestHeaders.isEmpty()) {
requestHeaders.forEach((key, values) -> httpHeaders.put(key, new LinkedList<>(values))); requestHeaders.forEach((key, values) -> httpHeaders.put(key, new ArrayList<>(values)));
} }
if (httpHeaders.getContentLength() < 0) { if (httpHeaders.getContentLength() < 0) {
httpHeaders.setContentLength(0L); httpHeaders.setContentLength(0L);
@ -931,7 +929,7 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat
(GenericHttpMessageConverter<Object>) messageConverter; (GenericHttpMessageConverter<Object>) messageConverter;
if (genericConverter.canWrite(requestBodyType, requestBodyClass, requestContentType)) { if (genericConverter.canWrite(requestBodyType, requestBodyClass, requestContentType)) {
if (!requestHeaders.isEmpty()) { if (!requestHeaders.isEmpty()) {
requestHeaders.forEach((key, values) -> httpHeaders.put(key, new LinkedList<>(values))); requestHeaders.forEach((key, values) -> httpHeaders.put(key, new ArrayList<>(values)));
} }
logBody(requestBody, requestContentType, genericConverter); logBody(requestBody, requestContentType, genericConverter);
genericConverter.write(requestBody, requestBodyType, requestContentType, httpRequest); genericConverter.write(requestBody, requestBodyType, requestContentType, httpRequest);
@ -940,7 +938,7 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat
} }
else if (messageConverter.canWrite(requestBodyClass, requestContentType)) { else if (messageConverter.canWrite(requestBodyClass, requestContentType)) {
if (!requestHeaders.isEmpty()) { if (!requestHeaders.isEmpty()) {
requestHeaders.forEach((key, values) -> httpHeaders.put(key, new LinkedList<>(values))); requestHeaders.forEach((key, values) -> httpHeaders.put(key, new ArrayList<>(values)));
} }
logBody(requestBody, requestContentType, messageConverter); logBody(requestBody, requestContentType, messageConverter);
((HttpMessageConverter<Object>) messageConverter).write( ((HttpMessageConverter<Object>) messageConverter).write(

17
spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java

@ -233,7 +233,7 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable {
} }
builder.scheme(scheme); builder.scheme(scheme);
if (opaque) { if (opaque) {
String ssp = uri.substring(scheme.length()).substring(1); String ssp = uri.substring(scheme.length() + 1);
if (StringUtils.hasLength(fragment)) { if (StringUtils.hasLength(fragment)) {
ssp = ssp.substring(0, ssp.length() - (fragment.length() + 1)); ssp = ssp.substring(0, ssp.length() - (fragment.length() + 1));
} }
@ -394,9 +394,8 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable {
* characters that should have been encoded. * characters that should have been encoded.
*/ */
public UriComponents build(boolean encoded) { public UriComponents build(boolean encoded) {
return buildInternal(encoded ? return buildInternal(encoded ? EncodingHint.FULLY_ENCODED :
EncodingHint.FULLY_ENCODED : (this.encodeTemplate ? EncodingHint.ENCODE_TEMPLATE : EncodingHint.NONE));
this.encodeTemplate ? EncodingHint.ENCODE_TEMPLATE : EncodingHint.NONE);
} }
private UriComponents buildInternal(EncodingHint hint) { private UriComponents buildInternal(EncodingHint hint) {
@ -408,8 +407,7 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable {
HierarchicalUriComponents uric = new HierarchicalUriComponents(this.scheme, this.fragment, HierarchicalUriComponents uric = new HierarchicalUriComponents(this.scheme, this.fragment,
this.userInfo, this.host, this.port, this.pathBuilder.build(), this.queryParams, this.userInfo, this.host, this.port, this.pathBuilder.build(), this.queryParams,
hint == EncodingHint.FULLY_ENCODED); hint == EncodingHint.FULLY_ENCODED);
result = (hint == EncodingHint.ENCODE_TEMPLATE ? uric.encodeTemplate(this.charset) : uric);
result = hint == EncodingHint.ENCODE_TEMPLATE ? uric.encodeTemplate(this.charset) : uric;
} }
if (!this.uriVariables.isEmpty()) { if (!this.uriVariables.isEmpty()) {
result = result.expand(name -> this.uriVariables.getOrDefault(name, UriTemplateVariables.SKIP_VALUE)); result = result.expand(name -> this.uriVariables.getOrDefault(name, UriTemplateVariables.SKIP_VALUE));
@ -466,9 +464,8 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable {
* @see UriComponents#toUriString() * @see UriComponents#toUriString()
*/ */
public String toUriString() { public String toUriString() {
return this.uriVariables.isEmpty() ? return (this.uriVariables.isEmpty() ? build().encode().toUriString() :
build().encode().toUriString() : buildInternal(EncodingHint.ENCODE_TEMPLATE).toUriString());
buildInternal(EncodingHint.ENCODE_TEMPLATE).toUriString();
} }
@ -849,12 +846,10 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable {
scheme("https"); scheme("https");
port(null); port(null);
} }
String hostHeader = headers.getFirst("X-Forwarded-Host"); String hostHeader = headers.getFirst("X-Forwarded-Host");
if (StringUtils.hasText(hostHeader)) { if (StringUtils.hasText(hostHeader)) {
adaptForwardedHost(StringUtils.tokenizeToStringArray(hostHeader, ",")[0]); adaptForwardedHost(StringUtils.tokenizeToStringArray(hostHeader, ",")[0]);
} }
String portHeader = headers.getFirst("X-Forwarded-Port"); String portHeader = headers.getFirst("X-Forwarded-Port");
if (StringUtils.hasText(portHeader)) { if (StringUtils.hasText(portHeader)) {
port(Integer.parseInt(StringUtils.tokenizeToStringArray(portHeader, ",")[0])); port(Integer.parseInt(StringUtils.tokenizeToStringArray(portHeader, ",")[0]));

Loading…
Cancel
Save