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 ac088b2  REST refactoring.
ac088b2 is described below

commit ac088b2205fa2960b04bc2b36d37730463749c0f
Author: JamesBognar <[email protected]>
AuthorDate: Wed Mar 10 13:34:16 2021 -0500

    REST refactoring.
---
 .../juneau/http/header/SerializedHeader.java       | 50 +++++++++++++-----
 .../apache/juneau/http/resource/BasicResource.java |  4 +-
 .../apache/juneau/http/resource/HttpResource.java  |  9 ++--
 .../juneau/http/response/BasicHttpException.java   | 16 +-----
 .../juneau/http/response/BasicHttpResponse.java    | 16 +-----
 .../org/apache/juneau/rest/client/RestClient.java  |  7 +--
 .../org/apache/juneau/rest/client/RestRequest.java |  4 +-
 .../main/java/org/apache/juneau/rest/RestCall.java | 61 ++++++++++++++++++++++
 .../java/org/apache/juneau/rest/RestContext.java   |  7 +--
 .../org/apache/juneau/rest/RestContextBuilder.java |  1 +
 .../apache/juneau/rest/RestOperationContext.java   | 10 ++--
 .../juneau/rest/processors/DefaultProcessor.java   |  7 ++-
 .../rest/processors/HttpEntityProcessor.java       |  7 ++-
 .../rest/processors/HttpResourceProcessor.java     | 20 ++++---
 .../rest/processors/HttpResponseProcessor.java     | 25 ++++++++-
 ...ponseProcessor.java => ThrowableProcessor.java} | 15 ++++--
 .../apache/juneau/http/BasicHttpResource_Test.java | 10 ++--
 .../apache/juneau/http/SerializedHeader_Test.java  |  4 +-
 18 files changed, 182 insertions(+), 91 deletions(-)

diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/header/SerializedHeader.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/header/SerializedHeader.java
index 2757434..8e7b9f3 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/header/SerializedHeader.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/header/SerializedHeader.java
@@ -132,14 +132,15 @@ public class SerializedHeader extends BasicHeader {
        }
 
        /**
-        * Sets the serializer to use for serializing the value to a string 
value if it's not already set on this object.
-        *
-        * @param value The new value for this property.
-        * @return This object (for method chaining).
+        * Copies this bean and sets the serializer on it.
+        * 
+        * @param value The new serializer for the bean.  Can be <jk>null</jk>.
+        * @return Either a new bean with the serializer set, or this bean if
+        *      the value is <jk>null</jk> or the serializer was already set.
         */
-       public SerializedHeader serializerIfNotSet(HttpPartSerializerSession 
value) {
-               if (serializer == null)
-                       serializer = value;
+       public SerializedHeader copyWithSerializer(HttpPartSerializerSession 
value) {
+               if (serializer == null && value != null)
+                       return copy().serializer(value);
                return this;
        }
 
@@ -155,14 +156,35 @@ public class SerializedHeader extends BasicHeader {
        }
 
        /**
-        * Sets the schema object that defines the format of the output if it's 
not already set on this object.
-        *
-        * @param value The new value for this property.
-        * @return This object (for method chaining).
+        * Copies this bean and sets the schema on it.
+        * 
+        * @param value The new schema for the bean.  Can be <jk>null</jk>.
+        * @return Either a new bean with the schema set, or this bean if
+        *      the value is <jk>null</jk> or the schema was already set.
         */
-       public SerializedHeader schemaIfNotSet(HttpPartSchema value) {
-               if (schema == null)
-                       schema = value;
+       public SerializedHeader copyWithSchema(HttpPartSchema value) {
+               if (schema == null && value != null)
+                       return copy().schema(value);
+               return this;
+       }
+
+       /**
+        * Copies this bean and sets the serializer and schema on it.
+        * 
+        * @param serializer The new serializer for the bean.  Can be 
<jk>null</jk>.
+        * @param schema The new schema for the bean.  Can be <jk>null</jk>.
+        * @return Either a new bean with the serializer set, or this bean if
+        *      both values are <jk>null</jk> or the serializer and schema were 
already set.
+        */
+       public SerializedHeader 
copyWithSerializerAndSchema(HttpPartSerializerSession serializer, 
HttpPartSchema schema) {
+               if ((this.serializer == null && serializer != null) || 
(this.schema == null && schema != null)) {
+                       SerializedHeader h = copy();
+                       if (serializer != null)
+                               h.serializer(serializer);
+                       if (schema != null)
+                               h.schema(schema);
+                       return h;
+               }
                return this;
        }
 
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/resource/BasicResource.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/resource/BasicResource.java
index 53d868e..42ca240 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/resource/BasicResource.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/resource/BasicResource.java
@@ -36,7 +36,7 @@ import org.apache.juneau.http.header.*;
  *             Externally-supplied/dynamic content.
  * </ul>
  */
-@BeanIgnore
+@BeanIgnore  /* Use toString() to serialize */
 public class BasicResource implements HttpResource {
 
        final BasicHttpEntity entity;
@@ -248,7 +248,7 @@ public class BasicResource implements HttpResource {
        }
 
        @Override /* HttpResource */
-       public List<Header> getHeaders() {
+       public List<Header> getAllHeaders() {
                return headers.getAll();
        }
 }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/resource/HttpResource.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/resource/HttpResource.java
index b0b2d39..2d6ab44 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/resource/HttpResource.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/resource/HttpResource.java
@@ -16,7 +16,6 @@ import java.util.*;
 
 import org.apache.http.*;
 import org.apache.http.Header;
-import org.apache.juneau.http.annotation.*;
 
 /**
  * An extension of an {@link HttpEntity} that also includes arbitrary headers.
@@ -37,18 +36,16 @@ import org.apache.juneau.http.annotation.*;
  *             .build();
  * </p>
  */
-@Response
 public interface HttpResource extends HttpEntity {
 
        /**
         * Returns the list of headers associated with this resource.
-        * 
+        *
         * <p>
         * Note that this typically does NOT include headers associated with 
{@link HttpEntity}
         * (e.g. <c>Content-Type</c>, <c>Content-Encoding</c>, and 
<c>Content-Length</c>).
-        * 
+        *
         * @return The list of headers associated with this resource.
         */
-       @ResponseHeader("*")
-       List<Header> getHeaders();
+       List<Header> getAllHeaders();
 }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/BasicHttpException.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/BasicHttpException.java
index 9155db0..9db0503 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/BasicHttpException.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/BasicHttpException.java
@@ -26,7 +26,6 @@ import org.apache.http.params.*;
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.http.*;
-import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.http.header.*;
 
 /**
@@ -42,8 +41,7 @@ import org.apache.juneau.http.header.*;
  * <p>
  * Beans are not thread safe unless they're marked as unmodifiable.
  */
-@Response
-@BeanIgnore
+@BeanIgnore /* Use toString() to serialize */
 public class BasicHttpException extends BasicRuntimeException implements 
HttpResponse {
 
        private static final long serialVersionUID = 1L;
@@ -163,16 +161,6 @@ public class BasicHttpException extends 
BasicRuntimeException implements HttpRes
        }
 
        /**
-        * Returns the HTTP status code of this response.
-        *
-        * @return The HTTP status code of this response.
-        */
-       @ResponseStatus
-       public int getStatusCode() {
-               return statusLine().getStatusCode();
-       }
-
-       /**
         * Asserts that the specified HTTP response has the same status code as 
the one on the status line of this bean.
         *
         * @param response The HTTP response to check.  Must not be 
<jk>null</jk>.
@@ -273,7 +261,6 @@ public class BasicHttpException extends 
BasicRuntimeException implements HttpRes
        }
 
        @Override /* HttpMessage */
-       @ResponseHeader("*")
        public Header[] getAllHeaders() {
                List<Header> l = headers().getAll();
                return l.isEmpty() ? EMPTY_HEADERS : l.toArray(new 
Header[l.size()]);
@@ -365,7 +352,6 @@ public class BasicHttpException extends 
BasicRuntimeException implements HttpRes
                statusLineBuilder().reasonPhrase(reason).build();
        }
 
-       @ResponseBody
        @Override /* HttpMessage */
        public HttpEntity getEntity() {
                // Constructing a StringEntity is somewhat expensive, so don't 
create it unless it's needed.
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/BasicHttpResponse.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/BasicHttpResponse.java
index 984b6cc..71d427f 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/BasicHttpResponse.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/BasicHttpResponse.java
@@ -22,7 +22,6 @@ import org.apache.http.Header;
 import org.apache.http.params.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.http.*;
-import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.http.header.*;
 
 /**
@@ -38,8 +37,7 @@ import org.apache.juneau.http.header.*;
  * <p>
  * Beans are not thread safe unless they're marked as unmodifiable.
  */
-@Response
-@BeanIgnore
+@BeanIgnore /* Use toString() to serialize */
 public class BasicHttpResponse implements HttpResponse {
 
        private static final Header[] EMPTY_HEADERS = new Header[0];
@@ -95,16 +93,6 @@ public class BasicHttpResponse implements HttpResponse {
        }
 
        /**
-        * Returns the HTTP status code of this response.
-        *
-        * @return The HTTP status code of this response.
-        */
-       @ResponseStatus
-       public int getStatusCode() {
-               return statusLine().getStatusCode();
-       }
-
-       /**
         * Asserts that the specified HTTP response has the same status code as 
the one on the status line of this bean.
         *
         * @param response The HTTP response to check.  Must not be 
<jk>null</jk>.
@@ -152,7 +140,6 @@ public class BasicHttpResponse implements HttpResponse {
        }
 
        @Override /* HttpMessage */
-       @ResponseHeader("*")
        public Header[] getAllHeaders() {
                List<Header> l = headers().getAll();
                return l.isEmpty() ? EMPTY_HEADERS : l.toArray(new 
Header[l.size()]);
@@ -244,7 +231,6 @@ public class BasicHttpResponse implements HttpResponse {
                statusLineBuilder().reasonPhrase(reason).build();
        }
 
-       @ResponseBody
        @Override /* HttpMessage */
        public HttpEntity getEntity() {
                // Constructing a StringEntity is somewhat expensive, so don't 
create it unless it's needed.
diff --git 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
index 352ebad..70d8149 100644
--- 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
+++ 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
@@ -2125,7 +2125,7 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
 
        private static Object buildBuilders(Object o, HttpPartSerializerSession 
ss) {
                if (o instanceof SerializedHeader)
-                       return 
((SerializedHeader)o).copy().serializerIfNotSet(ss);
+                       return ((SerializedHeader)o).copyWithSerializer(ss);
                if (o instanceof SerializedPart)
                        return 
((SerializedPart)o).copy().serializerIfNotSet(ss);
                return o;
@@ -2532,8 +2532,9 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
                        if (body instanceof PartList)
                                return req.body(new 
UrlEncodedFormEntity((PartList)body));
                        if (body instanceof HttpResource) {
-                               for (Header h : 
((HttpResource)body).getHeaders())
-                                       req.header(h);
+                               List<Header> headers = 
((HttpResource)body).getAllHeaders();
+                               for (int i = 0; i < headers.size(); i++)  // 
Avoids iterator creation.
+                                       req.header(headers.get(i));
                        }
                        if (body instanceof HttpEntity) {
                                HttpEntity e = (HttpEntity)body;
diff --git 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequest.java
 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequest.java
index 127bdfd..86a2ce3 100644
--- 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequest.java
+++ 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequest.java
@@ -2899,7 +2899,9 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
                                        entity = new 
UrlEncodedFormEntity((PartList)input2);
                                else if (input2 instanceof HttpResource) {
                                        HttpResource r = (HttpResource)input2;
-                                       headers(r.getHeaders());
+                                       List<Header> headers = 
r.getAllHeaders();
+                                       for (int i = 0; i < headers.size(); 
i++)  // Avoids iterator creation.
+                                               addHeader(headers.get(i));
                                        entity = (HttpEntity)input2;
                                }
                                else if (input2 instanceof HttpEntity)
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestCall.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestCall.java
index b7c2698..3761179 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestCall.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestCall.java
@@ -20,7 +20,9 @@ import java.util.*;
 
 import javax.servlet.http.*;
 
+import org.apache.http.*;
 import org.apache.juneau.cp.*;
+import org.apache.juneau.http.header.*;
 import org.apache.juneau.http.response.*;
 import org.apache.juneau.httppart.bean.*;
 import org.apache.juneau.reflect.*;
@@ -193,6 +195,65 @@ public class RestCall {
        }
 
        /**
+        * Sets the HTTP status on this call.
+        *
+        * @param value The status code.
+        * @return This object (for method chaining).
+        */
+       @SuppressWarnings("deprecation")
+       public RestCall status(StatusLine value) {
+               if (value != null)
+                       res.setStatus(value.getStatusCode(), 
value.getReasonPhrase());
+               return this;
+       }
+
+       /**
+        * Adds a header to the response.
+        *
+        * <p>
+        * If the header is a {@link BasicUriHeader}, the URI will be resolved 
using the {@link RestRequest#getUriResolver()} object.
+        *
+        * <p>
+        * If the header is a {@link SerializedHeader} and the serializer 
session is not set, it will be set to the one returned by {@link 
RestRequest#getPartSerializerSession()} before serialization.
+        *
+        * @param h The header to add.  Can be <jk>null</jk>.
+        * @return This object (for method chaining).
+        */
+       public RestCall addResponseHeader(Header h) {
+
+               if (h == null)
+                       return this;
+
+               if (h instanceof BasicUriHeader) {
+                       BasicUriHeader x = (BasicUriHeader)h;
+                       addResponseHeader(x.getName(), 
rreq.getUriResolver().resolve(x.getValue()));
+               } else if (h instanceof SerializedHeader) {
+                       SerializedHeader x = 
((SerializedHeader)h).copyWithSerializer(rreq.getPartSerializerSession());
+                       addResponseHeader(x.getName(), 
rreq.getUriResolver().resolve(x.getValue()));
+               } else {
+                       addResponseHeader(h.getName(), h.getValue());
+               }
+
+               return this;
+       }
+
+       /**
+        * Adds a header to the response.
+        *
+        * <p>
+        * A no-op of either the name or value is <jk>null</jk>.
+        *
+        * @param name The header name.
+        * @param value The header value.
+        * @return This object (for method chaining).
+        */
+       public RestCall addResponseHeader(String name, String value) {
+               if (name != null && value != null)
+                       res.addHeader(name, value);
+               return this;
+       }
+
+       /**
         * Identifies that an exception occurred during this call.
         *
         * @param value The thrown exception.
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
index fae65ff..c45fbb1 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
@@ -6910,7 +6910,8 @@ public class RestContext extends BeanContext {
                try {
                        res.setContentType("text/plain");
                        res.setHeader("Content-Encoding", "identity");
-                       res.setStatus(e2.getStatusCode());
+                       int statusCode = e2.getStatusLine().getStatusCode();
+                       res.setStatus(statusCode);
 
                        PrintWriter w = null;
                        try {
@@ -6920,9 +6921,9 @@ public class RestContext extends BeanContext {
                        }
 
                        try (PrintWriter w2 = w) {
-                               String httpMessage = 
RestUtils.getHttpResponseText(e2.getStatusCode());
+                               String httpMessage = 
RestUtils.getHttpResponseText(statusCode);
                                if (httpMessage != null)
-                                       w2.append("HTTP 
").append(String.valueOf(e2.getStatusCode())).append(": 
").append(httpMessage).append("\n\n");
+                                       w2.append("HTTP 
").append(String.valueOf(statusCode)).append(": 
").append(httpMessage).append("\n\n");
                                if (isRenderResponseStackTraces())
                                        e.printStackTrace(w2);
                                else
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
index 5d4b7c3..1f13dba 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
@@ -128,6 +128,7 @@ public class RestContextBuilder extends BeanContextBuilder 
implements ServletCon
                        responseProcessors(
                                ReaderProcessor.class,
                                InputStreamProcessor.class,
+                               ThrowableProcessor.class,
                                HttpResponseProcessor.class,
                                HttpResourceProcessor.class,
                                HttpEntityProcessor.class,
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOperationContext.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOperationContext.java
index c6a3123..cdb1f10 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOperationContext.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOperationContext.java
@@ -1886,13 +1886,11 @@ public class RestOperationContext extends BeanContext 
implements Comparable<Rest
                                                res.setOutput(output);
                                }
                        } catch (ExecutableException e) {
-                               Throwable e2 = e.unwrap();              // Get 
the throwable thrown from the doX() method.
-                               res.setStatus(500);
-                               ResponsePartMeta rpm = getResponseBodyMeta(e2);
-                               ResponseBeanMeta rbm = getResponseBeanMeta(e2);
-                               if (rpm != null || rbm != null) {
+                               Throwable e2 = e.unwrap();  // Get the 
throwable thrown from the doX() method.
+                               res.setStatus(500);  // May be overridden later.
+                               Class<?> c = e2.getClass();
+                               if (e2 instanceof HttpResponse || 
c.getAnnotation(Response.class) != null || c.getAnnotation(ResponseBody.class) 
!= null) {
                                        res.setOutput(e2);
-                                       res.setResponseMeta(rbm);
                                } else {
                                        throw e;
                                }
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processors/DefaultProcessor.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processors/DefaultProcessor.java
index 727a329..45cc06d 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processors/DefaultProcessor.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processors/DefaultProcessor.java
@@ -105,8 +105,8 @@ public class DefaultProcessor implements ResponseProcessor {
                                                                Object v = 
x.getValue();
                                                                
res.setHeader(new HttpPart(k, RESPONSE_HEADER, partSchema.getProperty(k), 
hm.getSerializerSession().orElse(ps), v));
                                                        } else if (ho2 
instanceof SerializedHeader) {
-                                                               
SerializedHeader x = ((SerializedHeader)ho2).copy().serializerIfNotSet(ps);
-                                                               
x.schemaIfNotSet(partSchema.getProperty(x.getName()));
+                                                               
SerializedHeader x = ((SerializedHeader)ho2);
+                                                               x = 
x.copyWithSerializerAndSchema(ps, partSchema.getProperty(x.getName()));
                                                                
res.setHeader(x.getName(), x.getValue());
                                                        } else if (ho2 
instanceof SerializedPart) {
                                                                SerializedPart 
x = ((SerializedPart)ho2).copy().serializerIfNotSet(ps);
@@ -127,8 +127,7 @@ public class DefaultProcessor implements ResponseProcessor {
                                                }
                                        } else {
                                                if (ho instanceof 
SerializedHeader) {
-                                                       SerializedHeader x = 
((SerializedHeader)ho).copy().serializerIfNotSet(ps);
-                                                       
x.schemaIfNotSet(schema);
+                                                       SerializedHeader x = 
((SerializedHeader)ho).copyWithSerializerAndSchema(ps, schema);
                                                        
res.setHeader(x.getName(), x.getValue());
                                                } else if (ho instanceof 
SerializedPart) {
                                                        SerializedPart x = 
((SerializedPart)ho).copy().serializerIfNotSet(ps);
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processors/HttpEntityProcessor.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processors/HttpEntityProcessor.java
index 3089494..7ab555a 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processors/HttpEntityProcessor.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processors/HttpEntityProcessor.java
@@ -33,14 +33,17 @@ public final class HttpEntityProcessor implements 
ResponseProcessor {
                RestResponse res = call.getRestResponse();
                HttpEntity e = res.getOutput(HttpEntity.class);
 
-               res.header(e.getContentType()).header(e.getContentEncoding());
+               call.addResponseHeader(e.getContentType());
+               call.addResponseHeader(e.getContentEncoding());
                long contentLength = e.getContentLength();
                if (contentLength >= 0)
-                       res.header(contentLength(contentLength));
+                       call.addResponseHeader(contentLength(contentLength));
+
                try (OutputStream os = res.getNegotiatedOutputStream()) {
                        e.writeTo(os);
                        os.flush();
                }
+
                return 1;
        }
 }
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processors/HttpResourceProcessor.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processors/HttpResourceProcessor.java
index a829e98..9ddffef 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processors/HttpResourceProcessor.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processors/HttpResourceProcessor.java
@@ -15,6 +15,7 @@ package org.apache.juneau.rest.processors;
 import static org.apache.juneau.http.HttpHeaders.*;
 
 import java.io.*;
+import java.util.*;
 
 import org.apache.juneau.rest.*;
 import org.apache.http.*;
@@ -32,18 +33,23 @@ public final class HttpResourceProcessor implements 
ResponseProcessor {
                        return 0;
 
                RestResponse res = call.getRestResponse();
-               HttpResource e = res.getOutput(HttpResource.class);
+               HttpResource r = res.getOutput(HttpResource.class);
 
-               res.header(e.getContentType()).header(e.getContentEncoding());
-               long contentLength = e.getContentLength();
+               call.addResponseHeader(r.getContentType());
+               call.addResponseHeader(r.getContentEncoding());
+               long contentLength = r.getContentLength();
                if (contentLength >= 0)
-                       res.header(contentLength(contentLength));
-               for (Header h : e.getHeaders())
-                       res.addHeader(h);
+                       call.addResponseHeader(contentLength(contentLength));
+               
+               List<Header> allHeaders = r.getAllHeaders();
+               for (int i = 0; i < allHeaders.size() ; i++) // Avoids Iterator 
creation.
+                       call.addResponseHeader(allHeaders.get(i));
+
                try (OutputStream os = res.getNegotiatedOutputStream()) {
-                       e.writeTo(os);
+                       r.writeTo(os);
                        os.flush();
                }
+
                return 1;
        }
 }
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processors/HttpResponseProcessor.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processors/HttpResponseProcessor.java
index 06d793f..6d8f251 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processors/HttpResponseProcessor.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processors/HttpResponseProcessor.java
@@ -12,6 +12,8 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.rest.processors;
 
+import static org.apache.juneau.http.HttpHeaders.*;
+
 import java.io.*;
 
 import org.apache.juneau.rest.*;
@@ -28,7 +30,28 @@ public final class HttpResponseProcessor implements 
ResponseProcessor {
                if (! call.getOutputInfo().isChildOf(HttpResponse.class))
                        return 0;
 
-               return 0;
+               RestResponse res = call.getRestResponse();
+               HttpResponse r = res.getOutput(HttpResponse.class);
+
+               call.status(r.getStatusLine().getStatusCode());
+
+               HttpEntity e = r.getEntity();
+
+               call.addResponseHeader(e.getContentType());
+               call.addResponseHeader(e.getContentEncoding());
+               long contentLength = e.getContentLength();
+               if (contentLength >= 0)
+                       call.addResponseHeader(contentLength(contentLength));
+               
+               for (Header h : r.getAllHeaders()) // No iterator involved.
+                       call.addResponseHeader(h);
+
+               try (OutputStream os = res.getNegotiatedOutputStream()) {
+                       e.writeTo(os);
+                       os.flush();
+               }
+               
+               return 1;
        }
 }
 
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processors/HttpResponseProcessor.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processors/ThrowableProcessor.java
similarity index 77%
copy from 
juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processors/HttpResponseProcessor.java
copy to 
juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processors/ThrowableProcessor.java
index 06d793f..235babe 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processors/HttpResponseProcessor.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processors/ThrowableProcessor.java
@@ -14,21 +14,26 @@ package org.apache.juneau.rest.processors;
 
 import java.io.*;
 
+import org.apache.juneau.http.header.*;
 import org.apache.juneau.rest.*;
-import org.apache.http.*;
 
 /**
- * Response handler for {@link HttpResponse} objects.
+ * Response handler for {@link Throwable} objects.
+ * 
+ * <p>
+ * Adds a <c>Thrown</c> header to the response and returns <c>0</c> so that 
the processor chain can continue.
  */
-public final class HttpResponseProcessor implements ResponseProcessor {
+public final class ThrowableProcessor implements ResponseProcessor {
 
        @Override /* ResponseProcessor */
        public int process(RestCall call) throws IOException {
 
-               if (! call.getOutputInfo().isChildOf(HttpResponse.class))
+               if (! call.getOutputInfo().isChildOf(Throwable.class))
                        return 0;
 
-               return 0;
+               
call.addResponseHeader(Thrown.of(call.getRestResponse().getOutput(Throwable.class)));
+
+               return 0; // Continue processing.
        }
 }
 
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/http/BasicHttpResource_Test.java 
b/juneau-utest/src/test/java/org/apache/juneau/http/BasicHttpResource_Test.java
index 5a5b85e..f77be54 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/http/BasicHttpResource_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/http/BasicHttpResource_Test.java
@@ -36,7 +36,7 @@ public class BasicHttpResource_Test {
                assertNull(x.getContentType());
                assertStream(x.getContent()).isNotNull().asString().isEmpty();
                assertNull(x.getContentEncoding());
-               assertList(x.getHeaders()).isSize(0);
+               assertList(x.getAllHeaders()).isSize(0);
 
                x = stringResource("foo").build();
                assertStream(x.getContent()).asString().is("foo");
@@ -121,7 +121,7 @@ public class BasicHttpResource_Test {
                assertString(x.getLastHeader("Foo").toString()).is("Foo: baz");
                assertObject(x.getFirstHeader("Bar")).doesNotExist();
                assertObject(x.getLastHeader("Bar")).doesNotExist();
-               assertObject(x.getHeaders()).asJson().is("['Foo: bar','Foo: 
baz']");
+               assertObject(x.getAllHeaders()).asJson().is("['Foo: bar','Foo: 
baz']");
        }
 
        @Test
@@ -131,7 +131,7 @@ public class BasicHttpResource_Test {
                assertString(x.getLastHeader("Foo").toString()).is("Foo: baz");
                assertObject(x.getFirstHeader("Bar").getValue()).doesNotExist();
                assertObject(x.getLastHeader("Bar").getValue()).doesNotExist();
-               assertObject(x.getHeaders()).asJson().is("['Foo: bar','Foo: 
baz','null: bar','Bar: null']");
+               assertObject(x.getAllHeaders()).asJson().is("['Foo: bar','Foo: 
baz','null: bar','Bar: null']");
        }
 
        @Test
@@ -141,7 +141,7 @@ public class BasicHttpResource_Test {
                assertString(x.getLastHeader("Foo").toString()).is("Foo: baz");
                assertObject(x.getFirstHeader("Bar").getValue()).doesNotExist();
                assertObject(x.getLastHeader("Bar").getValue()).doesNotExist();
-               assertObject(x.getHeaders()).asJson().is("['Foo: bar','Foo: 
baz','null: bar','Bar: null']");
+               assertObject(x.getAllHeaders()).asJson().is("['Foo: bar','Foo: 
baz','null: bar','Bar: null']");
        }
 
        @Test
@@ -151,7 +151,7 @@ public class BasicHttpResource_Test {
                assertString(x.getLastHeader("Foo").toString()).is("Foo: baz");
                assertObject(x.getFirstHeader("Bar").getValue()).doesNotExist();
                assertObject(x.getLastHeader("Bar").getValue()).doesNotExist();
-               assertObject(x.getHeaders()).asJson().is("['Foo: bar','Foo: 
baz','Bar: null']");
+               assertObject(x.getAllHeaders()).asJson().is("['Foo: bar','Foo: 
baz','Bar: null']");
        }
 
 
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/http/SerializedHeader_Test.java 
b/juneau-utest/src/test/java/org/apache/juneau/http/SerializedHeader_Test.java
index f43dd18..746cd16 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/http/SerializedHeader_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/http/SerializedHeader_Test.java
@@ -55,9 +55,9 @@ public class SerializedHeader_Test {
                assertString(x2.getValue()).is("bar,baz");
                SerializedHeader x3 = 
serializedHeader("Foo",list("bar","baz")).serializer(OAPI_SERIALIZER).serializer((HttpPartSerializerSession)null);
                assertString(x3.getValue()).is("['bar','baz']");
-               SerializedHeader x4 = 
serializedHeader("Foo",list("bar","baz")).serializer(OAPI_SERIALIZER).serializerIfNotSet((HttpPartSerializerSession)null);
+               SerializedHeader x4 = 
serializedHeader("Foo",list("bar","baz")).serializer(OAPI_SERIALIZER).copyWithSerializer((HttpPartSerializerSession)null);
                assertString(x4.getValue()).is("bar,baz");
-               SerializedHeader x5 = 
serializedHeader("Foo",list("bar","baz")).serializerIfNotSet(OAPI_SERIALIZER.createPartSession(null));
+               SerializedHeader x5 = 
serializedHeader("Foo",list("bar","baz")).copyWithSerializer(OAPI_SERIALIZER.createPartSession(null));
                assertString(x5.getValue()).is("bar,baz");
        }
 

Reply via email to