Merge branch '5.2.x'
This commit is contained in:
commit
2a74f20c99
|
@ -97,8 +97,6 @@ public abstract class StreamUtils {
|
||||||
/**
|
/**
|
||||||
* Copy the contents of the given {@link ByteArrayOutputStream} into a {@link String}.
|
* Copy the contents of the given {@link ByteArrayOutputStream} into a {@link String}.
|
||||||
* <p>This is a more effective equivalent of {@code new String(baos.toByteArray(), charset)}.
|
* <p>This is a more effective equivalent of {@code new String(baos.toByteArray(), charset)}.
|
||||||
* <p>As long as the {@code charset} is already available at the point of
|
|
||||||
* invocation, no exception is expected to be thrown by this method.
|
|
||||||
* @param baos the {@code ByteArrayOutputStream} to be copied into a String
|
* @param baos the {@code ByteArrayOutputStream} to be copied into a String
|
||||||
* @param charset the {@link Charset} to use to decode the bytes
|
* @param charset the {@link Charset} to use to decode the bytes
|
||||||
* @return the String that has been copied to (possibly empty)
|
* @return the String that has been copied to (possibly empty)
|
||||||
|
@ -108,10 +106,12 @@ public abstract class StreamUtils {
|
||||||
Assert.notNull(baos, "No ByteArrayOutputStream specified");
|
Assert.notNull(baos, "No ByteArrayOutputStream specified");
|
||||||
Assert.notNull(charset, "No Charset specified");
|
Assert.notNull(charset, "No Charset specified");
|
||||||
try {
|
try {
|
||||||
|
// Can be replaced with toString(Charset) call in Java 10+
|
||||||
return baos.toString(charset.name());
|
return baos.toString(charset.name());
|
||||||
}
|
}
|
||||||
catch (UnsupportedEncodingException ex) {
|
catch (UnsupportedEncodingException ex) {
|
||||||
throw new RuntimeException("Failed to copy contents of ByteArrayOutputStream into a String", ex);
|
// Should never happen
|
||||||
|
throw new IllegalArgumentException("Invalid charset name: " + charset, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,6 +262,7 @@ public abstract class StreamUtils {
|
||||||
return new NonClosingOutputStream(out);
|
return new NonClosingOutputStream(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class NonClosingInputStream extends FilterInputStream {
|
private static class NonClosingInputStream extends FilterInputStream {
|
||||||
|
|
||||||
public NonClosingInputStream(InputStream in) {
|
public NonClosingInputStream(InputStream in) {
|
||||||
|
|
|
@ -56,14 +56,15 @@ import org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default {@link ServerRequest.Builder} implementation.
|
* Default {@link ServerRequest.Builder} implementation.
|
||||||
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @since 5.2
|
* @since 5.2
|
||||||
*/
|
*/
|
||||||
class DefaultServerRequestBuilder implements ServerRequest.Builder {
|
class DefaultServerRequestBuilder implements ServerRequest.Builder {
|
||||||
|
|
||||||
private final List<HttpMessageConverter<?>> messageConverters;
|
private final HttpServletRequest servletRequest;
|
||||||
|
|
||||||
private HttpServletRequest servletRequest;
|
private final List<HttpMessageConverter<?>> messageConverters;
|
||||||
|
|
||||||
private String methodName;
|
private String methodName;
|
||||||
|
|
||||||
|
@ -80,8 +81,8 @@ class DefaultServerRequestBuilder implements ServerRequest.Builder {
|
||||||
|
|
||||||
public DefaultServerRequestBuilder(ServerRequest other) {
|
public DefaultServerRequestBuilder(ServerRequest other) {
|
||||||
Assert.notNull(other, "ServerRequest must not be null");
|
Assert.notNull(other, "ServerRequest must not be null");
|
||||||
this.messageConverters = other.messageConverters();
|
|
||||||
this.servletRequest = other.servletRequest();
|
this.servletRequest = other.servletRequest();
|
||||||
|
this.messageConverters = other.messageConverters();
|
||||||
this.methodName = other.methodName();
|
this.methodName = other.methodName();
|
||||||
this.uri = other.uri();
|
this.uri = other.uri();
|
||||||
headers(headers -> headers.addAll(other.headers().asHttpHeaders()));
|
headers(headers -> headers.addAll(other.headers().asHttpHeaders()));
|
||||||
|
@ -157,10 +158,8 @@ class DefaultServerRequestBuilder implements ServerRequest.Builder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ServerRequest build() {
|
public ServerRequest build() {
|
||||||
|
return new BuiltServerRequest(this.servletRequest, this.methodName, this.uri,
|
||||||
return new BuiltServerRequest(this.servletRequest,
|
this.headers, this.cookies, this.attributes, this.body, this.messageConverters);
|
||||||
this.methodName, this.uri, this.headers, this.cookies, this.attributes, this.body,
|
|
||||||
this.messageConverters);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -174,7 +173,7 @@ class DefaultServerRequestBuilder implements ServerRequest.Builder {
|
||||||
|
|
||||||
private final HttpServletRequest servletRequest;
|
private final HttpServletRequest servletRequest;
|
||||||
|
|
||||||
private MultiValueMap<String, Cookie> cookies;
|
private final MultiValueMap<String, Cookie> cookies;
|
||||||
|
|
||||||
private final Map<String, Object> attributes;
|
private final Map<String, Object> attributes;
|
||||||
|
|
||||||
|
@ -186,6 +185,7 @@ class DefaultServerRequestBuilder implements ServerRequest.Builder {
|
||||||
HttpHeaders headers, MultiValueMap<String, Cookie> cookies,
|
HttpHeaders headers, MultiValueMap<String, Cookie> cookies,
|
||||||
Map<String, Object> attributes, byte[] body,
|
Map<String, Object> attributes, byte[] body,
|
||||||
List<HttpMessageConverter<?>> messageConverters) {
|
List<HttpMessageConverter<?>> messageConverters) {
|
||||||
|
|
||||||
this.servletRequest = servletRequest;
|
this.servletRequest = servletRequest;
|
||||||
this.methodName = methodName;
|
this.methodName = methodName;
|
||||||
this.uri = uri;
|
this.uri = uri;
|
||||||
|
@ -251,9 +251,7 @@ class DefaultServerRequestBuilder implements ServerRequest.Builder {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private <T> T bodyInternal(Type bodyType, Class<?> bodyClass)
|
private <T> T bodyInternal(Type bodyType, Class<?> bodyClass) throws ServletException, IOException {
|
||||||
throws ServletException, IOException {
|
|
||||||
|
|
||||||
HttpInputMessage inputMessage = new BuiltInputMessage();
|
HttpInputMessage inputMessage = new BuiltInputMessage();
|
||||||
MediaType contentType = headers().contentType().orElse(MediaType.APPLICATION_OCTET_STREAM);
|
MediaType contentType = headers().contentType().orElse(MediaType.APPLICATION_OCTET_STREAM);
|
||||||
|
|
||||||
|
@ -313,6 +311,7 @@ class DefaultServerRequestBuilder implements ServerRequest.Builder {
|
||||||
return this.servletRequest;
|
return this.servletRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private class BuiltInputMessage implements HttpInputMessage {
|
private class BuiltInputMessage implements HttpInputMessage {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2019 the original author or authors.
|
* Copyright 2002-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -54,6 +54,7 @@ import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default {@link ServerResponse.BodyBuilder} implementation.
|
* Default {@link ServerResponse.BodyBuilder} implementation.
|
||||||
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @since 5.2
|
* @since 5.2
|
||||||
*/
|
*/
|
||||||
|
@ -184,6 +185,7 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
|
||||||
@Override
|
@Override
|
||||||
public ServerResponse build(
|
public ServerResponse build(
|
||||||
BiFunction<HttpServletRequest, HttpServletResponse, ModelAndView> writeFunction) {
|
BiFunction<HttpServletRequest, HttpServletResponse, ModelAndView> writeFunction) {
|
||||||
|
|
||||||
return new WriterFunctionResponse(this.statusCode, this.headers, this.cookies, writeFunction);
|
return new WriterFunctionResponse(this.statusCode, this.headers, this.cookies, writeFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,7 +243,6 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
|
||||||
|
|
||||||
private final List<ErrorHandler<?>> errorHandlers = new ArrayList<>();
|
private final List<ErrorHandler<?>> errorHandlers = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
protected AbstractServerResponse(
|
protected AbstractServerResponse(
|
||||||
int statusCode, HttpHeaders headers, MultiValueMap<String, Cookie> cookies) {
|
int statusCode, HttpHeaders headers, MultiValueMap<String, Cookie> cookies) {
|
||||||
|
|
||||||
|
@ -322,8 +323,7 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
|
||||||
if (servletResponse.getCharacterEncoding() == null &&
|
if (servletResponse.getCharacterEncoding() == null &&
|
||||||
this.headers.getContentType() != null &&
|
this.headers.getContentType() != null &&
|
||||||
this.headers.getContentType().getCharset() != null) {
|
this.headers.getContentType().getCharset() != null) {
|
||||||
servletResponse
|
servletResponse.setCharacterEncoding(this.headers.getContentType().getCharset().name());
|
||||||
.setCharacterEncoding(this.headers.getContentType().getCharset().name());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,8 +334,8 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
protected abstract ModelAndView writeToInternal(HttpServletRequest request,
|
protected abstract ModelAndView writeToInternal(
|
||||||
HttpServletResponse response, Context context)
|
HttpServletRequest request, HttpServletResponse response, Context context)
|
||||||
throws ServletException, IOException;
|
throws ServletException, IOException;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -346,21 +346,20 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
|
||||||
.filter(errorHandler -> errorHandler.test(t))
|
.filter(errorHandler -> errorHandler.test(t))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.map(errorHandler -> {
|
.map(errorHandler -> {
|
||||||
ServerRequest serverRequest =
|
ServerRequest serverRequest = (ServerRequest)
|
||||||
(ServerRequest) servletRequest
|
servletRequest.getAttribute(RouterFunctions.REQUEST_ATTRIBUTE);
|
||||||
.getAttribute(RouterFunctions.REQUEST_ATTRIBUTE);
|
|
||||||
ServerResponse serverResponse = errorHandler.handle(t, serverRequest);
|
ServerResponse serverResponse = errorHandler.handle(t, serverRequest);
|
||||||
try {
|
try {
|
||||||
return serverResponse.writeTo(servletRequest, servletResponse, context);
|
return serverResponse.writeTo(servletRequest, servletResponse, context);
|
||||||
}
|
}
|
||||||
catch (ServletException ex) {
|
catch (ServletException ex) {
|
||||||
throw new RuntimeException(ex);
|
throw new IllegalStateException(ex);
|
||||||
}
|
}
|
||||||
catch (IOException ex) {
|
catch (IOException ex) {
|
||||||
throw new UncheckedIOException(ex);
|
throw new UncheckedIOException(ex);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.orElseThrow(() -> new RuntimeException(t));
|
.orElseThrow(() -> new IllegalStateException(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -373,6 +372,7 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
|
||||||
|
|
||||||
public ErrorHandler(Predicate<Throwable> predicate,
|
public ErrorHandler(Predicate<Throwable> predicate,
|
||||||
BiFunction<Throwable, ServerRequest, T> responseProvider) {
|
BiFunction<Throwable, ServerRequest, T> responseProvider) {
|
||||||
|
|
||||||
Assert.notNull(predicate, "Predicate must not be null");
|
Assert.notNull(predicate, "Predicate must not be null");
|
||||||
Assert.notNull(responseProvider, "ResponseProvider must not be null");
|
Assert.notNull(responseProvider, "ResponseProvider must not be null");
|
||||||
this.predicate = predicate;
|
this.predicate = predicate;
|
||||||
|
@ -387,8 +387,6 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
|
||||||
return this.responseProvider.apply(t, serverRequest);
|
return this.responseProvider.apply(t, serverRequest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -396,24 +394,21 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
|
||||||
|
|
||||||
private final BiFunction<HttpServletRequest, HttpServletResponse, ModelAndView> writeFunction;
|
private final BiFunction<HttpServletRequest, HttpServletResponse, ModelAndView> writeFunction;
|
||||||
|
|
||||||
|
public WriterFunctionResponse(
|
||||||
public WriterFunctionResponse(int statusCode, HttpHeaders headers,
|
int statusCode, HttpHeaders headers, MultiValueMap<String, Cookie> cookies,
|
||||||
MultiValueMap<String, Cookie> cookies,
|
|
||||||
BiFunction<HttpServletRequest, HttpServletResponse, ModelAndView> writeFunction) {
|
BiFunction<HttpServletRequest, HttpServletResponse, ModelAndView> writeFunction) {
|
||||||
|
|
||||||
super(statusCode, headers, cookies);
|
super(statusCode, headers, cookies);
|
||||||
Assert.notNull(writeFunction, "WriteFunction must not be null");
|
Assert.notNull(writeFunction, "WriteFunction must not be null");
|
||||||
this.writeFunction = writeFunction;
|
this.writeFunction = writeFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ModelAndView writeToInternal(HttpServletRequest request,
|
protected ModelAndView writeToInternal(
|
||||||
HttpServletResponse response, Context context) {
|
HttpServletRequest request, HttpServletResponse response, Context context) {
|
||||||
|
|
||||||
return this.writeFunction.apply(request, response);
|
return this.writeFunction.apply(request, response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue