Allow built ServerResponse to throw exception

This commit ensures that ServerResponse.HeadersBuilder::build can throw
an exception, by introducing a separate functional interface that does
allow for exceptions to be thrown.

Closes gh-30818
This commit is contained in:
Arjen Poutsma 2023-07-05 12:01:55 +02:00
parent 7c37f4bc51
commit 496155525c
3 changed files with 32 additions and 16 deletions

View File

@ -136,6 +136,6 @@ abstract class AbstractServerResponse extends ErrorHandlingServerResponse {
@Nullable
protected abstract ModelAndView writeToInternal(
HttpServletRequest request, HttpServletResponse response, Context context)
throws ServletException, IOException;
throws Exception;
}

View File

@ -23,7 +23,6 @@ import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import jakarta.servlet.http.Cookie;
@ -174,10 +173,8 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
}
@Override
public ServerResponse build(
BiFunction<HttpServletRequest, HttpServletResponse, ModelAndView> writeFunction) {
return new WriterFunctionResponse(this.statusCode, this.headers, this.cookies, writeFunction);
public ServerResponse build(WriteFunction writeFunction) {
return new WriteFunctionResponse(this.statusCode, this.headers, this.cookies, writeFunction);
}
@Override
@ -219,12 +216,12 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
}
private static class WriterFunctionResponse extends AbstractServerResponse {
private static class WriteFunctionResponse extends AbstractServerResponse {
private final BiFunction<HttpServletRequest, HttpServletResponse, ModelAndView> writeFunction;
private final WriteFunction writeFunction;
public WriterFunctionResponse(HttpStatusCode statusCode, HttpHeaders headers, MultiValueMap<String, Cookie> cookies,
BiFunction<HttpServletRequest, HttpServletResponse, ModelAndView> writeFunction) {
public WriteFunctionResponse(HttpStatusCode statusCode, HttpHeaders headers, MultiValueMap<String, Cookie> cookies,
WriteFunction writeFunction) {
super(statusCode, headers, cookies);
Assert.notNull(writeFunction, "WriteFunction must not be null");
@ -232,10 +229,10 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
}
@Override
protected ModelAndView writeToInternal(
HttpServletRequest request, HttpServletResponse response, Context context) {
protected ModelAndView writeToInternal(HttpServletRequest request, HttpServletResponse response,
Context context) throws Exception {
return this.writeFunction.apply(request, response);
return this.writeFunction.write(request, response);
}
}

View File

@ -27,7 +27,6 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import jakarta.servlet.ServletException;
@ -457,8 +456,28 @@ public interface ServerResponse {
* Build the response entity with a custom write function.
* @param writeFunction the function used to write to the {@link HttpServletResponse}
*/
ServerResponse build(BiFunction<HttpServletRequest, HttpServletResponse,
ModelAndView> writeFunction);
ServerResponse build(WriteFunction writeFunction);
/**
* Defines the contract for {@link #build(WriteFunction)}.
* @since 6.1
*/
@FunctionalInterface
interface WriteFunction {
/**
* Write to the given {@code servletResponse}, or return a
* {@code ModelAndView} to be rendered.
* @param servletRequest the HTTP request
* @param servletResponse the HTTP response to write to
* @return a {@code ModelAndView} to render, or {@code null} if handled directly
* @throws Exception in case of Servlet errors
*/
@Nullable
ModelAndView write(HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws Exception;
}
}