Polishing
This commit is contained in:
parent
85f64706a8
commit
e892e02f41
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* 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.
|
||||||
|
|
@ -186,7 +186,7 @@ class ConfigurationClassBeanDefinitionReader {
|
||||||
// Consider name and any aliases
|
// Consider name and any aliases
|
||||||
AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
|
AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
|
||||||
List<String> names = new ArrayList<>(Arrays.asList(bean.getStringArray("name")));
|
List<String> names = new ArrayList<>(Arrays.asList(bean.getStringArray("name")));
|
||||||
String beanName = (names.size() > 0 ? names.remove(0) : methodName);
|
String beanName = (!names.isEmpty() ? names.remove(0) : methodName);
|
||||||
|
|
||||||
// Register aliases even when overridden
|
// Register aliases even when overridden
|
||||||
for (String alias : names) {
|
for (String alias : names) {
|
||||||
|
|
@ -336,7 +336,7 @@ class ConfigurationClassBeanDefinitionReader {
|
||||||
}
|
}
|
||||||
readerInstanceCache.put(readerClass, reader);
|
readerInstanceCache.put(readerClass, reader);
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Throwable ex) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Could not instantiate BeanDefinitionReader class [" + readerClass.getName() + "]");
|
"Could not instantiate BeanDefinitionReader class [" + readerClass.getName() + "]");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* 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.
|
||||||
|
|
@ -102,7 +102,7 @@ public class ReactiveAdapter {
|
||||||
/**
|
/**
|
||||||
* Adapt the given instance to a Reactive Streams Publisher.
|
* Adapt the given instance to a Reactive Streams Publisher.
|
||||||
* @param source the source object to adapt from
|
* @param source the source object to adapt from
|
||||||
* @return the Publisher repesenting the adaptation
|
* @return the Publisher representing the adaptation
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T> Publisher<T> toPublisher(Object source) {
|
public <T> Publisher<T> toPublisher(Object source) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* 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,10 +30,7 @@ import rx.RxReactiveStreams;
|
||||||
|
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
|
|
||||||
import static org.springframework.core.ReactiveTypeDescriptor.multiValue;
|
import static org.springframework.core.ReactiveTypeDescriptor.*;
|
||||||
import static org.springframework.core.ReactiveTypeDescriptor.noValue;
|
|
||||||
import static org.springframework.core.ReactiveTypeDescriptor.singleOptionalValue;
|
|
||||||
import static org.springframework.core.ReactiveTypeDescriptor.singleRequiredValue;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A registry of adapters to adapt a Reactive Streams {@link Publisher} to/from
|
* A registry of adapters to adapt a Reactive Streams {@link Publisher} to/from
|
||||||
|
|
@ -69,15 +66,12 @@ public class ReactiveAdapterRegistry {
|
||||||
* Create a registry and auto-register default adapters.
|
* Create a registry and auto-register default adapters.
|
||||||
*/
|
*/
|
||||||
public ReactiveAdapterRegistry() {
|
public ReactiveAdapterRegistry() {
|
||||||
|
|
||||||
if (reactorPresent) {
|
if (reactorPresent) {
|
||||||
new ReactorRegistrar().registerAdapters(this);
|
new ReactorRegistrar().registerAdapters(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rxJava1Present && rxJava1Adapter) {
|
if (rxJava1Present && rxJava1Adapter) {
|
||||||
new RxJava1Registrar().registerAdapters(this);
|
new RxJava1Registrar().registerAdapters(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rxJava2Present) {
|
if (rxJava2Present) {
|
||||||
new RxJava2Registrar().registerAdapters(this);
|
new RxJava2Registrar().registerAdapters(this);
|
||||||
}
|
}
|
||||||
|
|
@ -111,15 +105,16 @@ public class ReactiveAdapterRegistry {
|
||||||
* Get the adapter for the given reactive type. Or if a "source" object is
|
* Get the adapter for the given reactive type. Or if a "source" object is
|
||||||
* provided, its actual type is used instead.
|
* provided, its actual type is used instead.
|
||||||
* @param reactiveType the reactive type
|
* @param reactiveType the reactive type
|
||||||
* @param source an instance of the reactive type (i.e. to adapt from)
|
* (may be {@code null} if a concrete source object is given)
|
||||||
|
* @param source an instance of the reactive type
|
||||||
|
* (i.e. to adapt from; may be {@code null} if the reactive type is specified)
|
||||||
*/
|
*/
|
||||||
public ReactiveAdapter getAdapter(Class<?> reactiveType, Object source) {
|
public ReactiveAdapter getAdapter(Class<?> reactiveType, Object source) {
|
||||||
|
Object sourceToUse = (source instanceof Optional ? ((Optional<?>) source).orElse(null) : source);
|
||||||
source = (source instanceof Optional ? ((Optional<?>) source).orElse(null) : source);
|
Class<?> clazz = (sourceToUse != null ? sourceToUse.getClass() : reactiveType);
|
||||||
Class<?> clazz = (source != null ? source.getClass() : reactiveType);
|
|
||||||
|
|
||||||
return this.adapters.stream()
|
return this.adapters.stream()
|
||||||
.filter(adapter -> adapter.getReactiveType().equals(clazz))
|
.filter(adapter -> adapter.getReactiveType() == clazz)
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElseGet(() ->
|
.orElseGet(() ->
|
||||||
this.adapters.stream()
|
this.adapters.stream()
|
||||||
|
|
@ -132,7 +127,6 @@ public class ReactiveAdapterRegistry {
|
||||||
private static class ReactorRegistrar {
|
private static class ReactorRegistrar {
|
||||||
|
|
||||||
void registerAdapters(ReactiveAdapterRegistry registry) {
|
void registerAdapters(ReactiveAdapterRegistry registry) {
|
||||||
|
|
||||||
// Flux and Mono ahead of Publisher...
|
// Flux and Mono ahead of Publisher...
|
||||||
|
|
||||||
registry.registerReactiveType(
|
registry.registerReactiveType(
|
||||||
|
|
@ -161,6 +155,7 @@ public class ReactiveAdapterRegistry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class RxJava1Registrar {
|
private static class RxJava1Registrar {
|
||||||
|
|
||||||
void registerAdapters(ReactiveAdapterRegistry registry) {
|
void registerAdapters(ReactiveAdapterRegistry registry) {
|
||||||
|
|
@ -182,6 +177,7 @@ public class ReactiveAdapterRegistry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class RxJava2Registrar {
|
private static class RxJava2Registrar {
|
||||||
|
|
||||||
void registerAdapters(ReactiveAdapterRegistry registry) {
|
void registerAdapters(ReactiveAdapterRegistry registry) {
|
||||||
|
|
@ -213,6 +209,7 @@ public class ReactiveAdapterRegistry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extension of ReactiveAdapter that wraps adapted (raw) Publisher's as
|
* Extension of ReactiveAdapter that wraps adapted (raw) Publisher's as
|
||||||
* {@link Flux} or {@link Mono} depending on the underlying reactive type's
|
* {@link Flux} or {@link Mono} depending on the underlying reactive type's
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2007 the original author or authors.
|
* Copyright 2002-2017 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.
|
||||||
|
|
@ -21,16 +21,23 @@ package org.springframework.jdbc.core.metadata;
|
||||||
*
|
*
|
||||||
* @author Thomas Risberg
|
* @author Thomas Risberg
|
||||||
* @since 2.5
|
* @since 2.5
|
||||||
|
* @see GenericCallMetaDataProvider
|
||||||
*/
|
*/
|
||||||
public class CallParameterMetaData {
|
public class CallParameterMetaData {
|
||||||
|
|
||||||
private String parameterName;
|
private String parameterName;
|
||||||
|
|
||||||
private int parameterType;
|
private int parameterType;
|
||||||
|
|
||||||
private int sqlType;
|
private int sqlType;
|
||||||
|
|
||||||
private String typeName;
|
private String typeName;
|
||||||
|
|
||||||
private boolean nullable;
|
private boolean nullable;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor taking all the properties
|
* Constructor taking all the properties.
|
||||||
*/
|
*/
|
||||||
public CallParameterMetaData(String columnName, int columnType, int sqlType, String typeName, boolean nullable) {
|
public CallParameterMetaData(String columnName, int columnType, int sqlType, String typeName, boolean nullable) {
|
||||||
this.parameterName = columnName;
|
this.parameterName = columnName;
|
||||||
|
|
@ -45,34 +52,35 @@ public class CallParameterMetaData {
|
||||||
* Get the parameter name.
|
* Get the parameter name.
|
||||||
*/
|
*/
|
||||||
public String getParameterName() {
|
public String getParameterName() {
|
||||||
return parameterName;
|
return this.parameterName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the parameter type.
|
* Get the parameter type.
|
||||||
*/
|
*/
|
||||||
public int getParameterType() {
|
public int getParameterType() {
|
||||||
return parameterType;
|
return this.parameterType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the parameter SQL type.
|
* Get the parameter SQL type.
|
||||||
*/
|
*/
|
||||||
public int getSqlType() {
|
public int getSqlType() {
|
||||||
return sqlType;
|
return this.sqlType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the parameter type name.
|
* Get the parameter type name.
|
||||||
*/
|
*/
|
||||||
public String getTypeName() {
|
public String getTypeName() {
|
||||||
return typeName;
|
return this.typeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get whether the parameter is nullable.
|
* Get whether the parameter is nullable.
|
||||||
*/
|
*/
|
||||||
public boolean isNullable() {
|
public boolean isNullable() {
|
||||||
return nullable;
|
return this.nullable;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2007 the original author or authors.
|
* Copyright 2002-2017 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.
|
||||||
|
|
@ -21,6 +21,7 @@ package org.springframework.jdbc.core.metadata;
|
||||||
*
|
*
|
||||||
* @author Thomas Risberg
|
* @author Thomas Risberg
|
||||||
* @since 2.5
|
* @since 2.5
|
||||||
|
* @see GenericTableMetaDataProvider
|
||||||
*/
|
*/
|
||||||
public class TableParameterMetaData {
|
public class TableParameterMetaData {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* 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.
|
||||||
|
|
@ -426,7 +426,8 @@ public abstract class EntityManagerFactoryUtils {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for resource cleanup at the end of a non-JPA transaction
|
* Callback for resource cleanup at the end of a non-JPA transaction
|
||||||
* (e.g. when participating in a JtaTransactionManager transaction).
|
* (e.g. when participating in a JtaTransactionManager transaction),
|
||||||
|
* fully synchronized with the ongoing transaction.
|
||||||
* @see org.springframework.transaction.jta.JtaTransactionManager
|
* @see org.springframework.transaction.jta.JtaTransactionManager
|
||||||
*/
|
*/
|
||||||
private static class TransactionalEntityManagerSynchronization
|
private static class TransactionalEntityManagerSynchronization
|
||||||
|
|
@ -441,6 +442,7 @@ public abstract class EntityManagerFactoryUtils {
|
||||||
|
|
||||||
public TransactionalEntityManagerSynchronization(
|
public TransactionalEntityManagerSynchronization(
|
||||||
EntityManagerHolder emHolder, EntityManagerFactory emf, Object txData, boolean newEm) {
|
EntityManagerHolder emHolder, EntityManagerFactory emf, Object txData, boolean newEm) {
|
||||||
|
|
||||||
super(emHolder, emf);
|
super(emHolder, emf);
|
||||||
this.transactionData = txData;
|
this.transactionData = txData;
|
||||||
this.jpaDialect = (emf instanceof EntityManagerFactoryInfo ?
|
this.jpaDialect = (emf instanceof EntityManagerFactoryInfo ?
|
||||||
|
|
@ -488,7 +490,9 @@ public abstract class EntityManagerFactoryUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void cleanupResource(EntityManagerHolder resourceHolder, EntityManagerFactory resourceKey, boolean committed) {
|
protected void cleanupResource(
|
||||||
|
EntityManagerHolder resourceHolder, EntityManagerFactory resourceKey, boolean committed) {
|
||||||
|
|
||||||
if (!committed) {
|
if (!committed) {
|
||||||
// Clear all pending inserts/updates/deletes in the EntityManager.
|
// Clear all pending inserts/updates/deletes in the EntityManager.
|
||||||
// Necessary for pre-bound EntityManagers, to avoid inconsistent state.
|
// Necessary for pre-bound EntityManagers, to avoid inconsistent state.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2015 the original author or authors.
|
* Copyright 2002-2017 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,8 +30,11 @@ import org.testng.ITestResult;
|
||||||
public class TrackingTestNGTestListener implements ITestListener {
|
public class TrackingTestNGTestListener implements ITestListener {
|
||||||
|
|
||||||
public int testStartCount = 0;
|
public int testStartCount = 0;
|
||||||
|
|
||||||
public int testSuccessCount = 0;
|
public int testSuccessCount = 0;
|
||||||
|
|
||||||
public int testFailureCount = 0;
|
public int testFailureCount = 0;
|
||||||
|
|
||||||
public int failedConfigurationsCount = 0;
|
public int failedConfigurationsCount = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -66,4 +69,5 @@ public class TrackingTestNGTestListener implements ITestListener {
|
||||||
public void onTestSuccess(ITestResult testResult) {
|
public void onTestSuccess(ITestResult testResult) {
|
||||||
this.testSuccessCount++;
|
this.testSuccessCount++;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,7 @@ import org.springframework.web.reactive.function.client.ClientRequest;
|
||||||
import org.springframework.web.reactive.function.client.ExchangeFunction;
|
import org.springframework.web.reactive.function.client.ExchangeFunction;
|
||||||
import org.springframework.web.reactive.function.client.ExchangeFunctions;
|
import org.springframework.web.reactive.function.client.ExchangeFunctions;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.*;
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@link WiretapConnector}.
|
* Unit tests for {@link WiretapConnector}.
|
||||||
|
|
@ -46,7 +45,6 @@ public class WebTestClientConnectorTests {
|
||||||
@Test
|
@Test
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public void captureAndClaim() throws Exception {
|
public void captureAndClaim() throws Exception {
|
||||||
|
|
||||||
ClientHttpRequest request = new MockClientHttpRequest(HttpMethod.GET, "/test");
|
ClientHttpRequest request = new MockClientHttpRequest(HttpMethod.GET, "/test");
|
||||||
ClientHttpResponse response = new MockClientHttpResponse(HttpStatus.OK);
|
ClientHttpResponse response = new MockClientHttpResponse(HttpStatus.OK);
|
||||||
ClientHttpConnector connector = (method, uri, fn) -> fn.apply(request).then(Mono.just(response));
|
ClientHttpConnector connector = (method, uri, fn) -> fn.apply(request).then(Mono.just(response));
|
||||||
|
|
|
||||||
|
|
@ -64,13 +64,15 @@ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates whether this request factory should buffer the {@linkplain ClientHttpRequest#getBody() request body}
|
* Indicate whether this request factory should buffer the
|
||||||
* internally.
|
* {@linkplain ClientHttpRequest#getBody() request body} internally.
|
||||||
* <p>Default is {@code true}. When sending large amounts of data via POST or PUT, it is recommended
|
* <p>Default is {@code true}. When sending large amounts of data via POST or PUT,
|
||||||
* to change this property to {@code false}, so as not to run out of memory. This will result in a
|
* it is recommended to change this property to {@code false}, so as not to run
|
||||||
* {@link ClientHttpRequest} that either streams directly to the underlying {@link HttpURLConnection}
|
* out of memory. This will result in a {@link ClientHttpRequest} that either
|
||||||
* (if the {@link org.springframework.http.HttpHeaders#getContentLength() Content-Length} is known in advance),
|
* streams directly to the underlying {@link HttpURLConnection} (if the
|
||||||
* or that will use "Chunked transfer encoding" (if the {@code Content-Length} is not known in advance).
|
* {@link org.springframework.http.HttpHeaders#getContentLength() Content-Length}
|
||||||
|
* is known in advance), or that will use "Chunked transfer encoding"
|
||||||
|
* (if the {@code Content-Length} is not known in advance).
|
||||||
* @see #setChunkSize(int)
|
* @see #setChunkSize(int)
|
||||||
* @see HttpURLConnection#setFixedLengthStreamingMode(int)
|
* @see HttpURLConnection#setFixedLengthStreamingMode(int)
|
||||||
*/
|
*/
|
||||||
|
|
@ -79,9 +81,11 @@ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the number of bytes to write in each chunk when not buffering request bodies locally.
|
* Set the number of bytes to write in each chunk when not buffering request
|
||||||
* <p>Note that this parameter is only used when {@link #setBufferRequestBody(boolean) bufferRequestBody} is set
|
* bodies locally.
|
||||||
* to {@code false}, and the {@link org.springframework.http.HttpHeaders#getContentLength() Content-Length}
|
* <p>Note that this parameter is only used when
|
||||||
|
* {@link #setBufferRequestBody(boolean) bufferRequestBody} is set to {@code false},
|
||||||
|
* and the {@link org.springframework.http.HttpHeaders#getContentLength() Content-Length}
|
||||||
* is not known in advance.
|
* is not known in advance.
|
||||||
* @see #setBufferRequestBody(boolean)
|
* @see #setBufferRequestBody(boolean)
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* 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.
|
||||||
|
|
@ -248,11 +248,11 @@ public class WebDataBinder extends DataBinder {
|
||||||
* Determine an empty value for the specified field.
|
* Determine an empty value for the specified field.
|
||||||
* <p>Default implementation returns:
|
* <p>Default implementation returns:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@code Boolean.FALSE} for boolean fields
|
* <li>{@code Boolean.FALSE} for boolean fields
|
||||||
* <li>an empty array for array types
|
* <li>an empty array for array types
|
||||||
* <li>Collection implementations for Collection types
|
* <li>Collection implementations for Collection types
|
||||||
* <li>Map implementations for Map types
|
* <li>Map implementations for Map types
|
||||||
* <li>else, {@code null} is used as default
|
* <li>else, {@code null} is used as default
|
||||||
* </ul>
|
* </ul>
|
||||||
* @param field the name of the field
|
* @param field the name of the field
|
||||||
* @param fieldType the type of the field
|
* @param fieldType the type of the field
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import java.util.TreeMap;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import org.springframework.beans.MutablePropertyValues;
|
import org.springframework.beans.MutablePropertyValues;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.util.MultiValueMap;
|
import org.springframework.util.MultiValueMap;
|
||||||
import org.springframework.web.bind.WebDataBinder;
|
import org.springframework.web.bind.WebDataBinder;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
@ -82,16 +83,14 @@ public class WebExchangeDataBinder extends WebDataBinder {
|
||||||
for (Map.Entry<String, List<String>> entry : params.entrySet()) {
|
for (Map.Entry<String, List<String>> entry : params.entrySet()) {
|
||||||
String name = entry.getKey();
|
String name = entry.getKey();
|
||||||
List<String> values = entry.getValue();
|
List<String> values = entry.getValue();
|
||||||
if (values == null || values.isEmpty()) {
|
if (CollectionUtils.isEmpty(values)) {
|
||||||
// Do nothing, no values found at all.
|
// Do nothing, no values found at all.
|
||||||
}
|
}
|
||||||
|
else if (values.size() == 1) {
|
||||||
|
result.put(name, values.get(0));
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
if (values.size() > 1) {
|
result.put(name, values);
|
||||||
result.put(name, values);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result.put(name, values.get(0));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -113,7 +112,7 @@ public class WebExchangeDataBinder extends WebDataBinder {
|
||||||
/**
|
/**
|
||||||
* Extension point that subclasses can use to add extra bind values for a
|
* Extension point that subclasses can use to add extra bind values for a
|
||||||
* request. Invoked before {@link #doBind(MutablePropertyValues)}.
|
* request. Invoked before {@link #doBind(MutablePropertyValues)}.
|
||||||
* The default implementation is empty.
|
* <p>The default implementation is empty.
|
||||||
* @param exchange the current exchange
|
* @param exchange the current exchange
|
||||||
*/
|
*/
|
||||||
protected Map<String, ?> getExtraValuesToBind(ServerWebExchange exchange) {
|
protected Map<String, ?> getExtraValuesToBind(ServerWebExchange exchange) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2017 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.
|
||||||
|
|
@ -21,7 +21,8 @@ import java.io.IOException;
|
||||||
import org.springframework.http.client.ClientHttpResponse;
|
import org.springframework.http.client.ClientHttpResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Strategy interface used by the {@link RestTemplate} to determine whether a particular response has an error or not.
|
* Strategy interface used by the {@link RestTemplate} to determine
|
||||||
|
* whether a particular response has an error or not.
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
|
|
@ -29,9 +30,9 @@ import org.springframework.http.client.ClientHttpResponse;
|
||||||
public interface ResponseErrorHandler {
|
public interface ResponseErrorHandler {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates whether the given response has any errors.
|
* Indicate whether the given response has any errors.
|
||||||
* Implementations will typically inspect the {@link ClientHttpResponse#getStatusCode() HttpStatus}
|
* <p>Implementations will typically inspect the
|
||||||
* of the response.
|
* {@link ClientHttpResponse#getStatusCode() HttpStatus} of the response.
|
||||||
* @param response the response to inspect
|
* @param response the response to inspect
|
||||||
* @return {@code true} if the response has an error; {@code false} otherwise
|
* @return {@code true} if the response has an error; {@code false} otherwise
|
||||||
* @throws IOException in case of I/O errors
|
* @throws IOException in case of I/O errors
|
||||||
|
|
@ -39,10 +40,12 @@ public interface ResponseErrorHandler {
|
||||||
boolean hasError(ClientHttpResponse response) throws IOException;
|
boolean hasError(ClientHttpResponse response) throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the error in the given response.
|
* Handle the error in the given response.
|
||||||
* This method is only called when {@link #hasError(ClientHttpResponse)} has returned {@code true}.
|
* <p>This method is only called when {@link #hasError(ClientHttpResponse)}
|
||||||
|
* has returned {@code true}.
|
||||||
* @param response the response with the error
|
* @param response the response with the error
|
||||||
* @throws IOException in case of I/O errors
|
* @throws IOException in case of I/O errors
|
||||||
*/
|
*/
|
||||||
void handleError(ClientHttpResponse response) throws IOException;
|
void handleError(ClientHttpResponse response) throws IOException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2008 the original author or authors.
|
* Copyright 2002-2017 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.
|
||||||
|
|
@ -45,90 +45,88 @@ class HtmlCharacterEntityDecoder {
|
||||||
public HtmlCharacterEntityDecoder(HtmlCharacterEntityReferences characterEntityReferences, String original) {
|
public HtmlCharacterEntityDecoder(HtmlCharacterEntityReferences characterEntityReferences, String original) {
|
||||||
this.characterEntityReferences = characterEntityReferences;
|
this.characterEntityReferences = characterEntityReferences;
|
||||||
this.originalMessage = original;
|
this.originalMessage = original;
|
||||||
this.decodedMessage = new StringBuilder(originalMessage.length());
|
this.decodedMessage = new StringBuilder(original.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String decode() {
|
public String decode() {
|
||||||
while (currentPosition < originalMessage.length()) {
|
while (this.currentPosition < this.originalMessage.length()) {
|
||||||
findNextPotentialReference(currentPosition);
|
findNextPotentialReference(this.currentPosition);
|
||||||
copyCharactersTillPotentialReference();
|
copyCharactersTillPotentialReference();
|
||||||
processPossibleReference();
|
processPossibleReference();
|
||||||
}
|
}
|
||||||
return decodedMessage.toString();
|
return this.decodedMessage.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void findNextPotentialReference(int startPosition) {
|
private void findNextPotentialReference(int startPosition) {
|
||||||
nextPotentialReferencePosition = Math.max(startPosition, nextSemicolonPosition - MAX_REFERENCE_SIZE);
|
this.nextPotentialReferencePosition = Math.max(startPosition, this.nextSemicolonPosition - MAX_REFERENCE_SIZE);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
nextPotentialReferencePosition =
|
this.nextPotentialReferencePosition =
|
||||||
originalMessage.indexOf('&', nextPotentialReferencePosition);
|
this.originalMessage.indexOf('&', this.nextPotentialReferencePosition);
|
||||||
|
|
||||||
if (nextSemicolonPosition != -1 &&
|
if (this.nextSemicolonPosition != -1 &&
|
||||||
nextSemicolonPosition < nextPotentialReferencePosition)
|
this.nextSemicolonPosition < this.nextPotentialReferencePosition)
|
||||||
nextSemicolonPosition = originalMessage.indexOf(';', nextPotentialReferencePosition + 1);
|
this.nextSemicolonPosition = this.originalMessage.indexOf(';', this.nextPotentialReferencePosition + 1);
|
||||||
|
|
||||||
boolean isPotentialReference =
|
boolean isPotentialReference = (this.nextPotentialReferencePosition != -1 &&
|
||||||
nextPotentialReferencePosition != -1
|
this.nextSemicolonPosition != -1 &&
|
||||||
&& nextSemicolonPosition != -1
|
this.nextPotentialReferencePosition - this.nextSemicolonPosition < MAX_REFERENCE_SIZE);
|
||||||
&& nextPotentialReferencePosition - nextSemicolonPosition < MAX_REFERENCE_SIZE;
|
|
||||||
|
|
||||||
if (isPotentialReference) {
|
if (isPotentialReference) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (nextPotentialReferencePosition == -1) {
|
if (this.nextPotentialReferencePosition == -1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (nextSemicolonPosition == -1) {
|
if (this.nextSemicolonPosition == -1) {
|
||||||
nextPotentialReferencePosition = -1;
|
this.nextPotentialReferencePosition = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
nextPotentialReferencePosition = nextPotentialReferencePosition + 1;
|
this.nextPotentialReferencePosition = this.nextPotentialReferencePosition + 1;
|
||||||
}
|
}
|
||||||
while (nextPotentialReferencePosition != -1);
|
while (this.nextPotentialReferencePosition != -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void copyCharactersTillPotentialReference() {
|
private void copyCharactersTillPotentialReference() {
|
||||||
if (nextPotentialReferencePosition != currentPosition) {
|
if (this.nextPotentialReferencePosition != this.currentPosition) {
|
||||||
int skipUntilIndex = nextPotentialReferencePosition != -1 ?
|
int skipUntilIndex = (this.nextPotentialReferencePosition != -1 ?
|
||||||
nextPotentialReferencePosition : originalMessage.length();
|
this.nextPotentialReferencePosition : this.originalMessage.length());
|
||||||
if (skipUntilIndex - currentPosition > 3) {
|
if (skipUntilIndex - this.currentPosition > 3) {
|
||||||
decodedMessage.append(originalMessage.substring(currentPosition, skipUntilIndex));
|
this.decodedMessage.append(this.originalMessage.substring(this.currentPosition, skipUntilIndex));
|
||||||
currentPosition = skipUntilIndex;
|
this.currentPosition = skipUntilIndex;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
while (currentPosition < skipUntilIndex)
|
while (this.currentPosition < skipUntilIndex)
|
||||||
decodedMessage.append(originalMessage.charAt(currentPosition++));
|
this.decodedMessage.append(this.originalMessage.charAt(this.currentPosition++));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processPossibleReference() {
|
private void processPossibleReference() {
|
||||||
if (nextPotentialReferencePosition != -1) {
|
if (this.nextPotentialReferencePosition != -1) {
|
||||||
boolean isNumberedReference = originalMessage.charAt(currentPosition + 1) == '#';
|
boolean isNumberedReference = (this.originalMessage.charAt(this.currentPosition + 1) == '#');
|
||||||
boolean wasProcessable = isNumberedReference ? processNumberedReference() : processNamedReference();
|
boolean wasProcessable = isNumberedReference ? processNumberedReference() : processNamedReference();
|
||||||
if (wasProcessable) {
|
if (wasProcessable) {
|
||||||
currentPosition = nextSemicolonPosition + 1;
|
this.currentPosition = this.nextSemicolonPosition + 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
char currentChar = originalMessage.charAt(currentPosition);
|
char currentChar = this.originalMessage.charAt(this.currentPosition);
|
||||||
decodedMessage.append(currentChar);
|
this.decodedMessage.append(currentChar);
|
||||||
currentPosition++;
|
this.currentPosition++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean processNumberedReference() {
|
private boolean processNumberedReference() {
|
||||||
boolean isHexNumberedReference =
|
char referenceChar = this.originalMessage.charAt(this.nextPotentialReferencePosition + 2);
|
||||||
originalMessage.charAt(nextPotentialReferencePosition + 2) == 'x' ||
|
boolean isHexNumberedReference = (referenceChar == 'x' || referenceChar == 'X');
|
||||||
originalMessage.charAt(nextPotentialReferencePosition + 2) == 'X';
|
|
||||||
try {
|
try {
|
||||||
int value = (!isHexNumberedReference) ?
|
int value = (!isHexNumberedReference ?
|
||||||
Integer.parseInt(getReferenceSubstring(2)) :
|
Integer.parseInt(getReferenceSubstring(2)) :
|
||||||
Integer.parseInt(getReferenceSubstring(3), 16);
|
Integer.parseInt(getReferenceSubstring(3), 16));
|
||||||
decodedMessage.append((char) value);
|
this.decodedMessage.append((char) value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (NumberFormatException ex) {
|
catch (NumberFormatException ex) {
|
||||||
|
|
@ -138,16 +136,17 @@ class HtmlCharacterEntityDecoder {
|
||||||
|
|
||||||
private boolean processNamedReference() {
|
private boolean processNamedReference() {
|
||||||
String referenceName = getReferenceSubstring(1);
|
String referenceName = getReferenceSubstring(1);
|
||||||
char mappedCharacter = characterEntityReferences.convertToCharacter(referenceName);
|
char mappedCharacter = this.characterEntityReferences.convertToCharacter(referenceName);
|
||||||
if (mappedCharacter != HtmlCharacterEntityReferences.CHAR_NULL) {
|
if (mappedCharacter != HtmlCharacterEntityReferences.CHAR_NULL) {
|
||||||
decodedMessage.append(mappedCharacter);
|
this.decodedMessage.append(mappedCharacter);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getReferenceSubstring(int referenceOffset) {
|
private String getReferenceSubstring(int referenceOffset) {
|
||||||
return originalMessage.substring(nextPotentialReferencePosition + referenceOffset, nextSemicolonPosition);
|
return this.originalMessage.substring(
|
||||||
|
this.nextPotentialReferencePosition + referenceOffset, this.nextSemicolonPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* 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.
|
||||||
|
|
@ -43,7 +43,7 @@ import static org.junit.Assert.*;
|
||||||
*/
|
*/
|
||||||
public class GsonHttpMessageConverterTests {
|
public class GsonHttpMessageConverterTests {
|
||||||
|
|
||||||
private GsonHttpMessageConverter converter = new GsonHttpMessageConverter();
|
private final GsonHttpMessageConverter converter = new GsonHttpMessageConverter();
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* 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.
|
||||||
|
|
@ -45,13 +45,13 @@ import static org.junit.Assert.assertTrue;
|
||||||
*/
|
*/
|
||||||
public class WebExchangeDataBinderTests {
|
public class WebExchangeDataBinderTests {
|
||||||
|
|
||||||
private WebExchangeDataBinder binder;
|
|
||||||
|
|
||||||
private TestBean testBean;
|
private TestBean testBean;
|
||||||
|
|
||||||
|
private WebExchangeDataBinder binder;
|
||||||
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setup() throws Exception {
|
||||||
this.testBean = new TestBean();
|
this.testBean = new TestBean();
|
||||||
this.binder = new WebExchangeDataBinder(this.testBean, "person");
|
this.binder = new WebExchangeDataBinder(this.testBean, "person");
|
||||||
this.binder.registerCustomEditor(ITestBean.class, new TestBeanPropertyEditor());
|
this.binder.registerCustomEditor(ITestBean.class, new TestBeanPropertyEditor());
|
||||||
|
|
@ -177,6 +177,7 @@ public class WebExchangeDataBinderTests {
|
||||||
assertEquals("test", this.testBean.getSpouse().getName());
|
assertEquals("test", this.testBean.getSpouse().getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private String generateForm(MultiValueMap<String, String> form) {
|
private String generateForm(MultiValueMap<String, String> form) {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -41,10 +41,17 @@ public class BindingContext {
|
||||||
private final Model model = new BindingAwareConcurrentModel();
|
private final Model model = new BindingAwareConcurrentModel();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@code BindingContext}.
|
||||||
|
*/
|
||||||
public BindingContext() {
|
public BindingContext() {
|
||||||
this(null);
|
this(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@code BindingContext} with the given initializer.
|
||||||
|
* @param initializer the binding initializer to apply (may be {@code null})
|
||||||
|
*/
|
||||||
public BindingContext(WebBindingInitializer initializer) {
|
public BindingContext(WebBindingInitializer initializer) {
|
||||||
this.initializer = initializer;
|
this.initializer = initializer;
|
||||||
}
|
}
|
||||||
|
|
@ -61,11 +68,9 @@ public class BindingContext {
|
||||||
/**
|
/**
|
||||||
* Create a {@link WebExchangeDataBinder} to apply data binding and
|
* Create a {@link WebExchangeDataBinder} to apply data binding and
|
||||||
* validation with on the target, command object.
|
* validation with on the target, command object.
|
||||||
*
|
|
||||||
* @param exchange the current exchange
|
* @param exchange the current exchange
|
||||||
* @param target the object to create a data binder for
|
* @param target the object to create a data binder for
|
||||||
* @param name the name of the target object
|
* @param name the name of the target object
|
||||||
*
|
|
||||||
* @return the created data binder
|
* @return the created data binder
|
||||||
*/
|
*/
|
||||||
public WebExchangeDataBinder createDataBinder(ServerWebExchange exchange, Object target, String name) {
|
public WebExchangeDataBinder createDataBinder(ServerWebExchange exchange, Object target, String name) {
|
||||||
|
|
@ -86,10 +91,8 @@ public class BindingContext {
|
||||||
/**
|
/**
|
||||||
* Create a {@link WebExchangeDataBinder} without a target object for type
|
* Create a {@link WebExchangeDataBinder} without a target object for type
|
||||||
* conversion of request values to simple types.
|
* conversion of request values to simple types.
|
||||||
*
|
|
||||||
* @param exchange the current exchange
|
* @param exchange the current exchange
|
||||||
* @param name the name of the target object
|
* @param name the name of the target object
|
||||||
*
|
|
||||||
* @return the created data binder
|
* @return the created data binder
|
||||||
*/
|
*/
|
||||||
public WebExchangeDataBinder createDataBinder(ServerWebExchange exchange, String name) {
|
public WebExchangeDataBinder createDataBinder(ServerWebExchange exchange, String name) {
|
||||||
|
|
|
||||||
|
|
@ -49,10 +49,10 @@ import reactor.core.publisher.Mono
|
||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
|
* @author Sebastien Deleuze
|
||||||
|
* @author Yevhenii Melnyk
|
||||||
* @since 5.0
|
* @since 5.0
|
||||||
* @see <a href="https://youtrack.jetbrains.com/issue/KT-15667">Kotlin issue about supporting ::foo for member functions</a>
|
* @see <a href="https://youtrack.jetbrains.com/issue/KT-15667">Kotlin issue about supporting ::foo for member functions</a>
|
||||||
* @author Sebastien De leuze
|
|
||||||
* @author Yevhenii Melnyk
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typealias Routes = RouterDsl.() -> Unit
|
typealias Routes = RouterDsl.() -> Unit
|
||||||
|
|
@ -177,7 +177,6 @@ class RouterDsl {
|
||||||
|
|
||||||
fun pathExtension(predicate: (String) -> Boolean) = RequestPredicates.pathExtension(predicate)
|
fun pathExtension(predicate: (String) -> Boolean) = RequestPredicates.pathExtension(predicate)
|
||||||
|
|
||||||
|
|
||||||
fun queryParam(name: String, predicate: (String) -> Boolean, f: (ServerRequest) -> Mono<ServerResponse>) {
|
fun queryParam(name: String, predicate: (String) -> Boolean, f: (ServerRequest) -> Mono<ServerResponse>) {
|
||||||
routes += RouterFunctions.route(RequestPredicates.queryParam(name, predicate), HandlerFunction { f(it) })
|
routes += RouterFunctions.route(RequestPredicates.queryParam(name, predicate), HandlerFunction { f(it) })
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2017 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.
|
||||||
|
|
@ -54,6 +54,7 @@ public class ExtendedServletRequestDataBinder extends ServletRequestDataBinder {
|
||||||
super(target, objectName);
|
super(target, objectName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merge URI variables into the property values to use for data binding.
|
* Merge URI variables into the property values to use for data binding.
|
||||||
*/
|
*/
|
||||||
|
|
@ -65,8 +66,10 @@ public class ExtendedServletRequestDataBinder extends ServletRequestDataBinder {
|
||||||
if (uriVars != null) {
|
if (uriVars != null) {
|
||||||
for (Entry<String, String> entry : uriVars.entrySet()) {
|
for (Entry<String, String> entry : uriVars.entrySet()) {
|
||||||
if (mpvs.contains(entry.getKey())) {
|
if (mpvs.contains(entry.getKey())) {
|
||||||
logger.warn("Skipping URI variable '" + entry.getKey()
|
if (logger.isWarnEnabled()) {
|
||||||
+ "' since the request contains a bind value with the same name.");
|
logger.warn("Skipping URI variable '" + entry.getKey() +
|
||||||
|
"' since the request contains a bind value with the same name.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mpvs.addPropertyValue(entry.getKey(), entry.getValue());
|
mpvs.addPropertyValue(entry.getKey(), entry.getValue());
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* 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.
|
||||||
|
|
@ -48,6 +48,7 @@ import org.springframework.web.servlet.HandlerMapping;
|
||||||
public class ServletModelAttributeMethodProcessor extends ModelAttributeMethodProcessor {
|
public class ServletModelAttributeMethodProcessor extends ModelAttributeMethodProcessor {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Class constructor.
|
||||||
* @param annotationNotRequired if "true", non-simple method arguments and
|
* @param annotationNotRequired if "true", non-simple method arguments and
|
||||||
* return values are considered model attributes with or without a
|
* return values are considered model attributes with or without a
|
||||||
* {@code @ModelAttribute} annotation
|
* {@code @ModelAttribute} annotation
|
||||||
|
|
@ -87,19 +88,19 @@ public class ServletModelAttributeMethodProcessor extends ModelAttributeMethodPr
|
||||||
* a URI variable first and then a request parameter.
|
* a URI variable first and then a request parameter.
|
||||||
* @param attributeName the model attribute name
|
* @param attributeName the model attribute name
|
||||||
* @param request the current request
|
* @param request the current request
|
||||||
* @return the request value to try to convert or {@code null}
|
* @return the request value to try to convert, or {@code null} if none
|
||||||
*/
|
*/
|
||||||
protected String getRequestValueForAttribute(String attributeName, NativeWebRequest request) {
|
protected String getRequestValueForAttribute(String attributeName, NativeWebRequest request) {
|
||||||
Map<String, String> variables = getUriTemplateVariables(request);
|
Map<String, String> variables = getUriTemplateVariables(request);
|
||||||
if (StringUtils.hasText(variables.get(attributeName))) {
|
String variableValue = variables.get(attributeName);
|
||||||
return variables.get(attributeName);
|
if (StringUtils.hasText(variableValue)) {
|
||||||
|
return variableValue;
|
||||||
}
|
}
|
||||||
else if (StringUtils.hasText(request.getParameter(attributeName))) {
|
String parameterValue = request.getParameter(attributeName);
|
||||||
return request.getParameter(attributeName);
|
if (StringUtils.hasText(parameterValue)) {
|
||||||
}
|
return parameterValue;
|
||||||
else {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|
@ -115,11 +116,12 @@ public class ServletModelAttributeMethodProcessor extends ModelAttributeMethodPr
|
||||||
* <p>The default implementation converts only if there a registered
|
* <p>The default implementation converts only if there a registered
|
||||||
* {@link Converter} that can perform the conversion.
|
* {@link Converter} that can perform the conversion.
|
||||||
* @param sourceValue the source value to create the model attribute from
|
* @param sourceValue the source value to create the model attribute from
|
||||||
* @param attributeName the name of the attribute, never {@code null}
|
* @param attributeName the name of the attribute (never {@code null})
|
||||||
* @param methodParam the method parameter
|
* @param methodParam the method parameter
|
||||||
* @param binderFactory for creating WebDataBinder instance
|
* @param binderFactory for creating WebDataBinder instance
|
||||||
* @param request the current request
|
* @param request the current request
|
||||||
* @return the created model attribute, or {@code null}
|
* @return the created model attribute, or {@code null} if no suitable
|
||||||
|
* conversion found
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected Object createAttributeFromRequestValue(String sourceValue, String attributeName,
|
protected Object createAttributeFromRequestValue(String sourceValue, String attributeName,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue