This is an automated email from the ASF dual-hosted git repository.
jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/master by this push:
new b117d47 REST refactoring.
b117d47 is described below
commit b117d47ffb4ce59c5f2706cd7a3474c701c53ed2
Author: JamesBognar <[email protected]>
AuthorDate: Sat Feb 20 12:15:12 2021 -0500
REST refactoring.
---
.../java/org/apache/juneau/rest/RestResponse.java | 206 +++++++++++++++++++--
.../juneau/rest/logging/BasicRestLogger.java | 2 -
2 files changed, 192 insertions(+), 16 deletions(-)
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResponse.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResponse.java
index fc66df3..72ca20d 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResponse.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResponse.java
@@ -58,7 +58,7 @@ import org.apache.juneau.serializer.*;
* <li class='link'>{@doc RestmRestResponse}
* </ul>
*/
-public final class RestResponse extends HttpServletResponseWrapper {
+public final class RestResponse {
private HttpServletResponse inner;
private final RestRequest request;
@@ -73,7 +73,6 @@ public final class RestResponse extends
HttpServletResponseWrapper {
* Constructor.
*/
RestResponse(RestCall call) throws Exception {
- super(call.getResponse());
inner = call.getResponse();
request = call.getRestRequest();
@@ -247,6 +246,25 @@ public final class RestResponse extends
HttpServletResponseWrapper {
}
/**
+ * Sets the content type of the response being sent to the client, if
the response has not been committed yet.
+ *
+ * <p>
+ * The given content type may include a character encoding
specification, for example, text/html;charset=UTF-8.
+ * The response's character encoding is only set from the given content
type if this method is called before getWriter is called.
+ *
+ * <p>This method may be called repeatedly to change content type and
character encoding.
+ * This method has no effect if called after the response has been
committed.
+ * It does not set the response's character encoding if it is called
after getWriter has been called or after the response has been committed.
+ *
+ * @param value A string specifying the MIME type of the content.
+ * @return This object (for method chaining).
+ */
+ public RestResponse setContentType(String value) {
+ inner.setContentType(value);
+ return this;
+ }
+
+ /**
* Equivalent to {@link HttpServletResponse#getOutputStream()}, except
wraps the output stream if an {@link Encoder}
* was found that matched the <c>Accept-Encoding</c> header.
*
@@ -286,7 +304,19 @@ public final class RestResponse extends
HttpServletResponseWrapper {
return os;
}
- @Override /* ServletResponse */
+ /**
+ * Returns a ServletOutputStream suitable for writing binary data in
the response.
+ *
+ * <p>
+ * The servlet container does not encode the binary data.
+ *
+ * <p>
+ * Calling <c>flush()</c> on the ServletOutputStream commits the
response.
+ * Either this method or <c>getWriter</c> may be called to write the
body, not both, except when reset has been called.
+ *
+ * @return The stream.
+ * @throws IOException If stream could not be accessed.
+ */
public ServletOutputStream getOutputStream() throws IOException {
if (sos == null)
sos = inner.getOutputStream();
@@ -308,8 +338,10 @@ public final class RestResponse extends
HttpServletResponseWrapper {
* <p>
* This methods bypasses any specified encoders and returns a regular
unbuffered writer.
* Use the {@link #getNegotiatedWriter()} method if you want to use the
matched encoder (if any).
+ *
+ * @return The writer.
+ * @throws IOException If writer could not be accessed.
*/
- @Override /* ServletResponse */
public PrintWriter getWriter() throws IOException {
return getWriter(true, false);
}
@@ -369,6 +401,43 @@ public final class RestResponse extends
HttpServletResponseWrapper {
}
/**
+ * Sets the character encoding (MIME charset) of the response being
sent to the client, for example, to UTF-8.
+ *
+ * <p>
+ * If the character encoding has already been set by
<c>setContentType</c> or <c>setLocale</c>, this method overrides it.
+ * Calling {@link #setContentType(String)} with the String of
<js>"text/html"</js> and calling this method with
+ * <js>"UTF-8"</js> is equivalent with calling {@link
#setContentType(String)} with <js>"text/html; charset=UTF-8"</js>.
+ *
+ * <p>
+ * This method can be called repeatedly to change the character
encoding.
+ * This method has no effect if it is called after <c>getWriter</c> has
been called or after the response has been committed.
+ *
+ * @param value The character encoding value.
+ * @return This object (for method chaining).
+ */
+ public RestResponse setCharacterEncoding(String value) {
+ inner.setCharacterEncoding(value);
+ return this;
+ }
+
+ /**
+ * Returns the name of the character encoding (MIME charset) used for
the body sent in this response.
+ *
+ * <p>
+ * The character encoding may have been specified explicitly using the
<c>setCharacterEncoding</c> or <c>setContentType</c> methods,
+ * or implicitly using the <c>setLocale</c> method.
+ * Explicit specifications take precedence over implicit specifications.
+ * Calls made to these methods after <c>getWriter</c> has been called
or after the response has been committed have
+ * no effect on the character encoding.
+ * If no character encoding has been specified, <js>"ISO-8859-1"</js>
is returned.
+ *
+ * @return A string specifying the name of the character encoding, for
example, <js>"UTF-8"</js>.
+ */
+ public String getCharacterEncoding() {
+ return inner.getCharacterEncoding();
+ }
+
+ /**
* Returns the <c>Content-Type</c> header stripped of the charset
attribute if present.
*
* @return The <c>media-type</c> portion of the <c>Content-Type</c>
header.
@@ -378,6 +447,24 @@ public final class RestResponse extends
HttpServletResponseWrapper {
}
/**
+ * Returns the content type used for the MIME body sent in this
response.
+ *
+ *
+ * <p>
+ * The content type proper must have been specified using
<c>setContentType</c> before the response is committed.
+ * If no content type has been specified, this method returns
<jk>null</jk>.
+ * If a content type has been specified, and a character encoding has
been explicitly or implicitly specified as
+ * described in <c>getCharacterEncoding</c> or <c>getWriter</c> has
been called, the charset parameter is included
+ * in the string returned.
+ * If no character encoding has been specified, the charset parameter
is omitted.
+ *
+ * @return A string specifying the content type, for example,
<js>"text/html; charset=UTF-8"</js>, or <jk>null</jk>.
+ */
+ public String getContentType() {
+ return inner.getContentType();
+ }
+
+ /**
* Wrapper around {@link #getCharacterEncoding()} that converts the
value to a {@link Charset}.
*
* @return The request character encoding converted to a {@link
Charset}.
@@ -393,31 +480,54 @@ public final class RestResponse extends
HttpServletResponseWrapper {
* <p>
* Relative URIs are always interpreted as relative to the context root.
* This is similar to how WAS handles redirect requests, and is
different from how Tomcat handles redirect requests.
+ *
+ * @param uri The redirection URL.
+ * @throws IOException If an input or output exception occurs
*/
- @Override /* ServletResponse */
public void sendRedirect(String uri) throws IOException {
char c = (uri.length() > 0 ? uri.charAt(0) : 0);
if (c != '/' && uri.indexOf("://") == -1)
uri = request.getContextPath() + '/' + uri;
- super.sendRedirect(uri);
+ inner.sendRedirect(uri);
}
- @Override /* ServletResponse */
+ /**
+ * Sets a response header with the given name and value.
+ *
+ * <p>
+ * If the header had already been set, the new value overwrites the
previous one.
+ *
+ * <p>
+ * The {@link #containsHeader(String)} method can be used to test for
the presence of a header before setting its value.
+ *
+ * @param name The header name.
+ * @param value The header value.
+ */
public void setHeader(String name, String value) {
// Jetty doesn't set the content type correctly if set through
this method.
// Tomcat/WAS does.
if (name.equalsIgnoreCase("Content-Type")) {
- super.setContentType(value);
+ inner.setContentType(value);
ContentType ct = ContentType.of(value);
if (ct != null && ct.getParameter("charset") != null)
-
super.setCharacterEncoding(ct.getParameter("charset"));
+
inner.setCharacterEncoding(ct.getParameter("charset"));
} else {
- super.setHeader(name, value);
+ inner.setHeader(name, value);
}
}
/**
+ * Returns a boolean indicating whether the named response header has
already been set.
+ *
+ * @param name The header name.
+ * @return <jk>true</jk> if the response header has been set.
+ */
+ public boolean containsHeader(String name) {
+ return inner.containsHeader(name);
+ }
+
+ /**
* Same as {@link #setHeader(String, String)} but strips invalid
characters from the value if present.
*
* These include CTRL characters, newlines, and non-ISO8859-1
characters.
@@ -446,9 +556,9 @@ public final class RestResponse extends
HttpServletResponseWrapper {
// Jetty doesn't set the content type correctly if set through
this method.
// Tomcat/WAS does.
if (name.equalsIgnoreCase("Content-Type"))
- super.setContentType(value);
+ inner.setContentType(value);
else
- super.setHeader(name,
abbreviate(stripInvalidHttpHeaderChars(value), maxLength));
+ inner.setHeader(name,
abbreviate(stripInvalidHttpHeaderChars(value), maxLength));
}
/**
@@ -652,16 +762,84 @@ public final class RestResponse extends
HttpServletResponseWrapper {
return inner;
}
- @Override /* ServletResponse */
+ /**
+ * Forces any content in the buffer to be written to the client.
+ *
+ * <p>
+ * A call to this method automatically commits the response, meaning
the status code and headers will be written.
+ *
+ * @throws IOException If an I/O error occurred.
+ */
public void flushBuffer() throws IOException {
if (w != null)
w.flush();
if (os != null)
os.flush();
- super.flushBuffer();
+ inner.flushBuffer();
}
private Object getRawOutput() {
return output.isPresent() ? output.get().orElse(null) : null;
}
+
+ /**
+ * Returns the current status code of this response.
+ *
+ * @return The current status code of this response.
+ */
+ public int getStatus() {
+ return inner.getStatus();
+ }
+
+ /**
+ * Sets the status code for this response.
+ *
+ * <p>
+ * This method is used to set the return status code when there is no
error (for example, for the SC_OK or SC_MOVED_TEMPORARILY status codes).
+ *
+ * <p>
+ * If this method is used to set an error code, then the container's
error page mechanism will not be triggered.
+ * If there is an error and the caller wishes to invoke an error page
defined in the web application, then sendError must be used instead.
+ *
+ * <p>
+ * This method preserves any cookies and other response headers.
+ *
+ * <p>
+ * Valid status codes are those in the 2XX, 3XX, 4XX, and 5XX ranges.
Other status codes are treated as container specific.
+ *
+ * @param value The status code for this response.
+ * @return This object (for method chaining).
+ */
+ public RestResponse setStatus(int value) {
+ inner.setStatus(value);
+ return this;
+ }
+
+ /**
+ * Adds a response header with the given name and value.
+ *
+ * <p>
+ * This method allows response headers to have multiple values.
+ *
+ * @param name The header name.
+ * @param value The header value.
+ * @return This object (for method chaining).
+ */
+ public RestResponse addHeader(String name, String value) {
+ inner.addHeader(name, value);
+ return this;
+ }
+
+ /**
+ * Gets the value of the response header with the given name.
+ *
+ * <p>
+ * If a response header with the given name exists and contains
multiple values, the value that was added first will be returned.
+ *
+ * @param name The header name.
+ * @return The header value, or <jk>null</jk> if it wasn't set.
+ */
+ public String getHeader(String name) {
+ return inner.getHeader(name);
+ }
}
\ No newline at end of file
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logging/BasicRestLogger.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logging/BasicRestLogger.java
index 2af886a..64b49d9 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logging/BasicRestLogger.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logging/BasicRestLogger.java
@@ -341,8 +341,6 @@ public class BasicRestLogger implements RestLogger {
}
private byte[] getResponseBody(HttpServletRequest req,
HttpServletResponse res) {
- if (res instanceof RestResponse)
- res = ((RestResponse)res).getHttpServletResponse();
if (res instanceof CachingHttpServletResponse)
return ((CachingHttpServletResponse)res).getBody();
return castOrNull(req.getAttribute("ResponseBody"),
byte[].class);