Browse Source

Polishing

pull/1290/head
Juergen Hoeller 9 years ago
parent
commit
b5f2e56e38
  1. 2
      spring-core/src/main/java/org/springframework/core/Conventions.java
  2. 12
      spring-core/src/main/java/org/springframework/core/convert/support/CollectionToStringConverter.java
  3. 30
      spring-core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java
  4. 10
      spring-core/src/main/java/org/springframework/core/convert/support/ObjectToOptionalConverter.java
  5. 12
      spring-core/src/test/java/org/springframework/util/xml/AbstractStaxHandlerTestCase.java
  6. 5
      spring-core/src/test/java/org/springframework/util/xml/StaxEventHandlerTests.java
  7. 5
      spring-core/src/test/java/org/springframework/util/xml/StaxStreamHandlerTests.java
  8. 6
      spring-oxm/src/main/java/org/springframework/oxm/Marshaller.java
  9. 6
      spring-oxm/src/main/java/org/springframework/oxm/Unmarshaller.java
  10. 52
      spring-web/src/main/java/org/springframework/web/client/AsyncRestOperations.java
  11. 6
      spring-web/src/main/java/org/springframework/web/client/AsyncRestTemplate.java
  12. 6
      spring-web/src/main/java/org/springframework/web/method/annotation/ModelFactory.java
  13. 4
      spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java
  14. 7
      spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodProcessor.java
  15. 24
      spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java

2
spring-core/src/main/java/org/springframework/core/Conventions.java

@ -281,7 +281,7 @@ public abstract class Conventions {
/** /**
* Retrieves the {@code Class} of an element in the {@code Collection}. * Retrieves the {@code Class} of an element in the {@code Collection}.
* The exact element for which the {@code Class} is retreived will depend * The exact element for which the {@code Class} is retrieved will depend
* on the concrete {@code Collection} implementation. * on the concrete {@code Collection} implementation.
*/ */
private static <E> E peekAhead(Collection<E> collection) { private static <E> E peekAhead(Collection<E> collection) {

12
spring-core/src/main/java/org/springframework/core/convert/support/CollectionToStringConverter.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2016 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.
@ -36,10 +36,12 @@ final class CollectionToStringConverter implements ConditionalGenericConverter {
private final ConversionService conversionService; private final ConversionService conversionService;
public CollectionToStringConverter(ConversionService conversionService) { public CollectionToStringConverter(ConversionService conversionService) {
this.conversionService = conversionService; this.conversionService = conversionService;
} }
@Override @Override
public Set<ConvertiblePair> getConvertibleTypes() { public Set<ConvertiblePair> getConvertibleTypes() {
return Collections.singleton(new ConvertiblePair(Collection.class, String.class)); return Collections.singleton(new ConvertiblePair(Collection.class, String.class));
@ -47,7 +49,8 @@ final class CollectionToStringConverter implements ConditionalGenericConverter {
@Override @Override
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
return ConversionUtils.canConvertElements(sourceType.getElementTypeDescriptor(), targetType, this.conversionService); return ConversionUtils.canConvertElements(
sourceType.getElementTypeDescriptor(), targetType, this.conversionService);
} }
@Override @Override
@ -56,7 +59,7 @@ final class CollectionToStringConverter implements ConditionalGenericConverter {
return null; return null;
} }
Collection<?> sourceCollection = (Collection<?>) source; Collection<?> sourceCollection = (Collection<?>) source;
if (sourceCollection.size() == 0) { if (sourceCollection.isEmpty()) {
return ""; return "";
} }
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
@ -65,7 +68,8 @@ final class CollectionToStringConverter implements ConditionalGenericConverter {
if (i > 0) { if (i > 0) {
sb.append(DELIMITER); sb.append(DELIMITER);
} }
Object targetElement = this.conversionService.convert(sourceElement, sourceType.elementTypeDescriptor(sourceElement), targetType); Object targetElement = this.conversionService.convert(
sourceElement, sourceType.elementTypeDescriptor(sourceElement), targetType);
sb.append(targetElement); sb.append(targetElement);
i++; i++;
} }

30
spring-core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java

@ -145,14 +145,14 @@ public class GenericConversionService implements ConfigurableConversionService {
@Override @Override
public boolean canConvert(Class<?> sourceType, Class<?> targetType) { public boolean canConvert(Class<?> sourceType, Class<?> targetType) {
Assert.notNull(targetType, "targetType to convert to cannot be null"); Assert.notNull(targetType, "Target type to convert to cannot be null");
return canConvert((sourceType != null ? TypeDescriptor.valueOf(sourceType) : null), return canConvert((sourceType != null ? TypeDescriptor.valueOf(sourceType) : null),
TypeDescriptor.valueOf(targetType)); TypeDescriptor.valueOf(targetType));
} }
@Override @Override
public boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType) { public boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType) {
Assert.notNull(targetType, "targetType to convert to cannot be null"); Assert.notNull(targetType, "Target type to convert to cannot be null");
if (sourceType == null) { if (sourceType == null) {
return true; return true;
} }
@ -161,9 +161,9 @@ public class GenericConversionService implements ConfigurableConversionService {
} }
/** /**
* Return whether conversion between the sourceType and targetType can be bypassed. * Return whether conversion between the source type and the target type can be bypassed.
* <p>More precisely, this method will return true if objects of sourceType can be * <p>More precisely, this method will return true if objects of sourceType can be
* converted to the targetType by returning the source object unchanged. * converted to the target type by returning the source object unchanged.
* @param sourceType context about the source type to convert from * @param sourceType context about the source type to convert from
* (may be {@code null} if source is {@code null}) * (may be {@code null} if source is {@code null})
* @param targetType context about the target type to convert to (required) * @param targetType context about the target type to convert to (required)
@ -172,7 +172,7 @@ public class GenericConversionService implements ConfigurableConversionService {
* @since 3.2 * @since 3.2
*/ */
public boolean canBypassConvert(TypeDescriptor sourceType, TypeDescriptor targetType) { public boolean canBypassConvert(TypeDescriptor sourceType, TypeDescriptor targetType) {
Assert.notNull(targetType, "targetType to convert to cannot be null"); Assert.notNull(targetType, "Target type to convert to cannot be null");
if (sourceType == null) { if (sourceType == null) {
return true; return true;
} }
@ -183,20 +183,20 @@ public class GenericConversionService implements ConfigurableConversionService {
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> T convert(Object source, Class<T> targetType) { public <T> T convert(Object source, Class<T> targetType) {
Assert.notNull(targetType, "targetType to convert to cannot be null"); Assert.notNull(targetType, "Target type to convert to cannot be null");
return (T) convert(source, TypeDescriptor.forObject(source), TypeDescriptor.valueOf(targetType)); return (T) convert(source, TypeDescriptor.forObject(source), TypeDescriptor.valueOf(targetType));
} }
@Override @Override
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
Assert.notNull(targetType, "targetType to convert to cannot be null"); Assert.notNull(targetType, "Target type to convert to cannot be null");
if (sourceType == null) { if (sourceType == null) {
Assert.isTrue(source == null, "source must be [null] if sourceType == [null]"); Assert.isTrue(source == null, "Source must be [null] if source type == [null]");
return handleResult(null, targetType, convertNullSource(null, targetType)); return handleResult(null, targetType, convertNullSource(null, targetType));
} }
if (source != null && !sourceType.getObjectType().isInstance(source)) { if (source != null && !sourceType.getObjectType().isInstance(source)) {
throw new IllegalArgumentException("source to convert from must be an instance of " + throw new IllegalArgumentException("Source to convert from must be an instance of [" +
sourceType + "; instead it was a " + source.getClass().getName()); sourceType + "]; instead it was a [" + source.getClass().getName() + "]");
} }
GenericConverter converter = getConverter(sourceType, targetType); GenericConverter converter = getConverter(sourceType, targetType);
if (converter != null) { if (converter != null) {
@ -208,9 +208,9 @@ public class GenericConversionService implements ConfigurableConversionService {
/** /**
* Convenience operation for converting a source object to the specified targetType, * Convenience operation for converting a source object to the specified targetType,
* where the targetType is a descriptor that provides additional conversion context. * where the target type is a descriptor that provides additional conversion context.
* Simply delegates to {@link #convert(Object, TypeDescriptor, TypeDescriptor)} and * Simply delegates to {@link #convert(Object, TypeDescriptor, TypeDescriptor)} and
* encapsulates the construction of the sourceType descriptor using * encapsulates the construction of the source type descriptor using
* {@link TypeDescriptor#forObject(Object)}. * {@link TypeDescriptor#forObject(Object)}.
* @param source the source object * @param source the source object
* @param targetType the target type * @param targetType the target type
@ -237,8 +237,8 @@ public class GenericConversionService implements ConfigurableConversionService {
* {@link java.util.Optional#empty()} instance if the target type is * {@link java.util.Optional#empty()} instance if the target type is
* {@code java.util.Optional}. Subclasses may override this to return * {@code java.util.Optional}. Subclasses may override this to return
* custom {@code null} objects for specific target types. * custom {@code null} objects for specific target types.
* @param sourceType the sourceType to convert from * @param sourceType the source type to convert from
* @param targetType the targetType to convert to * @param targetType the target type to convert to
* @return the converted null object * @return the converted null object
*/ */
protected Object convertNullSource(TypeDescriptor sourceType, TypeDescriptor targetType) { protected Object convertNullSource(TypeDescriptor sourceType, TypeDescriptor targetType) {
@ -282,7 +282,7 @@ public class GenericConversionService implements ConfigurableConversionService {
/** /**
* Return the default converter if no converter is found for the given sourceType/targetType pair. * Return the default converter if no converter is found for the given sourceType/targetType pair.
* <p>Returns a NO_OP Converter if the sourceType is assignable to the targetType. * <p>Returns a NO_OP Converter if the source type is assignable to the target type.
* Returns {@code null} otherwise, indicating no suitable converter could be found. * Returns {@code null} otherwise, indicating no suitable converter could be found.
* @param sourceType the source type to convert from * @param sourceType the source type to convert from
* @param targetType the target type to convert to * @param targetType the target type to convert to

10
spring-core/src/main/java/org/springframework/core/convert/support/ObjectToOptionalConverter.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2015 the original author or authors. * Copyright 2002-2016 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.
@ -68,13 +68,13 @@ final class ObjectToOptionalConverter implements ConditionalGenericConverter {
else if (source instanceof Optional) { else if (source instanceof Optional) {
return source; return source;
} }
else if (targetType.getResolvableType() == null) { else if (targetType.getResolvableType() != null) {
return Optional.of(source);
}
else {
Object target = this.conversionService.convert(source, sourceType, new GenericTypeDescriptor(targetType)); Object target = this.conversionService.convert(source, sourceType, new GenericTypeDescriptor(targetType));
return Optional.ofNullable(target); return Optional.ofNullable(target);
} }
else {
return Optional.of(source);
}
} }

12
spring-core/src/test/java/org/springframework/util/xml/AbstractStaxHandlerTestCase.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2015 the original author or authors. * Copyright 2002-2016 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.
@ -19,7 +19,6 @@ package org.springframework.util.xml;
import java.io.StringReader; import java.io.StringReader;
import java.io.StringWriter; import java.io.StringWriter;
import java.net.Socket; import java.net.Socket;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamException;
@ -30,7 +29,6 @@ import javax.xml.transform.stream.StreamResult;
import org.junit.Assume; import org.junit.Assume;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
import org.xml.sax.XMLReader; import org.xml.sax.XMLReader;
@ -58,11 +56,13 @@ public abstract class AbstractStaxHandlerTestCase {
private XMLReader xmlReader; private XMLReader xmlReader;
@Before @Before
public void createXMLReader() throws Exception { public void createXMLReader() throws Exception {
xmlReader = XMLReaderFactory.createXMLReader(); xmlReader = XMLReaderFactory.createXMLReader();
} }
@Test @Test
public void noNamespacePrefixes() throws Exception { public void noNamespacePrefixes() throws Exception {
Assume.assumeTrue(wwwSpringframeworkOrgIsAccessible()); Assume.assumeTrue(wwwSpringframeworkOrgIsAccessible());
@ -109,8 +109,7 @@ public abstract class AbstractStaxHandlerTestCase {
@Test @Test
public void noNamespacePrefixesDom() throws Exception { public void noNamespacePrefixesDom() throws Exception {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true); documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
@ -131,8 +130,7 @@ public abstract class AbstractStaxHandlerTestCase {
@Test @Test
public void namespacePrefixesDom() throws Exception { public void namespacePrefixesDom() throws Exception {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true); documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();

5
spring-core/src/test/java/org/springframework/util/xml/StaxEventHandlerTests.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2016 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.
@ -27,8 +27,7 @@ import javax.xml.transform.Result;
public class StaxEventHandlerTests extends AbstractStaxHandlerTestCase { public class StaxEventHandlerTests extends AbstractStaxHandlerTestCase {
@Override @Override
protected AbstractStaxHandler createStaxHandler(Result result) protected AbstractStaxHandler createStaxHandler(Result result) throws XMLStreamException {
throws XMLStreamException {
XMLOutputFactory outputFactory = XMLOutputFactory.newFactory(); XMLOutputFactory outputFactory = XMLOutputFactory.newFactory();
XMLEventWriter eventWriter = outputFactory.createXMLEventWriter(result); XMLEventWriter eventWriter = outputFactory.createXMLEventWriter(result);
return new StaxEventHandler(eventWriter); return new StaxEventHandler(eventWriter);

5
spring-core/src/test/java/org/springframework/util/xml/StaxStreamHandlerTests.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2016 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.
@ -27,8 +27,7 @@ import javax.xml.transform.Result;
public class StaxStreamHandlerTests extends AbstractStaxHandlerTestCase { public class StaxStreamHandlerTests extends AbstractStaxHandlerTestCase {
@Override @Override
protected AbstractStaxHandler createStaxHandler(Result result) protected AbstractStaxHandler createStaxHandler(Result result) throws XMLStreamException {
throws XMLStreamException {
XMLOutputFactory outputFactory = XMLOutputFactory.newFactory(); XMLOutputFactory outputFactory = XMLOutputFactory.newFactory();
XMLStreamWriter streamWriter = outputFactory.createXMLStreamWriter(result); XMLStreamWriter streamWriter = outputFactory.createXMLStreamWriter(result);
return new StaxStreamHandler(streamWriter); return new StaxStreamHandler(streamWriter);

6
spring-oxm/src/main/java/org/springframework/oxm/Marshaller.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2016 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.
@ -35,7 +35,7 @@ import javax.xml.transform.Result;
public interface Marshaller { public interface Marshaller {
/** /**
* Indicates whether this marshaller can marshal instances of the supplied type. * Indicate whether this marshaller can marshal instances of the supplied type.
* @param clazz the class that this marshaller is being asked if it can marshal * @param clazz the class that this marshaller is being asked if it can marshal
* @return {@code true} if this marshaller can indeed marshal instances of the supplied class; * @return {@code true} if this marshaller can indeed marshal instances of the supplied class;
* {@code false} otherwise * {@code false} otherwise
@ -43,7 +43,7 @@ public interface Marshaller {
boolean supports(Class<?> clazz); boolean supports(Class<?> clazz);
/** /**
* Marshals the object graph with the given root into the provided {@link Result}. * Marshal the object graph with the given root into the provided {@link Result}.
* @param graph the root of the object graph to marshal * @param graph the root of the object graph to marshal
* @param result the result to marshal to * @param result the result to marshal to
* @throws IOException if an I/O error occurs * @throws IOException if an I/O error occurs

6
spring-oxm/src/main/java/org/springframework/oxm/Unmarshaller.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2016 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.
@ -30,7 +30,7 @@ import javax.xml.transform.Source;
public interface Unmarshaller { public interface Unmarshaller {
/** /**
* Indicates whether this unmarshaller can unmarshal instances of the supplied type. * Indicate whether this unmarshaller can unmarshal instances of the supplied type.
* @param clazz the class that this unmarshaller is being asked if it can marshal * @param clazz the class that this unmarshaller is being asked if it can marshal
* @return {@code true} if this unmarshaller can indeed unmarshal to the supplied class; * @return {@code true} if this unmarshaller can indeed unmarshal to the supplied class;
* {@code false} otherwise * {@code false} otherwise
@ -38,7 +38,7 @@ public interface Unmarshaller {
boolean supports(Class<?> clazz); boolean supports(Class<?> clazz);
/** /**
* Unmarshals the given {@link Source} into an object graph. * Unmarshal the given {@link Source} into an object graph.
* @param source the source to marshal from * @param source the source to marshal from
* @return the object graph * @return the object graph
* @throws IOException if an I/O error occurs * @throws IOException if an I/O error occurs

52
spring-web/src/main/java/org/springframework/web/client/AsyncRestOperations.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2013 the original author or authors. * Copyright 2002-2016 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.
@ -29,12 +29,14 @@ import org.springframework.http.ResponseEntity;
import org.springframework.util.concurrent.ListenableFuture; import org.springframework.util.concurrent.ListenableFuture;
/** /**
* Interface specifying a basic set of asynchronous RESTful operations. Implemented by * Interface specifying a basic set of asynchronous RESTful operations.
* {@link AsyncRestTemplate}. Not often used directly, but a useful option to enhance * Implemented by {@link AsyncRestTemplate}. Not often used directly, but a useful
* testability, as it can easily be mocked or stubbed. * option to enhance testability, as it can easily be mocked or stubbed.
* *
* @author Arjen Poutsma * @author Arjen Poutsma
* @since 4.0 * @since 4.0
* @see AsyncRestTemplate
* @see RestOperations
*/ */
public interface AsyncRestOperations { public interface AsyncRestOperations {
@ -47,8 +49,8 @@ public interface AsyncRestOperations {
// GET // GET
/** /**
* Asynchronously retrieve an entity by doing a GET on the specified URL. The response is * Asynchronously retrieve an entity by doing a GET on the specified URL.
* converted and stored in an {@link ResponseEntity}. * The response is converted and stored in an {@link ResponseEntity}.
* <p>URI Template variables are expanded using the given URI variables, if any. * <p>URI Template variables are expanded using the given URI variables, if any.
* @param url the URL * @param url the URL
* @param responseType the type of the return value * @param responseType the type of the return value
@ -59,8 +61,8 @@ public interface AsyncRestOperations {
Object... uriVariables) throws RestClientException; Object... uriVariables) throws RestClientException;
/** /**
* Asynchronously retrieve a representation by doing a GET on the URI template. The * Asynchronously retrieve a representation by doing a GET on the URI template.
* response is converted and stored in an {@link ResponseEntity}. * The response is converted and stored in an {@link ResponseEntity}.
* <p>URI Template variables are expanded using the given map. * <p>URI Template variables are expanded using the given map.
* @param url the URL * @param url the URL
* @param responseType the type of the return value * @param responseType the type of the return value
@ -80,6 +82,7 @@ public interface AsyncRestOperations {
<T> ListenableFuture<ResponseEntity<T>> getForEntity(URI url, Class<T> responseType) <T> ListenableFuture<ResponseEntity<T>> getForEntity(URI url, Class<T> responseType)
throws RestClientException; throws RestClientException;
// HEAD // HEAD
/** /**
@ -109,6 +112,7 @@ public interface AsyncRestOperations {
*/ */
ListenableFuture<HttpHeaders> headForHeaders(URI url) throws RestClientException; ListenableFuture<HttpHeaders> headForHeaders(URI url) throws RestClientException;
// POST // POST
/** /**
@ -117,7 +121,7 @@ public interface AsyncRestOperations {
* typically indicates where the new resource is stored. * typically indicates where the new resource is stored.
* <p>URI Template variables are expanded using the given URI variables, if any. * <p>URI Template variables are expanded using the given URI variables, if any.
* @param url the URL * @param url the URL
* @param request the Object to be POSTed, may be {@code null} * @param request the Object to be POSTed (may be {@code null})
* @param uriVariables the variables to expand the template * @param uriVariables the variables to expand the template
* @return the value for the {@code Location} header wrapped in a {@link Future} * @return the value for the {@code Location} header wrapped in a {@link Future}
* @see org.springframework.http.HttpEntity * @see org.springframework.http.HttpEntity
@ -131,7 +135,7 @@ public interface AsyncRestOperations {
* typically indicates where the new resource is stored. * typically indicates where the new resource is stored.
* <p>URI Template variables are expanded using the given map. * <p>URI Template variables are expanded using the given map.
* @param url the URL * @param url the URL
* @param request the Object to be POSTed, may be {@code null} * @param request the Object to be POSTed (may be {@code null})
* @param uriVariables the variables to expand the template * @param uriVariables the variables to expand the template
* @return the value for the {@code Location} header wrapped in a {@link Future} * @return the value for the {@code Location} header wrapped in a {@link Future}
* @see org.springframework.http.HttpEntity * @see org.springframework.http.HttpEntity
@ -144,7 +148,7 @@ public interface AsyncRestOperations {
* returns the value of the {@code Location} header. This header typically indicates * returns the value of the {@code Location} header. This header typically indicates
* where the new resource is stored. * where the new resource is stored.
* @param url the URL * @param url the URL
* @param request the Object to be POSTed, may be {@code null} * @param request the Object to be POSTed (may be {@code null})
* @return the value for the {@code Location} header wrapped in a {@link Future} * @return the value for the {@code Location} header wrapped in a {@link Future}
* @see org.springframework.http.HttpEntity * @see org.springframework.http.HttpEntity
*/ */
@ -155,7 +159,7 @@ public interface AsyncRestOperations {
* and asynchronously returns the response as {@link ResponseEntity}. * and asynchronously returns the response as {@link ResponseEntity}.
* <p>URI Template variables are expanded using the given URI variables, if any. * <p>URI Template variables are expanded using the given URI variables, if any.
* @param url the URL * @param url the URL
* @param request the Object to be POSTed, may be {@code null} * @param request the Object to be POSTed (may be {@code null})
* @param uriVariables the variables to expand the template * @param uriVariables the variables to expand the template
* @return the entity wrapped in a {@link Future} * @return the entity wrapped in a {@link Future}
* @see org.springframework.http.HttpEntity * @see org.springframework.http.HttpEntity
@ -168,26 +172,26 @@ public interface AsyncRestOperations {
* and asynchronously returns the response as {@link ResponseEntity}. * and asynchronously returns the response as {@link ResponseEntity}.
* <p>URI Template variables are expanded using the given map. * <p>URI Template variables are expanded using the given map.
* @param url the URL * @param url the URL
* @param request the Object to be POSTed, may be {@code null} * @param request the Object to be POSTed (may be {@code null})
* @param uriVariables the variables to expand the template * @param uriVariables the variables to expand the template
* @return the entity wrapped in a {@link Future} * @return the entity wrapped in a {@link Future}
* @see org.springframework.http.HttpEntity * @see org.springframework.http.HttpEntity
*/ */
<T> ListenableFuture<ResponseEntity<T>> postForEntity(String url, HttpEntity<?> request, <T> ListenableFuture<ResponseEntity<T>> postForEntity(String url, HttpEntity<?> request,
Class<T> responseType, Map<String, ?> uriVariables) Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException;
throws RestClientException;
/** /**
* Create a new resource by POSTing the given object to the URL, * Create a new resource by POSTing the given object to the URL,
* and asynchronously returns the response as {@link ResponseEntity}. * and asynchronously returns the response as {@link ResponseEntity}.
* @param url the URL * @param url the URL
* @param request the Object to be POSTed, may be {@code null} * @param request the Object to be POSTed (may be {@code null})
* @return the entity wrapped in a {@link Future} * @return the entity wrapped in a {@link Future}
* @see org.springframework.http.HttpEntity * @see org.springframework.http.HttpEntity
*/ */
<T> ListenableFuture<ResponseEntity<T>> postForEntity(URI url, HttpEntity<?> request, <T> ListenableFuture<ResponseEntity<T>> postForEntity(URI url, HttpEntity<?> request,
Class<T> responseType) throws RestClientException; Class<T> responseType) throws RestClientException;
// PUT // PUT
/** /**
@ -195,7 +199,7 @@ public interface AsyncRestOperations {
* <p>URI Template variables are expanded using the given URI variables, if any. * <p>URI Template variables are expanded using the given URI variables, if any.
* <p>The Future will return a {@code null} result upon completion. * <p>The Future will return a {@code null} result upon completion.
* @param url the URL * @param url the URL
* @param request the Object to be PUT, may be {@code null} * @param request the Object to be PUT (may be {@code null})
* @param uriVariables the variables to expand the template * @param uriVariables the variables to expand the template
* @see HttpEntity * @see HttpEntity
*/ */
@ -207,7 +211,7 @@ public interface AsyncRestOperations {
* <p>URI Template variables are expanded using the given map. * <p>URI Template variables are expanded using the given map.
* <p>The Future will return a {@code null} result upon completion. * <p>The Future will return a {@code null} result upon completion.
* @param url the URL * @param url the URL
* @param request the Object to be PUT, may be {@code null} * @param request the Object to be PUT (may be {@code null})
* @param uriVariables the variables to expand the template * @param uriVariables the variables to expand the template
* @see HttpEntity * @see HttpEntity
*/ */
@ -218,11 +222,12 @@ public interface AsyncRestOperations {
* Creates a new resource by PUTting the given object to URL. * Creates a new resource by PUTting the given object to URL.
* <p>The Future will return a {@code null} result upon completion. * <p>The Future will return a {@code null} result upon completion.
* @param url the URL * @param url the URL
* @param request the Object to be PUT, may be {@code null} * @param request the Object to be PUT (may be {@code null})
* @see HttpEntity * @see HttpEntity
*/ */
ListenableFuture<?> put(URI url, HttpEntity<?> request) throws RestClientException; ListenableFuture<?> put(URI url, HttpEntity<?> request) throws RestClientException;
// DELETE // DELETE
/** /**
@ -251,6 +256,7 @@ public interface AsyncRestOperations {
*/ */
ListenableFuture<?> delete(URI url) throws RestClientException; ListenableFuture<?> delete(URI url) throws RestClientException;
// OPTIONS // OPTIONS
/** /**
@ -344,7 +350,7 @@ public interface AsyncRestOperations {
* @param url the URL * @param url the URL
* @param method the HTTP method (GET, POST, etc) * @param method the HTTP method (GET, POST, etc)
* @param requestEntity the entity (headers and/or body) to write to the * @param requestEntity the entity (headers and/or body) to write to the
* request, may be {@code null} * request (may be {@code null})
* @param responseType the type of the return value * @param responseType the type of the return value
* @param uriVariables the variables to expand in the template * @param uriVariables the variables to expand in the template
* @return the response as entity wrapped in a {@link Future} * @return the response as entity wrapped in a {@link Future}
@ -364,7 +370,8 @@ public interface AsyncRestOperations {
* </pre> * </pre>
* @param url the URL * @param url the URL
* @param method the HTTP method (GET, POST, etc) * @param method the HTTP method (GET, POST, etc)
* @param requestEntity the entity (headers and/or body) to write to the request, may be {@code null} * @param requestEntity the entity (headers and/or body) to write to the request
* (may be {@code null})
* @param responseType the type of the return value * @param responseType the type of the return value
* @param uriVariables the variables to expand in the template * @param uriVariables the variables to expand in the template
* @return the response as entity wrapped in a {@link Future} * @return the response as entity wrapped in a {@link Future}
@ -384,7 +391,8 @@ public interface AsyncRestOperations {
* </pre> * </pre>
* @param url the URL * @param url the URL
* @param method the HTTP method (GET, POST, etc) * @param method the HTTP method (GET, POST, etc)
* @param requestEntity the entity (headers and/or body) to write to the request, may be {@code null} * @param requestEntity the entity (headers and/or body) to write to the request
* (may be {@code null})
* @param responseType the type of the return value * @param responseType the type of the return value
* @return the response as entity wrapped in a {@link Future} * @return the response as entity wrapped in a {@link Future}
*/ */

6
spring-web/src/main/java/org/springframework/web/client/AsyncRestTemplate.java

@ -53,10 +53,8 @@ import org.springframework.web.util.UriTemplateHandler;
* wrappers as opposed to concrete results. * wrappers as opposed to concrete results.
* *
* <p>The {@code AsyncRestTemplate} exposes a synchronous {@link RestTemplate} via the * <p>The {@code AsyncRestTemplate} exposes a synchronous {@link RestTemplate} via the
* {@link #getRestOperations()} method, and it shares its * {@link #getRestOperations()} method and shares its {@linkplain #setErrorHandler error handler}
* {@linkplain #setErrorHandler(ResponseErrorHandler) error handler} and * and {@linkplain #setMessageConverters message converters} with that {@code RestTemplate}.
* {@linkplain #setMessageConverters(List) message converters} with this
* {@code RestTemplate}.
* *
* <p><strong>Note:</strong> by default {@code AsyncRestTemplate} relies on * <p><strong>Note:</strong> by default {@code AsyncRestTemplate} relies on
* standard JDK facilities to establish HTTP connections. You can switch to use * standard JDK facilities to establish HTTP connections. You can switch to use

6
spring-web/src/main/java/org/springframework/web/method/annotation/ModelFactory.java

@ -250,10 +250,8 @@ public final class ModelFactory {
List<String> keyNames = new ArrayList<String>(model.keySet()); List<String> keyNames = new ArrayList<String>(model.keySet());
for (String name : keyNames) { for (String name : keyNames) {
Object value = model.get(name); Object value = model.get(name);
if (isBindingCandidate(name, value)) { if (isBindingCandidate(name, value)) {
String bindingResultKey = BindingResult.MODEL_KEY_PREFIX + name; String bindingResultKey = BindingResult.MODEL_KEY_PREFIX + name;
if (!model.containsAttribute(bindingResultKey)) { if (!model.containsAttribute(bindingResultKey)) {
WebDataBinder dataBinder = this.dataBinderFactory.createBinder(request, value, name); WebDataBinder dataBinder = this.dataBinderFactory.createBinder(request, value, name);
model.put(bindingResultKey, dataBinder.getBindingResult()); model.put(bindingResultKey, dataBinder.getBindingResult());
@ -270,7 +268,7 @@ public final class ModelFactory {
return false; return false;
} }
Class<?> attrType = (value != null) ? value.getClass() : null; Class<?> attrType = (value != null ? value.getClass() : null);
if (this.sessionAttributesHandler.isHandlerSessionAttribute(attributeName, attrType)) { if (this.sessionAttributesHandler.isHandlerSessionAttribute(attributeName, attrType)) {
return true; return true;
} }
@ -286,7 +284,7 @@ public final class ModelFactory {
private final Set<String> dependencies = new HashSet<String>(); private final Set<String> dependencies = new HashSet<String>();
private ModelMethod(InvocableHandlerMethod handlerMethod) { public ModelMethod(InvocableHandlerMethod handlerMethod) {
this.handlerMethod = handlerMethod; this.handlerMethod = handlerMethod;
for (MethodParameter parameter : handlerMethod.getMethodParameters()) { for (MethodParameter parameter : handlerMethod.getMethodParameters()) {
if (parameter.hasParameterAnnotation(ModelAttribute.class)) { if (parameter.hasParameterAnnotation(ModelAttribute.class)) {

4
spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java

@ -194,7 +194,7 @@ final class HierarchicalUriComponents extends UriComponents {
String hostTo = encodeUriComponent(this.host, encoding, getHostType()); String hostTo = encodeUriComponent(this.host, encoding, getHostType());
PathComponent pathTo = this.path.encode(encoding); PathComponent pathTo = this.path.encode(encoding);
MultiValueMap<String, String> paramsTo = encodeQueryParams(encoding); MultiValueMap<String, String> paramsTo = encodeQueryParams(encoding);
String fragmentTo = encodeUriComponent(this.getFragment(), encoding, Type.FRAGMENT); String fragmentTo = encodeUriComponent(getFragment(), encoding, Type.FRAGMENT);
return new HierarchicalUriComponents(schemeTo, userInfoTo, hostTo, this.port, return new HierarchicalUriComponents(schemeTo, userInfoTo, hostTo, this.port,
pathTo, paramsTo, fragmentTo, true, false); pathTo, paramsTo, fragmentTo, true, false);
} }
@ -328,7 +328,7 @@ final class HierarchicalUriComponents extends UriComponents {
String portTo = expandUriComponent(this.port, uriVariables); String portTo = expandUriComponent(this.port, uriVariables);
PathComponent pathTo = this.path.expand(uriVariables); PathComponent pathTo = this.path.expand(uriVariables);
MultiValueMap<String, String> paramsTo = expandQueryParams(uriVariables); MultiValueMap<String, String> paramsTo = expandQueryParams(uriVariables);
String fragmentTo = expandUriComponent(this.getFragment(), uriVariables); String fragmentTo = expandUriComponent(getFragment(), uriVariables);
return new HierarchicalUriComponents(schemeTo, userInfoTo, hostTo, portTo, return new HierarchicalUriComponents(schemeTo, userInfoTo, hostTo, portTo,
pathTo, paramsTo, fragmentTo, false, false); pathTo, paramsTo, fragmentTo, false, false);

7
spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodProcessor.java

@ -90,7 +90,6 @@ public abstract class AbstractMessageConverterMethodProcessor extends AbstractMe
private final Set<String> safeExtensions = new HashSet<String>(); private final Set<String> safeExtensions = new HashSet<String>();
/** /**
* Constructor with list of converters only. * Constructor with list of converters only.
*/ */
@ -348,9 +347,7 @@ public abstract class AbstractMessageConverterMethodProcessor extends AbstractMe
* header with a safe attachment file name ("f.txt") is added to prevent * header with a safe attachment file name ("f.txt") is added to prevent
* RFD exploits. * RFD exploits.
*/ */
private void addContentDispositionHeader(ServletServerHttpRequest request, private void addContentDispositionHeader(ServletServerHttpRequest request, ServletServerHttpResponse response) {
ServletServerHttpResponse response) {
HttpHeaders headers = response.getHeaders(); HttpHeaders headers = response.getHeaders();
if (headers.containsKey(HttpHeaders.CONTENT_DISPOSITION)) { if (headers.containsKey(HttpHeaders.CONTENT_DISPOSITION)) {
return; return;
@ -363,7 +360,7 @@ public abstract class AbstractMessageConverterMethodProcessor extends AbstractMe
} }
} }
catch (Throwable ex) { catch (Throwable ex) {
// Ignore // ignore
} }
HttpServletRequest servletRequest = request.getServletRequest(); HttpServletRequest servletRequest = request.getServletRequest();

24
spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java

@ -69,11 +69,7 @@ import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView; import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
import org.springframework.web.util.WebUtils; import org.springframework.web.util.WebUtils;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.*;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/** /**
* Test fixture for a {@link RequestResponseBodyMethodProcessor} with * Test fixture for a {@link RequestResponseBodyMethodProcessor} with
@ -732,7 +728,6 @@ public class RequestResponseBodyMethodProcessorTests {
} }
String handle( String handle(
@RequestBody List<SimpleBean> list, @RequestBody List<SimpleBean> list,
@RequestBody SimpleBean simpleBean, @RequestBody SimpleBean simpleBean,
@ -751,15 +746,18 @@ public class RequestResponseBodyMethodProcessorTests {
return null; return null;
} }
private static abstract class MyParameterizedController<DTO extends Identifiable> { private static abstract class MyParameterizedController<DTO extends Identifiable> {
@SuppressWarnings("unused") @SuppressWarnings("unused")
public void handleDto(@RequestBody DTO dto) {} public void handleDto(@RequestBody DTO dto) {}
} }
private static class MySimpleParameterizedController extends MyParameterizedController<SimpleBean> { private static class MySimpleParameterizedController extends MyParameterizedController<SimpleBean> {
} }
private interface Identifiable extends Serializable { private interface Identifiable extends Serializable {
Long getId(); Long getId();
@ -767,6 +765,7 @@ public class RequestResponseBodyMethodProcessorTests {
void setId(Long id); void setId(Long id);
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
private static abstract class MyParameterizedControllerWithList<DTO extends Identifiable> { private static abstract class MyParameterizedControllerWithList<DTO extends Identifiable> {
@ -774,6 +773,7 @@ public class RequestResponseBodyMethodProcessorTests {
} }
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
private static class MySimpleParameterizedControllerWithList extends MyParameterizedControllerWithList<SimpleBean> { private static class MySimpleParameterizedControllerWithList extends MyParameterizedControllerWithList<SimpleBean> {
} }
@ -843,9 +843,12 @@ public class RequestResponseBodyMethodProcessorTests {
} }
} }
private interface MyJacksonView1 {} private interface MyJacksonView1 {}
private interface MyJacksonView2 {} private interface MyJacksonView2 {}
private static class JacksonViewBean { private static class JacksonViewBean {
@JsonView(MyJacksonView1.class) @JsonView(MyJacksonView1.class)
@ -881,6 +884,7 @@ public class RequestResponseBodyMethodProcessorTests {
} }
} }
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type") @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
public static class ParentClass { public static class ParentClass {
@ -902,6 +906,7 @@ public class RequestResponseBodyMethodProcessorTests {
} }
} }
@JsonTypeName("foo") @JsonTypeName("foo")
public static class Foo extends ParentClass { public static class Foo extends ParentClass {
@ -913,6 +918,7 @@ public class RequestResponseBodyMethodProcessorTests {
} }
} }
@JsonTypeName("bar") @JsonTypeName("bar")
public static class Bar extends ParentClass { public static class Bar extends ParentClass {
@ -924,6 +930,7 @@ public class RequestResponseBodyMethodProcessorTests {
} }
} }
private static class JacksonController { private static class JacksonController {
@RequestMapping @RequestMapping
@ -996,9 +1003,9 @@ public class RequestResponseBodyMethodProcessorTests {
public String defaultCharset() { public String defaultCharset() {
return "foo"; return "foo";
} }
} }
private static class EmptyRequestBodyAdvice implements RequestBodyAdvice { private static class EmptyRequestBodyAdvice implements RequestBodyAdvice {
@Override @Override
@ -1030,12 +1037,15 @@ public class RequestResponseBodyMethodProcessorTests {
} }
} }
interface MappingInterface<A> { interface MappingInterface<A> {
default A handle(@RequestBody A arg) { default A handle(@RequestBody A arg) {
return arg; return arg;
} }
} }
static class MyControllerImplementingInterface implements MappingInterface<String> { static class MyControllerImplementingInterface implements MappingInterface<String> {
} }

Loading…
Cancel
Save