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 e59c7e8  Code cleanup.
e59c7e8 is described below

commit e59c7e8e190c95e237c5f0cbc17bd70943886e21
Author: JamesBognar <[email protected]>
AuthorDate: Sun Jun 6 16:01:21 2021 -0400

    Code cleanup.
---
 .../httppart/bean/RequestBeanPropertyMeta.java     |  11 ++-
 .../juneau/httppart/bean/ResponseBeanMeta.java     |  13 +--
 .../httppart/bean/ResponseBeanPropertyMeta.java    |  21 +++--
 .../org/apache/juneau/rest/client/RestClient.java  |  92 ++++++++++++++++---
 .../org/apache/juneau/rest/client/RestRequest.java | 101 ++++++++++++++-------
 .../apache/juneau/rest/client/RestResponse.java    |  43 +++++++--
 .../rest/client/remote/RemoteOperationArg.java     |  12 ++-
 .../java/org/apache/juneau/rest/RestRequest.java   |  38 +++++---
 .../rest/processors/ResponseBeanProcessor.java     |  21 +----
 9 files changed, 242 insertions(+), 110 deletions(-)

diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/RequestBeanPropertyMeta.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/RequestBeanPropertyMeta.java
index 204e826..f5e98ed 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/RequestBeanPropertyMeta.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/RequestBeanPropertyMeta.java
@@ -13,9 +13,11 @@
 package org.apache.juneau.httppart.bean;
 
 import static org.apache.juneau.internal.ClassUtils.*;
+import static java.util.Optional.*;
 
 import java.lang.annotation.*;
 import java.lang.reflect.*;
+import java.util.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.http.annotation.*;
@@ -40,7 +42,7 @@ public class RequestBeanPropertyMeta {
 
        private final Method getter;
        private final HttpPartType partType;
-       private final HttpPartSerializer serializer;
+       private final Optional<HttpPartSerializer> serializer;
        private final HttpPartParser parser;
        private final HttpPartSchema schema;
 
@@ -48,7 +50,7 @@ public class RequestBeanPropertyMeta {
                this.partType = b.partType;
                this.schema = b.schema;
                this.getter = b.getter;
-               this.serializer = schema.getSerializer() == null ? serializer : 
castOrCreate(HttpPartSerializer.class, schema.getSerializer(), true, b.cp);
+               this.serializer = ofNullable(schema.getSerializer() == null ? 
serializer : castOrCreate(HttpPartSerializer.class, schema.getSerializer(), 
true, b.cp));
                this.parser = schema.getParser() == null ? parser : 
castOrCreate(HttpPartParser.class, schema.getParser(), true, b.cp);
        }
 
@@ -112,11 +114,10 @@ public class RequestBeanPropertyMeta {
        /**
         * Returns the serializer to use for serializing the bean property 
value.
         *
-        * @param _default The default serializer to use if not defined on the 
annotation.
         * @return The serializer to use for serializing the bean property 
value.
         */
-       public HttpPartSerializerSession 
getSerializer(HttpPartSerializerSession _default) {
-               return serializer == null ? _default : 
serializer.createPartSession(null);
+       public Optional<HttpPartSerializer> getSerializer() {
+               return serializer;
        }
 
        /**
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanMeta.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanMeta.java
index d4d865d..b4ada18 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanMeta.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanMeta.java
@@ -16,6 +16,7 @@ import static org.apache.juneau.internal.ClassUtils.*;
 import static org.apache.juneau.httppart.bean.Utils.*;
 import static org.apache.juneau.httppart.HttpPartType.*;
 import static org.apache.juneau.annotation.InvalidAnnotationException.*;
+import static java.util.Optional.*;
 
 import java.io.*;
 import java.lang.reflect.*;
@@ -104,15 +105,15 @@ public class ResponseBeanMeta {
        private final int code;
        private final Map<String,ResponseBeanPropertyMeta> headerMethods;
        private final ResponseBeanPropertyMeta statusMethod, bodyMethod;
-       private final HttpPartSerializer partSerializer;
-       private final HttpPartParser partParser;
+       private final Optional<HttpPartSerializer> partSerializer;
+       private final Optional<HttpPartParser> partParser;
        private final HttpPartSchema schema;
 
        ResponseBeanMeta(Builder b) {
                this.cm = b.cm;
                this.code = b.code;
-               this.partSerializer = castOrCreate(HttpPartSerializer.class, 
b.partSerializer, true, b.cp);
-               this.partParser = castOrCreate(HttpPartParser.class, 
b.partParser, true, b.cp);
+               this.partSerializer = 
ofNullable(castOrCreate(HttpPartSerializer.class, b.partSerializer, true, 
b.cp));
+               this.partParser = ofNullable(castOrCreate(HttpPartParser.class, 
b.partParser, true, b.cp));
                this.schema = b.schema.build();
 
                Map<String,ResponseBeanPropertyMeta> properties = new 
LinkedHashMap<>();
@@ -126,7 +127,7 @@ public class ResponseBeanMeta {
                this.headerMethods = Collections.unmodifiableMap(hm);
 
                this.bodyMethod = b.bodyMethod == null ? null : 
b.bodyMethod.schema(schema).build(partSerializer, partParser);
-               this.statusMethod = b.statusMethod == null ? null : 
b.statusMethod.build(null, null);
+               this.statusMethod = b.statusMethod == null ? null : 
b.statusMethod.build(empty(), empty());
 
                if (bodyMethod != null)
                        properties.put(bodyMethod.getGetter().getName(), 
bodyMethod);
@@ -250,7 +251,7 @@ public class ResponseBeanMeta {
         *
         * @return The part serializer to use to serialize this response.
         */
-       public HttpPartSerializer getPartSerializer() {
+       public Optional<HttpPartSerializer> getPartSerializer() {
                return partSerializer;
        }
 
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanPropertyMeta.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanPropertyMeta.java
index 8b6e262..647d8ad 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanPropertyMeta.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanPropertyMeta.java
@@ -16,6 +16,7 @@ import static org.apache.juneau.internal.ClassUtils.*;
 
 import java.lang.reflect.*;
 import java.util.*;
+import static java.util.Optional.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.http.annotation.*;
@@ -41,16 +42,16 @@ public class ResponseBeanPropertyMeta {
 
        private final Method getter;
        private final HttpPartType partType;
-       private final HttpPartSerializer serializer;
-       private final HttpPartParser parser;
+       private final Optional<HttpPartSerializer> serializer;
+       private final Optional<HttpPartParser> parser;
        private final HttpPartSchema schema;
 
-       ResponseBeanPropertyMeta(Builder b, HttpPartSerializer serializer, 
HttpPartParser parser) {
+       ResponseBeanPropertyMeta(Builder b, Optional<HttpPartSerializer> 
serializer, Optional<HttpPartParser> parser) {
                this.partType = b.partType;
                this.schema = b.schema;
                this.getter = b.getter;
-               this.serializer = schema.getSerializer() == null ? serializer : 
castOrCreate(HttpPartSerializer.class, schema.getSerializer(), true, b.cp);
-               this.parser = schema.getParser() == null ? parser : 
castOrCreate(HttpPartParser.class, schema.getParser(), true, b.cp);
+               this.serializer = serializer.isPresent() ? serializer : 
ofNullable(castOrCreate(HttpPartSerializer.class, schema.getSerializer(), true, 
b.cp));
+               this.parser = parser.isPresent() ? parser : 
ofNullable(castOrCreate(HttpPartParser.class, schema.getParser(), true, b.cp));
        }
 
        static class Builder {
@@ -80,7 +81,7 @@ public class ResponseBeanPropertyMeta {
                        return this;
                }
 
-               ResponseBeanPropertyMeta build(HttpPartSerializer serializer, 
HttpPartParser parser) {
+               ResponseBeanPropertyMeta build(Optional<HttpPartSerializer> 
serializer, Optional<HttpPartParser> parser) {
                        return new ResponseBeanPropertyMeta(this, serializer, 
parser);
                }
        }
@@ -121,8 +122,8 @@ public class ResponseBeanPropertyMeta {
         *
         * @return The serializer to use for serializing the bean property 
value.
         */
-       public Optional<HttpPartSerializerSession> getSerializerSession() {
-               return Optional.ofNullable(serializer == null ? null : 
serializer.createPartSession(null));
+       public Optional<HttpPartSerializer> getSerializer() {
+               return serializer;
        }
 
        /**
@@ -130,8 +131,8 @@ public class ResponseBeanPropertyMeta {
         *
         * @return The parser to use for parsing the bean property value.
         */
-       public Optional<HttpPartParserSession> getParserSession() {
-               return Optional.ofNullable(parser == null ? null : 
parser.createPartSession(null));
+       public Optional<HttpPartParser> getParser() {
+               return parser;
        }
 
        /**
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 bb321d0..502f013 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
@@ -76,6 +76,7 @@ import org.apache.juneau.http.HttpHeaders;
 
 /**
  * Utility class for interfacing with remote REST interfaces.
+ * {@review}
  *
  * <p class='w900'>
  * Built upon the feature-rich Apache HttpClient library, the Juneau 
RestClient API adds support for fluent-style
@@ -1977,6 +1978,7 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
        final CloseableHttpClient httpClient;
        private final HttpClientConnectionManager connectionManager;
        private final boolean keepHttpClientOpen, leakDetection;
+       private final BeanStore beanStore;
        private final UrlEncodingSerializer urlEncodingSerializer;  // Used for 
form posts only.
        private final HttpPartSerializer partSerializer;
        private final HttpPartParser partParser;
@@ -2001,6 +2003,9 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
 
        final RestCallInterceptor[] interceptors;
 
+       private final Map<Class<?>, HttpPartParser> partParsers = new 
ConcurrentHashMap<>();
+       private final Map<Class<?>, HttpPartSerializer> partSerializers = new 
ConcurrentHashMap<>();
+
        // This is lazy-created.
        private volatile ExecutorService executorService;
        private final boolean executorServiceShutdownOnClose;
@@ -2034,6 +2039,11 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
        protected RestClient(ContextProperties cp) {
                super(cp);
                this.httpClient = cp.getInstance(RESTCLIENT_httpClient, 
CloseableHttpClient.class).orElse(null);
+
+               BeanStore bs = this.beanStore = new BeanStore()
+                       .addBean(ContextProperties.class, cp)
+                       .addBean(RestClient.class, this);
+
                this.connectionManager = 
cp.getInstance(RESTCLIENT_connectionManager, 
HttpClientConnectionManager.class).orElse(null);
                this.keepHttpClientOpen = 
cp.getBoolean(RESTCLIENT_keepHttpClientOpen).orElse(false);
                this.errorCodes = cp.getInstance(RESTCLIENT_errorCodes, 
Predicate.class).orElse(ERROR_CODES_DEFAULT);
@@ -2078,10 +2088,6 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
                }
                this.parsers = pgb.build();
 
-               BeanStore bs = new BeanStore()
-                       .addBean(ContextProperties.class, cp)
-                       .addBean(RestClient.class, this);
-
                this.urlEncodingSerializer = 
UrlEncodingSerializer.create().apply(cp).build();
                this.partSerializer = cp.getInstance(RESTCLIENT_partSerializer, 
HttpPartSerializer.class, 
bs).orElseGet(bs.createBeanSupplier(OpenApiSerializer.class));
                this.partParser = cp.getInstance(RESTCLIENT_partParser, 
HttpPartParser.class, bs).orElseGet(bs.createBeanSupplier(OpenApiParser.class));
@@ -3062,6 +3068,7 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
 
                                final RemoteMeta rm = new 
RemoteMeta(interfaceClass);
 
+                               @SuppressWarnings("deprecation")
                                @Override /* InvocationHandler */
                                public Object invoke(Object proxy, Method 
method, Object[] args) throws Throwable {
                                        RemoteOperationMeta rom = 
rm.getOperationMeta(method);
@@ -3073,8 +3080,6 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
                                                throw new 
RemoteMetadataException(interfaceClass, "Root URI has not been specified.  
Cannot construct absolute path to remote resource.");
 
                                        String httpMethod = rom.getHttpMethod();
-                                       HttpPartSerializerSession s = 
getPartSerializerSession();
-
                                        RestRequest rc = request(httpMethod, 
uri, hasContent(httpMethod));
 
                                        rc.serializer(serializer);
@@ -3082,17 +3087,19 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
 
                                        rm.getHeaders().forEach(x -> 
rc.header(APPEND, x));
 
+                                       HttpPartSerializer partSerializer = 
getPartSerializer();
+
                                        for (RemoteOperationArg a : 
rom.getPathArgs())
-                                               rc.pathArg(a.getName(), 
args[a.getIndex()], a.getSchema(), a.getSerializer(s));
+                                               rc.pathArg(a.getName(), 
args[a.getIndex()], a.getSchema(), a.getSerializer().orElse(partSerializer));
 
                                        for (RemoteOperationArg a : 
rom.getQueryArgs())
-                                               rc.queryArg(a.isSkipIfEmpty() ? 
SKIP_IF_EMPTY_FLAGS : DEFAULT_FLAGS, a.getName(), args[a.getIndex()], 
a.getSchema(), a.getSerializer(s));
+                                               rc.queryArg(a.isSkipIfEmpty() ? 
SKIP_IF_EMPTY_FLAGS : DEFAULT_FLAGS, a.getName(), args[a.getIndex()], 
a.getSchema(), a.getSerializer().orElse(partSerializer));
 
                                        for (RemoteOperationArg a : 
rom.getFormDataArgs())
-                                               
rc.formDataArg(a.isSkipIfEmpty() ? SKIP_IF_EMPTY_FLAGS : DEFAULT_FLAGS, 
a.getName(), args[a.getIndex()], a.getSchema(), a.getSerializer(s));
+                                               
rc.formDataArg(a.isSkipIfEmpty() ? SKIP_IF_EMPTY_FLAGS : DEFAULT_FLAGS, 
a.getName(), args[a.getIndex()], a.getSchema(), 
a.getSerializer().orElse(partSerializer));
 
                                        for (RemoteOperationArg a : 
rom.getHeaderArgs())
-                                               rc.headerArg(a.isSkipIfEmpty() 
? SKIP_IF_EMPTY_FLAGS : DEFAULT_FLAGS, a.getName(), args[a.getIndex()], 
a.getSchema(), a.getSerializer(s));
+                                               rc.headerArg(a.isSkipIfEmpty() 
? SKIP_IF_EMPTY_FLAGS : DEFAULT_FLAGS, a.getName(), args[a.getIndex()], 
a.getSchema(), a.getSerializer().orElse(partSerializer));
 
                                        RemoteOperationArg ba = 
rom.getBodyArg();
                                        if (ba != null)
@@ -3106,19 +3113,18 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
                                                                for 
(RequestBeanPropertyMeta p : rbm.getProperties()) {
                                                                        Object 
val = p.getGetter().invoke(bean);
                                                                        
HttpPartType pt = p.getPartType();
-                                                                       
HttpPartSerializerSession ps = p.getSerializer(s);
                                                                        String 
pn = p.getPartName();
                                                                        
HttpPartSchema schema = p.getSchema();
                                                                        
EnumSet<ListOperation> flags = schema.isSkipIfEmpty() ? SKIP_IF_EMPTY_FLAGS : 
DEFAULT_FLAGS;
                                                                        if (pt 
== PATH)
-                                                                               
rc.pathArg(pn, val, schema, p.getSerializer(s));
+                                                                               
rc.pathArg(pn, val, schema, p.getSerializer().orElse(partSerializer));
                                                                        else if 
(val != null) {
                                                                                
if (pt == QUERY)
-                                                                               
        rc.queryArg(flags, pn, val, schema, ps);
+                                                                               
        rc.queryArg(flags, pn, val, schema, 
p.getSerializer().orElse(partSerializer));
                                                                                
else if (pt == FORMDATA)
-                                                                               
        rc.formDataArg(flags, pn, val, schema, ps);
+                                                                               
        rc.formDataArg(flags, pn, val, schema, 
p.getSerializer().orElse(partSerializer));
                                                                                
else if (pt == HEADER)
-                                                                               
        rc.headerArg(flags, pn, val, schema, ps);
+                                                                               
        rc.headerArg(flags, pn, val, schema, 
p.getSerializer().orElse(partSerializer));
                                                                                
else /* (pt == HttpPartType.BODY) */
                                                                                
        rc.body(val, schema);
                                                                        }
@@ -3397,6 +3403,62 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
                return ()->args.length == 0 ? msg : MessageFormat.format(msg, 
args);
        }
 
+       /**
+        * Returns the part serializer associated with this client.
+        *
+        * @return The part serializer associated with this client.
+        */
+       protected HttpPartSerializer getPartSerializer() {
+               return partSerializer;
+       }
+
+       /**
+        * Returns the part parser associated with this client.
+        *
+        * @return The part parser associated with this client.
+        */
+       protected HttpPartParser getPartParser() {
+               return partParser;
+       }
+
+       /**
+        * Returns the part serializer instance of the specified type.
+        *
+        * @param c The part serializer class.
+        * @return The part serializer.
+        */
+       protected HttpPartSerializer getPartSerializer(Class<? extends 
HttpPartSerializer> c) {
+               HttpPartSerializer x = partSerializers.get(c);
+               if (x == null) {
+                       try {
+                               x = beanStore.createBean(c);
+                       } catch (ExecutableException e) {
+                               throw new RuntimeException(e);
+                       }
+                       partSerializers.put(c, x);
+               }
+               return x;
+       }
+
+       /**
+        * Returns the part parser instance of the specified type.
+        *
+        * @param c The part parser class.
+        * @return The part parser.
+        */
+       protected HttpPartParser getPartParser(Class<? extends HttpPartParser> 
c) {
+               HttpPartParser x = partParsers.get(c);
+               if (x == null) {
+                       try {
+                               x = beanStore.createBean(c);
+                       } catch (ExecutableException e) {
+                               throw new RuntimeException(e);
+                       }
+                       partParsers.put(c, x);
+               }
+               return x;
+       }
+
 
        
//-----------------------------------------------------------------------------------------------------------------
        // RestCallInterceptor methods
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 c4ea02e..afae51a 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
@@ -83,7 +83,6 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
        private boolean hasInput;                              // input() was 
called, even if it's setting 'null'.
        private Serializer serializer;
        private Parser parser;
-       private HttpPartSerializerSession partSerializer;
        private HttpPartSchema requestBodySchema;
        private URIBuilder uriBuilder;
        private List<NameValuePair> formData;
@@ -92,6 +91,8 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
        private HttpContext context;
        private List<Class<? extends Throwable>> rethrow;
 
+       private final Map<HttpPartSerializer,HttpPartSerializerSession> 
partSerializerSessions = new IdentityHashMap<>();
+
        /**
         * Constructs a REST call with the specified method name.
         *
@@ -106,7 +107,6 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
                this.client = client;
                this.request = createInnerRequest(method, uri, hasBody);
                this.errorCodes = client.errorCodes;
-               this.partSerializer = client.getPartSerializerSession();
                this.uriBuilder = new URIBuilder(request.getURI());
                this.ignoreErrors = client.ignoreErrors;
        }
@@ -905,7 +905,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         * @throws RestCallException Invalid input.
         */
        public RestRequest path(String name, Object value) throws 
RestCallException {
-               return paths(serializedPart(name, value, PATH, partSerializer, 
null, null));
+               return paths(serializedPart(name, value, PATH, 
partSerializer(), null, null));
        }
 
        /**
@@ -954,7 +954,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         * @throws RestCallException Invalid input.
         */
        public RestRequest path(String name, Object value, HttpPartSchema 
schema) throws RestCallException {
-               return paths(serializedPart(name, value, PATH, partSerializer, 
schema, null));
+               return paths(serializedPart(name, value, PATH, 
partSerializer(), schema, null));
        }
 
        /**
@@ -1005,10 +1005,10 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
                                        innerPath(BasicPart.cast(Array.get(o, 
i)));
                        } else if (o instanceof Map) {
                                for (Map.Entry e : toMap(o).entrySet())
-                                       innerPath(serializedPart(e.getKey(), 
e.getValue(), PATH, partSerializer, null, null));
+                                       innerPath(serializedPart(e.getKey(), 
e.getValue(), PATH, partSerializer(), null, null));
                        } else if (isBean(o)) {
                                for (Map.Entry<String,Object> e : 
toBeanMap(o).entrySet())
-                                       innerPath(serializedPart(e.getKey(), 
e.getValue(), PATH, partSerializer, null, null));
+                                       innerPath(serializedPart(e.getKey(), 
e.getValue(), PATH, partSerializer(), null, null));
                        } else if (o != null) {
                                throw runtimeException("Invalid type passed to 
paths(): {0}", className(o));
                        }
@@ -1043,13 +1043,15 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
                if (pairs.length % 2 != 0)
                        throw new RestCallException(null, null, "Odd number of 
parameters passed into pathPairs()");
                for (int i = 0; i < pairs.length; i+=2)
-                       paths(serializedPart(pairs[i], pairs[i+1], PATH, 
partSerializer, null, null));
+                       paths(serializedPart(pairs[i], pairs[i+1], PATH, 
partSerializer(), null, null));
                return this;
        }
 
-       RestRequest pathArg(String name, Object value, HttpPartSchema schema, 
HttpPartSerializerSession serializer) throws RestCallException {
+       RestRequest pathArg(String name, Object value, HttpPartSchema schema, 
HttpPartSerializer serializer2) throws RestCallException {
                boolean isMulti = isEmpty(name) || "*".equals(name) || value 
instanceof PartList || isNameValuePairArray(value);
 
+               HttpPartSerializerSession serializer = 
getPartSerializerSession(serializer2);
+
                if (! isMulti)
                        return innerPath(serializedPart(name, value, PATH, 
serializer, schema, null));
 
@@ -1131,7 +1133,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         * @throws RestCallException Invalid input.
         */
        public RestRequest query(ListOperation flag, String name, Object value, 
HttpPartSchema schema) throws RestCallException {
-               return queries(flag, serializedPart(name, value, QUERY, 
partSerializer, schema, EnumSet.of(flag)));
+               return queries(flag, serializedPart(name, value, QUERY, 
partSerializer(), schema, EnumSet.of(flag)));
        }
 
        /**
@@ -1156,7 +1158,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         * @throws RestCallException Invalid input.
         */
        public RestRequest query(String name, Object value) throws 
RestCallException {
-               return queries(serializedPart(name, value, QUERY, 
partSerializer, null, null));
+               return queries(serializedPart(name, value, QUERY, 
partSerializer(), null, null));
        }
 
        /**
@@ -1207,7 +1209,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         * @throws RestCallException Invalid input.
         */
        public RestRequest query(String name, Object value, HttpPartSchema 
schema) throws RestCallException {
-               return queries(serializedPart(name, value, QUERY, 
partSerializer, schema, null));
+               return queries(serializedPart(name, value, QUERY, 
partSerializer(), schema, null));
        }
 
        /**
@@ -1240,7 +1242,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         * @return This object (for method chaining).
         */
        public RestRequest query(ListOperation flag, String name, Object value) 
{
-               return queries(flag, serializedPart(name, value, QUERY, 
partSerializer, null, EnumSet.of(flag)));
+               return queries(flag, serializedPart(name, value, QUERY, 
partSerializer(), null, EnumSet.of(flag)));
        }
 
        /**
@@ -1333,10 +1335,10 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
                                        l.add(BasicPart.cast(Array.get(o, i)));
                        } else if (o instanceof Map) {
                                for (Map.Entry<Object,Object> e : 
toMap(o).entrySet())
-                                       l.add(serializedPart(e.getKey(), 
e.getValue(), QUERY, partSerializer, null, EnumSet.of(flag)));
+                                       l.add(serializedPart(e.getKey(), 
e.getValue(), QUERY, partSerializer(), null, EnumSet.of(flag)));
                        } else if (isBean(o)) {
                                for (Map.Entry<String,Object> e : 
toBeanMap(o).entrySet())
-                                       l.add(serializedPart(e.getKey(), 
e.getValue(), QUERY, partSerializer, null, EnumSet.of(flag)));
+                                       l.add(serializedPart(e.getKey(), 
e.getValue(), QUERY, partSerializer(), null, EnumSet.of(flag)));
                        } else if (o != null) {
                                throw runtimeException("Invalid type passed to 
queries(): {0}", className(o));
                        }
@@ -1368,7 +1370,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
                if (pairs.length % 2 != 0)
                        throw new RestCallException(null, null, "Odd number of 
parameters passed into queryPairs()");
                for (int i = 0; i < pairs.length; i+=2)
-                       queries(serializedPart(pairs[i], pairs[i+1], QUERY, 
partSerializer, null, null));
+                       queries(serializedPart(pairs[i], pairs[i+1], QUERY, 
partSerializer(), null, null));
                return this;
        }
 
@@ -1415,10 +1417,13 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
                return this;
        }
 
-       RestRequest queryArg(EnumSet<ListOperation> flags, String name, Object 
value, HttpPartSchema schema, HttpPartSerializerSession serializer) throws 
RestCallException {
+       @SuppressWarnings("deprecation")
+       RestRequest queryArg(EnumSet<ListOperation> flags, String name, Object 
value, HttpPartSchema schema, HttpPartSerializer serializer2) throws 
RestCallException {
                flags = ListOperation.orDefault(flags);
                boolean isMulti = isEmpty(name) || "*".equals(name) || value 
instanceof PartList || isNameValuePairArray(value);
 
+               HttpPartSerializerSession serializer = 
getPartSerializerSession(serializer2);
+
                if (! isMulti)
                        return innerQuery(flags, AList.of(serializedPart(name, 
value, QUERY, serializer, schema, flags)));
 
@@ -1447,6 +1452,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
                return innerQuery(flags, l);
        }
 
+       @SuppressWarnings("deprecation")
        private RestRequest innerQuery(EnumSet<ListOperation> flags, 
List<NameValuePair> params) {
                flags = ListOperation.orDefault(flags);
                params.removeIf(x -> x.getValue() == null);
@@ -1510,7 +1516,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         * @throws RestCallException Invalid input.
         */
        public RestRequest formData(ListOperation flag, String name, Object 
value, HttpPartSchema schema) throws RestCallException {
-               return formDatas(flag, serializedPart(name, value, FORMDATA, 
partSerializer, schema, EnumSet.of(flag)));
+               return formDatas(flag, serializedPart(name, value, FORMDATA, 
partSerializer(), schema, EnumSet.of(flag)));
        }
 
        /**
@@ -1535,7 +1541,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         * @throws RestCallException Invalid input.
         */
        public RestRequest formData(String name, Object value) throws 
RestCallException {
-               return formDatas(serializedPart(name, value, FORMDATA, 
partSerializer, null, null));
+               return formDatas(serializedPart(name, value, FORMDATA, 
partSerializer(), null, null));
        }
 
        /**
@@ -1587,7 +1593,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         * @throws RestCallException Invalid input.
         */
        public RestRequest formData(String name, Object value, HttpPartSchema 
schema) throws RestCallException {
-               return formDatas(serializedPart(name, value, FORMDATA, 
partSerializer, schema, null));
+               return formDatas(serializedPart(name, value, FORMDATA, 
partSerializer(), schema, null));
        }
 
        /**
@@ -1620,7 +1626,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         * @return This object (for method chaining).
         */
        public RestRequest formData(ListOperation flag, String name, Object 
value) {
-               return formDatas(flag, serializedPart(name, value, FORMDATA, 
partSerializer, null, EnumSet.of(flag)));
+               return formDatas(flag, serializedPart(name, value, FORMDATA, 
partSerializer(), null, EnumSet.of(flag)));
        }
 
        /**
@@ -1715,10 +1721,10 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
                                        l.add(BasicPart.cast(Array.get(o, i)));
                        } else if (o instanceof Map) {
                                for (Map.Entry<Object,Object> e : 
toMap(o).entrySet())
-                                       l.add(serializedPart(e.getKey(), 
e.getValue(), FORMDATA, partSerializer, null, EnumSet.of(flag)));
+                                       l.add(serializedPart(e.getKey(), 
e.getValue(), FORMDATA, partSerializer(), null, EnumSet.of(flag)));
                        } else if (isBean(o)) {
                                for (Map.Entry<String,Object> e : 
toBeanMap(o).entrySet())
-                                       l.add(serializedPart(e.getKey(), 
e.getValue(), FORMDATA, partSerializer, null, EnumSet.of(flag)));
+                                       l.add(serializedPart(e.getKey(), 
e.getValue(), FORMDATA, partSerializer(), null, EnumSet.of(flag)));
                        } else if (o != null) {
                                throw runtimeException("Invalid type passed to 
formDatas(): {0}", className(o));
                        }
@@ -1750,7 +1756,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
                if (pairs.length % 2 != 0)
                        throw new RestCallException(null, null, "Odd number of 
parameters passed into formDataPairs()");
                for (int i = 0; i < pairs.length; i+=2)
-                       formDatas(serializedPart(pairs[i], pairs[i+1], 
FORMDATA, partSerializer, null, null));
+                       formDatas(serializedPart(pairs[i], pairs[i+1], 
FORMDATA, partSerializer(), null, null));
                return this;
        }
 
@@ -1806,10 +1812,13 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
                return this;
        }
 
-       RestRequest formDataArg(EnumSet<ListOperation> flags, String name, 
Object value, HttpPartSchema schema, HttpPartSerializerSession serializer) 
throws RestCallException {
+       @SuppressWarnings("deprecation")
+       RestRequest formDataArg(EnumSet<ListOperation> flags, String name, 
Object value, HttpPartSchema schema, HttpPartSerializer serializer2) throws 
RestCallException {
                flags = ListOperation.orDefault(flags);
                boolean isMulti = isEmpty(name) || "*".equals(name) || value 
instanceof PartList || isNameValuePairArray(value);
 
+               HttpPartSerializerSession serializer = 
getPartSerializerSession(serializer2);
+
                if (! isMulti)
                        return innerFormData(flags, 
AList.of(serializedPart(name, value, FORMDATA, serializer, schema, flags)));
 
@@ -1838,6 +1847,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
                return innerFormData(flags, l);
        }
 
+       @SuppressWarnings("deprecation")
        private RestRequest innerFormData(EnumSet<ListOperation> flags, 
List<NameValuePair> params) {
                input = null;
                flags = ListOperation.orDefault(flags);
@@ -2013,7 +2023,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         * @return This object (for method chaining).
         */
        public RestRequest header(ListOperation flag, String name, Object 
value, HttpPartSchema schema) {
-               return headers(flag, serializedHeader(name, value, 
partSerializer, schema, EnumSet.of(flag)));
+               return headers(flag, serializedHeader(name, value, 
partSerializer(), schema, EnumSet.of(flag)));
        }
 
        /**
@@ -2040,7 +2050,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         * @return This object (for method chaining).
         */
        public RestRequest header(String name, Object value) {
-               return headers(serializedHeader(name, value, partSerializer, 
null, null));
+               return headers(serializedHeader(name, value, partSerializer(), 
null, null));
        }
 
        /**
@@ -2074,7 +2084,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         * @return This object (for method chaining).
         */
        public RestRequest header(String name, Object value, HttpPartSchema 
schema) {
-               return headers(serializedHeader(name, value, partSerializer, 
schema, null));
+               return headers(serializedHeader(name, value, partSerializer(), 
schema, null));
        }
 
        /**
@@ -2107,7 +2117,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         * @return This object (for method chaining).
         */
        public RestRequest header(ListOperation flag, String name, Object 
value) {
-               return headers(flag, serializedHeader(name, value, 
partSerializer, null, EnumSet.of(flag)));
+               return headers(flag, serializedHeader(name, value, 
partSerializer(), null, EnumSet.of(flag)));
        }
 
        /**
@@ -2250,10 +2260,10 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
                                        l.add(HttpHeaders.cast(Array.get(o, 
i)));
                        } else if (o instanceof Map) {
                                for (Map.Entry<Object,Object> e : 
toMap(o).entrySet())
-                                       l.add(serializedHeader(e.getKey(), 
e.getValue(), partSerializer, null, EnumSet.of(flag)));
+                                       l.add(serializedHeader(e.getKey(), 
e.getValue(), partSerializer(), null, EnumSet.of(flag)));
                        } else if (isBean(o)) {
                                for (Map.Entry<String,Object> e : 
toBeanMap(o).entrySet())
-                                       l.add(serializedHeader(e.getKey(), 
e.getValue(), partSerializer, null, EnumSet.of(flag)));
+                                       l.add(serializedHeader(e.getKey(), 
e.getValue(), partSerializer(), null, EnumSet.of(flag)));
                        } else if (o != null) {
                                throw runtimeException("Invalid type passed to 
headers(): {0}", className(o));
                        }
@@ -2317,14 +2327,17 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
                if (pairs.length % 2 != 0)
                        throw runtimeException("Odd number of parameters passed 
into headerPairs()");
                for (int i = 0; i < pairs.length; i+=2)
-                       l.add(serializedHeader(pairs[i], pairs[i+1], 
partSerializer, null, null));
+                       l.add(serializedHeader(pairs[i], pairs[i+1], 
partSerializer(), null, null));
                return innerHeaders(EnumSet.of(flag), l);
        }
 
-       RestRequest headerArg(EnumSet<ListOperation> flags, String name, Object 
value, HttpPartSchema schema, HttpPartSerializerSession serializer) throws 
RestCallException {
+       @SuppressWarnings("deprecation")
+       RestRequest headerArg(EnumSet<ListOperation> flags, String name, Object 
value, HttpPartSchema schema, HttpPartSerializer serializer2) throws 
RestCallException {
                flags = ListOperation.orDefault(flags);
                boolean isMulti = isEmpty(name) || "*".equals(name) || value 
instanceof HeaderList || isHeaderArray(value);
 
+               HttpPartSerializerSession serializer = 
getPartSerializerSession(serializer2);
+
                if (! isMulti)
                        return innerHeaders(flags, 
AList.of(serializedHeader(name, value, serializer, schema, flags)));
 
@@ -2353,6 +2366,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
                return innerHeaders(flags, l);
        }
 
+       @SuppressWarnings("deprecation")
        private RestRequest innerHeaders(EnumSet<ListOperation> flags, 
Collection<Header> headers) {
                flags = ListOperation.orDefault(flags);
                headers.removeIf(x -> x.getValue() == null);
@@ -3523,14 +3537,31 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
                return (Map<Object,Object>)o;
        }
 
+       @SuppressWarnings("deprecation")
        private static SerializedPart serializedPart(Object key, Object value, 
HttpPartType type, HttpPartSerializerSession serializer, HttpPartSchema schema, 
EnumSet<ListOperation> flags) {
                return key == null ? null : new SerializedPart(stringify(key), 
value, type, serializer, schema, flags == null ? false : 
flags.contains(SKIP_IF_EMPTY));
        }
 
+       @SuppressWarnings("deprecation")
        private static SerializedHeader serializedHeader(Object key, Object 
value, HttpPartSerializerSession serializer, HttpPartSchema schema, 
EnumSet<ListOperation> flags) {
                return key == null ? null : new 
SerializedHeader(stringify(key), value, serializer, schema, flags == null ? 
false : flags.contains(SKIP_IF_EMPTY));
        }
 
+       /**
+        * Creates a session of the specified part serializer.
+        *
+        * @param serializer The serializer to create a session for.
+        * @return A session of the specified serializer.
+        */
+       protected HttpPartSerializerSession 
getPartSerializerSession(HttpPartSerializer serializer) {
+               HttpPartSerializerSession s = 
partSerializerSessions.get(serializer);
+               if (s == null) {
+                       s = serializer.createPartSession(null);
+                       partSerializerSessions.put(serializer, s);
+               }
+               return s;
+       }
+
        private static boolean isNameValuePairArray(Object o) {
                if (o == null || ! o.getClass().isArray())
                        return false;
@@ -3547,6 +3578,11 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
                return false;
        }
 
+       // TEMP.
+       private HttpPartSerializerSession partSerializer() {
+               return getPartSerializerSession(client.getPartSerializer());
+       }
+
        
//-----------------------------------------------------------------------------------------------------------------
        // Other methods
        
//-----------------------------------------------------------------------------------------------------------------
@@ -3563,7 +3599,6 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
                                        .a("hasInput", hasInput)
                                        .a("ignoreErrors", ignoreErrors)
                                        .a("interceptors", interceptors)
-                                       .a("partSerializer", partSerializer)
                                        .a("requestBodySchema", 
requestBodySchema)
                                        .a("response", response)
                                        .a("serializer", serializer)
diff --git 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestResponse.java
 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestResponse.java
index 284e386..ee91d68 100644
--- 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestResponse.java
+++ 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestResponse.java
@@ -51,11 +51,13 @@ public class RestResponse implements HttpResponse {
        private final RestRequest request;
        private final HttpResponse response;
        private final Parser parser;
-       HttpPartParserSession partParser;
        private ResponseBody responseBody;
        private boolean isClosed;
        private HeaderList headers;
 
+       private Map<HttpPartParser,HttpPartParserSession> partParserSessions = 
new IdentityHashMap<>();
+       private HttpPartParserSession partParserSession;
+
        /**
         * Constructor.
         *
@@ -70,7 +72,6 @@ public class RestResponse implements HttpResponse {
                this.parser = parser;
                this.response = response == null ? new BasicHttpResponse(null, 
0, null) : response;
                this.responseBody = new ResponseBody(client, request, this, 
parser);
-               this.partParser = client.getPartParserSession();
                this.headers = HeaderList.of(this.response.getAllHeaders());
        }
 
@@ -432,7 +433,7 @@ public class RestResponse implements HttpResponse {
                                @Override /* InvocationHandler */
                                public Object invoke(Object proxy, Method 
method, Object[] args) throws Throwable {
                                        ResponseBeanPropertyMeta pm = 
rbm.getProperty(method.getName());
-                                       HttpPartParserSession pp = 
pm.getParserSession().orElse(partParser);
+                                       HttpPartParserSession pp = 
getPartParserSession(pm.getParser().orElse(rc.getPartParser()));
                                        HttpPartSchema schema = pm.getSchema();
                                        HttpPartType pt = pm.getPartType();
                                        String name = 
pm.getPartName().orElse(null);
@@ -640,7 +641,7 @@ public class RestResponse implements HttpResponse {
         */
        @Override /* HttpMessage */
        public ResponseHeader[] getHeaders(String name) {
-               return headers.stream(name).map(x -> new 
ResponseHeader(request, this, 
x).parser(partParser)).toArray(ResponseHeader[]::new);
+               return headers.stream(name).map(x -> new 
ResponseHeader(request, this, 
x).parser(getPartParserSession())).toArray(ResponseHeader[]::new);
        }
 
        /**
@@ -656,7 +657,7 @@ public class RestResponse implements HttpResponse {
         */
        @Override /* HttpMessage */
        public ResponseHeader getFirstHeader(String name) {
-               return new ResponseHeader(request, this, 
headers.getFirst(name).orElse(null)).parser(partParser);
+               return new ResponseHeader(request, this, 
headers.getFirst(name).orElse(null)).parser(getPartParserSession());
        }
 
        /**
@@ -672,7 +673,7 @@ public class RestResponse implements HttpResponse {
         */
        @Override /* HttpMessage */
        public ResponseHeader getLastHeader(String name) {
-               return new ResponseHeader(request, this, 
headers.getLast(name).orElse(null)).parser(partParser);
+               return new ResponseHeader(request, this, 
headers.getLast(name).orElse(null)).parser(getPartParserSession());
        }
 
        /**
@@ -685,7 +686,7 @@ public class RestResponse implements HttpResponse {
         * @return The header, never <jk>null</jk>.
         */
        public ResponseHeader getHeader(String name) {
-               return new ResponseHeader(request, this, 
headers.get(name).orElse(null)).parser(partParser);
+               return new ResponseHeader(request, this, 
headers.get(name).orElse(null)).parser(getPartParserSession());
        }
 
        /**
@@ -697,7 +698,7 @@ public class RestResponse implements HttpResponse {
         */
        @Override /* HttpMessage */
        public ResponseHeader[] getAllHeaders() {
-               return headers.stream().map(x -> new ResponseHeader(request, 
this, x).parser(partParser)).toArray(ResponseHeader[]::new);
+               return headers.stream().map(x -> new ResponseHeader(request, 
this, x).parser(getPartParserSession())).toArray(ResponseHeader[]::new);
        }
 
        /**
@@ -882,6 +883,32 @@ public class RestResponse implements HttpResponse {
        // Other methods
        
//------------------------------------------------------------------------------------------------------------------
 
+       /**
+        * Creates a session of the specified part parser.
+        *
+        * @param parser The parser to create a session for.
+        * @return A session of the specified parser.
+        */
+       protected HttpPartParserSession getPartParserSession(HttpPartParser 
parser) {
+               HttpPartParserSession s = partParserSessions.get(parser);
+               if (s == null) {
+                       s = parser.createPartSession(null);
+                       partParserSessions.put(parser, s);
+               }
+               return s;
+       }
+
+       /**
+        * Creates a session of the client-default parat parser.
+        *
+        * @return A session of the specified parser.
+        */
+       protected HttpPartParserSession getPartParserSession() {
+               if (partParserSession == null)
+                       partParserSession = 
client.getPartParser().createPartSession(null);
+               return partParserSession;
+       }
+
        HttpResponse asHttpResponse() {
                return response;
        }
diff --git 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationArg.java
 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationArg.java
index 12f6812..afe8b64 100644
--- 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationArg.java
+++ 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationArg.java
@@ -13,6 +13,9 @@
 package org.apache.juneau.rest.client.remote;
 
 import static org.apache.juneau.internal.ClassUtils.*;
+import static java.util.Optional.*;
+
+import java.util.*;
 
 import static org.apache.juneau.httppart.HttpPartType.*;
 
@@ -31,13 +34,13 @@ public final class RemoteOperationArg {
 
        private final int index;
        private final HttpPartType partType;
-       private final HttpPartSerializer serializer;
+       private final Optional<HttpPartSerializer> serializer;
        private final HttpPartSchema schema;
 
        RemoteOperationArg(int index, HttpPartType partType, HttpPartSchema 
schema) {
                this.index = index;
                this.partType = partType;
-               this.serializer = createSerializer(partType, schema);
+               this.serializer = ofNullable(createSerializer(partType, 
schema));
                this.schema = schema;
        }
 
@@ -84,11 +87,10 @@ public final class RemoteOperationArg {
        /**
         * Returns the HTTP part serializer to use for serializing this part.
         *
-        * @param _default The default serializer to use if the serializer was 
not defined via annotations.
         * @return The HTTP part serializer, or the default if not specified.
         */
-       public HttpPartSerializerSession 
getSerializer(HttpPartSerializerSession _default) {
-               return serializer == null ? _default : 
serializer.createPartSession(null);
+       public Optional<HttpPartSerializer> getSerializer() {
+               return serializer;
        }
 
        /**
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java
index 5e786f6..7df7af3 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java
@@ -119,12 +119,13 @@ public final class RestRequest {
        private final RequestPathParams pathParams;
        private final RequestHeaders headers;
        private final RequestAttributes attrs;
-       private final HttpPartSerializerSession partSerializerSession;
        private final HttpPartParserSession partParserSession;
        private final RestCall call;
        private final SerializerSessionArgs serializerSessionArgs;
        private final ParserSessionArgs parserSessionArgs;
 
+       private final Map<HttpPartSerializer,HttpPartSerializerSession> 
partSerializerSessions = new IdentityHashMap<>();
+
        // Lazy initialized.
        private VarResolverSession varSession;
        private RequestFormParams formParams;
@@ -184,8 +185,6 @@ public final class RestRequest {
                        .resolver(getVarResolverSession())
                        .useWhitespace(isPlainText() ? true : null);
 
-               partSerializerSession = 
opContext.getPartSerializer().createPartSession(serializerSessionArgs);
-
                pathParams.parser(partParserSession);
 
                queryParams
@@ -1571,15 +1570,6 @@ public final class RestRequest {
        }
 
        /**
-        * Returns the part serializer associated with this request.
-        *
-        * @return The part serializer associated with this request.
-        */
-       public HttpPartSerializerSession getPartSerializerSession() {
-               return partSerializerSession;
-       }
-
-       /**
         * Returns the HTTP method of this request.
         *
         * <p>
@@ -1983,6 +1973,21 @@ public final class RestRequest {
                return parserSessionArgs;
        }
 
+       /**
+        * Creates a session of the specified part serializer.
+        *
+        * @param serializer The serializer to create a session for.
+        * @return A session of the specified serializer.
+        */
+       public HttpPartSerializerSession 
getPartSerializerSession(HttpPartSerializer serializer) {
+               HttpPartSerializerSession s = 
partSerializerSessions.get(serializer);
+               if (s == null) {
+                       s = 
serializer.createPartSession(getSerializerSessionArgs());
+                       partSerializerSessions.put(serializer, s);
+               }
+               return s;
+       }
+
        /* Called by RestCall.finish() */
        void close() {
                if (config != null) {
@@ -2028,6 +2033,15 @@ public final class RestRequest {
                return inner;
        }
 
+       /**
+        * Returns the part serializer session for this request.
+        *
+        * @return The part serializer session for this request.
+        */
+       public HttpPartSerializerSession getPartSerializerSession() {
+               return getPartSerializerSession(opContext.getPartSerializer());
+       }
+
        @Override /* Object */
        public String toString() {
                StringBuilder sb = new 
StringBuilder("\n").append(getRequestLine()).append("\n");
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processors/ResponseBeanProcessor.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processors/ResponseBeanProcessor.java
index 416bd97..ffa00e5 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processors/ResponseBeanProcessor.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processors/ResponseBeanProcessor.java
@@ -24,7 +24,6 @@ import org.apache.http.*;
 import org.apache.http.Header;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.http.header.*;
-import org.apache.juneau.http.part.*;
 import org.apache.juneau.http.response.*;
 import org.apache.juneau.httppart.*;
 import org.apache.juneau.httppart.bean.*;
@@ -39,6 +38,8 @@ public final class ResponseBeanProcessor implements 
ResponseProcessor {
 
                RestRequest req = call.getRestRequest();
                RestResponse res = call.getRestResponse();
+               HttpPartSerializer defaultPartSerializer = 
req.getOpContext().getPartSerializer();
+
                Object output = res.getOutput(Object.class);
 
                if (output == null)
@@ -51,8 +52,6 @@ public final class ResponseBeanProcessor implements 
ResponseProcessor {
                if (rm == null)
                        rm = req.getOpContext().getResponseBeanMeta(output);
 
-               HttpPartSerializerSession ss = req.getPartSerializerSession();
-
                ResponseBeanPropertyMeta stm = rm.getStatusMethod();
                if (stm != null) {
                        try {
@@ -76,13 +75,7 @@ public final class ResponseBeanProcessor implements 
ResponseProcessor {
                                                        
@SuppressWarnings("rawtypes")
                                                        Map.Entry x = 
(Map.Entry)o2;
                                                        String k = 
stringify(x.getKey());
-                                                       h = new 
SerializedHeader(k, x.getValue(), hm.getSerializerSession().orElse(ss), 
ps.getProperty(k), true);
-                                               } else if (o2 instanceof 
SerializedHeader) {
-                                                       SerializedHeader x = 
((SerializedHeader)o2);
-                                                       h = x.copyWith(ss, 
ps.getProperty(x.getName()));
-                                               } else if (o2 instanceof 
SerializedPart) {
-                                                       SerializedPart x = 
((SerializedPart)o2);
-                                                       h = 
BasicHeader.of(x.copyWith(ss, ps.getProperty(x.getName())));
+                                                       h = new 
SerializedHeader(k, x.getValue(), 
req.getPartSerializerSession(hm.getSerializer().orElse(defaultPartSerializer)), 
ps.getProperty(k), true);
                                                } else if (o2 instanceof 
Header) {
                                                        h = (Header)o2;
                                                } else if (o2 instanceof 
NameValuePair) {
@@ -94,16 +87,12 @@ public final class ResponseBeanProcessor implements 
ResponseProcessor {
                                        }
                                } else {
                                        Header h = null;
-                                       if (o instanceof SerializedHeader)
-                                               h = 
((SerializedHeader)o).copyWith(ss, ps);
-                                       else if (o instanceof SerializedPart)
-                                               h = 
BasicHeader.of(((SerializedPart)o).copyWith(ss, ps));
-                                       else if (o instanceof Header)
+                                       if (o instanceof Header)
                                                h = (Header)o;
                                        else if (o instanceof NameValuePair)
                                                h = 
BasicHeader.of((NameValuePair)o);
                                        else
-                                               h = new SerializedHeader(n, o, 
hm.getSerializerSession().orElse(ss), ps, true);
+                                               h = new SerializedHeader(n, o, 
req.getPartSerializerSession(hm.getSerializer().orElse(defaultPartSerializer)), 
ps, true);
                                        res.addHeader(h);
                                }
                        } catch (Exception e) {

Reply via email to