Polishing
This commit is contained in:
@@ -64,13 +64,15 @@ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory,
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this request factory should buffer the {@linkplain ClientHttpRequest#getBody() request body}
|
||||
* internally.
|
||||
* <p>Default is {@code true}. When sending large amounts of data via POST or PUT, it is recommended
|
||||
* to change this property to {@code false}, so as not to run out of memory. This will result in a
|
||||
* {@link ClientHttpRequest} that either streams directly to the underlying {@link HttpURLConnection}
|
||||
* (if the {@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).
|
||||
* Indicate whether this request factory should buffer the
|
||||
* {@linkplain ClientHttpRequest#getBody() request body} internally.
|
||||
* <p>Default is {@code true}. When sending large amounts of data via POST or PUT,
|
||||
* it is recommended to change this property to {@code false}, so as not to run
|
||||
* out of memory. This will result in a {@link ClientHttpRequest} that either
|
||||
* streams directly to the underlying {@link HttpURLConnection} (if the
|
||||
* {@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 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.
|
||||
* <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}
|
||||
* Set the number of bytes to write in each chunk when not buffering request
|
||||
* bodies locally.
|
||||
* <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.
|
||||
* @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");
|
||||
* 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.
|
||||
* <p>Default implementation returns:
|
||||
* <ul>
|
||||
* <li>{@code Boolean.FALSE} for boolean fields
|
||||
* <li>an empty array for array types
|
||||
* <li>Collection implementations for Collection types
|
||||
* <li>Map implementations for Map types
|
||||
* <li>else, {@code null} is used as default
|
||||
* <li>{@code Boolean.FALSE} for boolean fields
|
||||
* <li>an empty array for array types
|
||||
* <li>Collection implementations for Collection types
|
||||
* <li>Map implementations for Map types
|
||||
* <li>else, {@code null} is used as default
|
||||
* </ul>
|
||||
* @param field the name of the field
|
||||
* @param fieldType the type of the field
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.TreeMap;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
@@ -82,16 +83,14 @@ public class WebExchangeDataBinder extends WebDataBinder {
|
||||
for (Map.Entry<String, List<String>> entry : params.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
List<String> values = entry.getValue();
|
||||
if (values == null || values.isEmpty()) {
|
||||
if (CollectionUtils.isEmpty(values)) {
|
||||
// Do nothing, no values found at all.
|
||||
}
|
||||
else if (values.size() == 1) {
|
||||
result.put(name, values.get(0));
|
||||
}
|
||||
else {
|
||||
if (values.size() > 1) {
|
||||
result.put(name, values);
|
||||
}
|
||||
else {
|
||||
result.put(name, values.get(0));
|
||||
}
|
||||
result.put(name, values);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -113,7 +112,7 @@ public class WebExchangeDataBinder extends WebDataBinder {
|
||||
/**
|
||||
* Extension point that subclasses can use to add extra bind values for a
|
||||
* request. Invoked before {@link #doBind(MutablePropertyValues)}.
|
||||
* The default implementation is empty.
|
||||
* <p>The default implementation is empty.
|
||||
* @param exchange the current 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");
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @since 3.0
|
||||
@@ -29,9 +30,9 @@ import org.springframework.http.client.ClientHttpResponse;
|
||||
public interface ResponseErrorHandler {
|
||||
|
||||
/**
|
||||
* Indicates whether the given response has any errors.
|
||||
* Implementations will typically inspect the {@link ClientHttpResponse#getStatusCode() HttpStatus}
|
||||
* of the response.
|
||||
* Indicate whether the given response has any errors.
|
||||
* <p>Implementations will typically inspect the
|
||||
* {@link ClientHttpResponse#getStatusCode() HttpStatus} of the response.
|
||||
* @param response the response to inspect
|
||||
* @return {@code true} if the response has an error; {@code false} otherwise
|
||||
* @throws IOException in case of I/O errors
|
||||
@@ -39,10 +40,12 @@ public interface ResponseErrorHandler {
|
||||
boolean hasError(ClientHttpResponse response) throws IOException;
|
||||
|
||||
/**
|
||||
* Handles the error in the given response.
|
||||
* This method is only called when {@link #hasError(ClientHttpResponse)} has returned {@code true}.
|
||||
* Handle the error in the given response.
|
||||
* <p>This method is only called when {@link #hasError(ClientHttpResponse)}
|
||||
* has returned {@code true}.
|
||||
* @param response the response with the error
|
||||
* @throws IOException in case of I/O errors
|
||||
*/
|
||||
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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -45,90 +45,88 @@ class HtmlCharacterEntityDecoder {
|
||||
public HtmlCharacterEntityDecoder(HtmlCharacterEntityReferences characterEntityReferences, String original) {
|
||||
this.characterEntityReferences = characterEntityReferences;
|
||||
this.originalMessage = original;
|
||||
this.decodedMessage = new StringBuilder(originalMessage.length());
|
||||
this.decodedMessage = new StringBuilder(original.length());
|
||||
}
|
||||
|
||||
|
||||
public String decode() {
|
||||
while (currentPosition < originalMessage.length()) {
|
||||
findNextPotentialReference(currentPosition);
|
||||
while (this.currentPosition < this.originalMessage.length()) {
|
||||
findNextPotentialReference(this.currentPosition);
|
||||
copyCharactersTillPotentialReference();
|
||||
processPossibleReference();
|
||||
}
|
||||
return decodedMessage.toString();
|
||||
return this.decodedMessage.toString();
|
||||
}
|
||||
|
||||
private void findNextPotentialReference(int startPosition) {
|
||||
nextPotentialReferencePosition = Math.max(startPosition, nextSemicolonPosition - MAX_REFERENCE_SIZE);
|
||||
this.nextPotentialReferencePosition = Math.max(startPosition, this.nextSemicolonPosition - MAX_REFERENCE_SIZE);
|
||||
|
||||
do {
|
||||
nextPotentialReferencePosition =
|
||||
originalMessage.indexOf('&', nextPotentialReferencePosition);
|
||||
this.nextPotentialReferencePosition =
|
||||
this.originalMessage.indexOf('&', this.nextPotentialReferencePosition);
|
||||
|
||||
if (nextSemicolonPosition != -1 &&
|
||||
nextSemicolonPosition < nextPotentialReferencePosition)
|
||||
nextSemicolonPosition = originalMessage.indexOf(';', nextPotentialReferencePosition + 1);
|
||||
if (this.nextSemicolonPosition != -1 &&
|
||||
this.nextSemicolonPosition < this.nextPotentialReferencePosition)
|
||||
this.nextSemicolonPosition = this.originalMessage.indexOf(';', this.nextPotentialReferencePosition + 1);
|
||||
|
||||
boolean isPotentialReference =
|
||||
nextPotentialReferencePosition != -1
|
||||
&& nextSemicolonPosition != -1
|
||||
&& nextPotentialReferencePosition - nextSemicolonPosition < MAX_REFERENCE_SIZE;
|
||||
boolean isPotentialReference = (this.nextPotentialReferencePosition != -1 &&
|
||||
this.nextSemicolonPosition != -1 &&
|
||||
this.nextPotentialReferencePosition - this.nextSemicolonPosition < MAX_REFERENCE_SIZE);
|
||||
|
||||
if (isPotentialReference) {
|
||||
break;
|
||||
}
|
||||
if (nextPotentialReferencePosition == -1) {
|
||||
if (this.nextPotentialReferencePosition == -1) {
|
||||
break;
|
||||
}
|
||||
if (nextSemicolonPosition == -1) {
|
||||
nextPotentialReferencePosition = -1;
|
||||
if (this.nextSemicolonPosition == -1) {
|
||||
this.nextPotentialReferencePosition = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
nextPotentialReferencePosition = nextPotentialReferencePosition + 1;
|
||||
this.nextPotentialReferencePosition = this.nextPotentialReferencePosition + 1;
|
||||
}
|
||||
while (nextPotentialReferencePosition != -1);
|
||||
while (this.nextPotentialReferencePosition != -1);
|
||||
}
|
||||
|
||||
|
||||
private void copyCharactersTillPotentialReference() {
|
||||
if (nextPotentialReferencePosition != currentPosition) {
|
||||
int skipUntilIndex = nextPotentialReferencePosition != -1 ?
|
||||
nextPotentialReferencePosition : originalMessage.length();
|
||||
if (skipUntilIndex - currentPosition > 3) {
|
||||
decodedMessage.append(originalMessage.substring(currentPosition, skipUntilIndex));
|
||||
currentPosition = skipUntilIndex;
|
||||
if (this.nextPotentialReferencePosition != this.currentPosition) {
|
||||
int skipUntilIndex = (this.nextPotentialReferencePosition != -1 ?
|
||||
this.nextPotentialReferencePosition : this.originalMessage.length());
|
||||
if (skipUntilIndex - this.currentPosition > 3) {
|
||||
this.decodedMessage.append(this.originalMessage.substring(this.currentPosition, skipUntilIndex));
|
||||
this.currentPosition = skipUntilIndex;
|
||||
}
|
||||
else {
|
||||
while (currentPosition < skipUntilIndex)
|
||||
decodedMessage.append(originalMessage.charAt(currentPosition++));
|
||||
while (this.currentPosition < skipUntilIndex)
|
||||
this.decodedMessage.append(this.originalMessage.charAt(this.currentPosition++));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processPossibleReference() {
|
||||
if (nextPotentialReferencePosition != -1) {
|
||||
boolean isNumberedReference = originalMessage.charAt(currentPosition + 1) == '#';
|
||||
if (this.nextPotentialReferencePosition != -1) {
|
||||
boolean isNumberedReference = (this.originalMessage.charAt(this.currentPosition + 1) == '#');
|
||||
boolean wasProcessable = isNumberedReference ? processNumberedReference() : processNamedReference();
|
||||
if (wasProcessable) {
|
||||
currentPosition = nextSemicolonPosition + 1;
|
||||
this.currentPosition = this.nextSemicolonPosition + 1;
|
||||
}
|
||||
else {
|
||||
char currentChar = originalMessage.charAt(currentPosition);
|
||||
decodedMessage.append(currentChar);
|
||||
currentPosition++;
|
||||
char currentChar = this.originalMessage.charAt(this.currentPosition);
|
||||
this.decodedMessage.append(currentChar);
|
||||
this.currentPosition++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean processNumberedReference() {
|
||||
boolean isHexNumberedReference =
|
||||
originalMessage.charAt(nextPotentialReferencePosition + 2) == 'x' ||
|
||||
originalMessage.charAt(nextPotentialReferencePosition + 2) == 'X';
|
||||
char referenceChar = this.originalMessage.charAt(this.nextPotentialReferencePosition + 2);
|
||||
boolean isHexNumberedReference = (referenceChar == 'x' || referenceChar == 'X');
|
||||
try {
|
||||
int value = (!isHexNumberedReference) ?
|
||||
int value = (!isHexNumberedReference ?
|
||||
Integer.parseInt(getReferenceSubstring(2)) :
|
||||
Integer.parseInt(getReferenceSubstring(3), 16);
|
||||
decodedMessage.append((char) value);
|
||||
Integer.parseInt(getReferenceSubstring(3), 16));
|
||||
this.decodedMessage.append((char) value);
|
||||
return true;
|
||||
}
|
||||
catch (NumberFormatException ex) {
|
||||
@@ -138,16 +136,17 @@ class HtmlCharacterEntityDecoder {
|
||||
|
||||
private boolean processNamedReference() {
|
||||
String referenceName = getReferenceSubstring(1);
|
||||
char mappedCharacter = characterEntityReferences.convertToCharacter(referenceName);
|
||||
char mappedCharacter = this.characterEntityReferences.convertToCharacter(referenceName);
|
||||
if (mappedCharacter != HtmlCharacterEntityReferences.CHAR_NULL) {
|
||||
decodedMessage.append(mappedCharacter);
|
||||
this.decodedMessage.append(mappedCharacter);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String getReferenceSubstring(int referenceOffset) {
|
||||
return originalMessage.substring(nextPotentialReferencePosition + referenceOffset, nextSemicolonPosition);
|
||||
return this.originalMessage.substring(
|
||||
this.nextPotentialReferencePosition + referenceOffset, this.nextSemicolonPosition);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user