juneau-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jamesbog...@apache.org
Subject juneau git commit: RestContext refactor.
Date Mon, 01 Jan 2018 15:59:33 GMT
Repository: juneau
Updated Branches:
  refs/heads/master 6ac075fc2 -> 240182f06


RestContext refactor.

Project: http://git-wip-us.apache.org/repos/asf/juneau/repo
Commit: http://git-wip-us.apache.org/repos/asf/juneau/commit/240182f0
Tree: http://git-wip-us.apache.org/repos/asf/juneau/tree/240182f0
Diff: http://git-wip-us.apache.org/repos/asf/juneau/diff/240182f0

Branch: refs/heads/master
Commit: 240182f06fcb1a6b34ba4eb33597071b3d3353f7
Parents: 6ac075f
Author: JamesBognar <jamesbognar@apache.org>
Authored: Mon Jan 1 10:59:29 2018 -0500
Committer: JamesBognar <jamesbognar@apache.org>
Committed: Mon Jan 1 10:59:29 2018 -0500

----------------------------------------------------------------------
 .../org/apache/juneau/PropertyStore2Test.java   | 256 +++++++++----------
 .../java/org/apache/juneau/BeanContext.java     |  12 +-
 .../java/org/apache/juneau/PropertyStore.java   |  20 +-
 .../org/apache/juneau/PropertyStoreBuilder.java |  52 +++-
 .../java/org/apache/juneau/PropertyType.java    |  28 +-
 .../apache/juneau/rest/client/RestClient.java   |   8 +-
 .../org/apache/juneau/rest/RestContext.java     |  68 ++++-
 .../apache/juneau/rest/RestContextBuilder.java  | 222 +++++++++-------
 .../org/apache/juneau/rest/RestResponse.java    |   4 +-
 .../juneau/rest/annotation/RestMethod.java      |  44 ++--
 .../juneau/rest/annotation/RestResource.java    |  86 ++++---
 11 files changed, 464 insertions(+), 336 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/juneau/blob/240182f0/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/PropertyStore2Test.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/PropertyStore2Test.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/PropertyStore2Test.java
index e524471..1aff36d 100644
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/PropertyStore2Test.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/PropertyStore2Test.java
@@ -767,40 +767,40 @@ public class PropertyStore2Test {
 	public void testMapString() throws Exception {
 		PropertyStoreBuilder b = PropertyStore.create();
 		PropertyStore ps = null;
-		b.set("A.f1.ms", new AMap<String,String>().append("foo", "bar").append("baz", "qux").append("quux", null).append(null, null));  
-		b.set("A.f2.ms", new AMap<String,Object>().append("foo", 123).append("bar", true).append("baz", TestEnum.ONE).append("qux", null));  
-		b.set("A.f3.ms", new AMap<String,StringBuilder>().append("foo", new StringBuilder("bar")).append("baz", null));  
-		b.set("A.f4.ms", "{foo:'bar',baz:123,qux:true}");  
-		b.set("A.f5.ms", null);
+		b.set("A.f1.sms", new AMap<String,String>().append("foo", "bar").append("baz", "qux").append("quux", null).append(null, null));  
+		b.set("A.f2.sms", new AMap<String,Object>().append("foo", 123).append("bar", true).append("baz", TestEnum.ONE).append("qux", null));  
+		b.set("A.f3.sms", new AMap<String,StringBuilder>().append("foo", new StringBuilder("bar")).append("baz", null));  
+		b.set("A.f4.sms", "{foo:'bar',baz:123,qux:true}");  
+		b.set("A.f5.sms", null);
 		ps = b.build();
-		assertObjectEquals("{A:{'f1.ms':{baz:'qux',foo:'bar'},'f2.ms':{bar:'true',baz:'ONE',foo:'123'},'f3.ms':{foo:'bar'},'f4.ms':{baz:'123',foo:'bar',qux:'true'}}}", ps);
-		assertType(Map.class, ps.getProperty("A.f1.ms"));
-		assertType(Map.class, ps.getProperty("A.f2.ms"));
-		assertType(Map.class, ps.getProperty("A.f3.ms"));
-		assertType(Map.class, ps.getProperty("A.f4.ms"));
+		assertObjectEquals("{A:{'f1.sms':{baz:'qux',foo:'bar'},'f2.sms':{bar:'true',baz:'ONE',foo:'123'},'f3.sms':{foo:'bar'},'f4.sms':{baz:'123',foo:'bar',qux:'true'}}}", ps);
+		assertType(Map.class, ps.getProperty("A.f1.sms"));
+		assertType(Map.class, ps.getProperty("A.f2.sms"));
+		assertType(Map.class, ps.getProperty("A.f3.sms"));
+		assertType(Map.class, ps.getProperty("A.f4.sms"));
 
 		b.clear();
-		b.set("A.f1.ms/add", "{foo:'bar'}");  
-		assertObjectEquals("{A:{'f1.ms':{foo:'bar'}}}", b.build());
+		b.set("A.f1.sms/add", "{foo:'bar'}");  
+		assertObjectEquals("{A:{'f1.sms':{foo:'bar'}}}", b.build());
 		
 		b.clear();
-		b.set("A.f1.ms/add.foo", "bar");  
-		assertObjectEquals("{A:{'f1.ms':{foo:'bar'}}}", b.build());
-		b.set("A.f1.ms/add.foo", null);  
+		b.set("A.f1.sms/add.foo", "bar");  
+		assertObjectEquals("{A:{'f1.sms':{foo:'bar'}}}", b.build());
+		b.set("A.f1.sms/add.foo", null);  
 		assertObjectEquals("{}", b.build());
 
 		b.clear();
-		b.set("A.f1.ms", null);
+		b.set("A.f1.sms", null);
 		assertObjectEquals("{}", b.build());
 				
 		b.clear();
-		b.set("A.f1.ms", "{foo:'bar'}");
-		testError(b, "A.f1.ms/remove", "foo", "Cannot remove value 'foo' (String) from property 'f1.ms' (Map<String,String>).");
+		b.set("A.f1.sms", "{foo:'bar'}");
+		testError(b, "A.f1.sms/remove", "foo", "Cannot remove value 'foo' (String) from property 'f1.sms' (Map<String,String>).");
 		try {
-			b.removeFrom("A.f1.ms", "foo");
+			b.removeFrom("A.f1.sms", "foo");
 			fail("Exception expected.");
 		} catch (Exception e) {
-			assertEquals("Cannot remove value 'foo' (String) from property 'f1.ms' (Map<String,String>).", e.getMessage());
+			assertEquals("Cannot remove value 'foo' (String) from property 'f1.sms' (Map<String,String>).", e.getMessage());
 		}
 	}
 	
@@ -808,40 +808,40 @@ public class PropertyStore2Test {
 	public void testMapInteger() throws Exception {
 		PropertyStoreBuilder b = PropertyStore.create();
 		PropertyStore ps = null;
-		b.set("A.f1.mi", new AMap<String,String>().append("foo", "1").append("baz", "2").append("quux", null).append(null, null));  
-		b.set("A.f2.mi", new AMap<String,Object>().append("foo", 123).append("bar", "456").append("baz", null));  
-		b.set("A.f3.mi", new AMap<String,StringBuilder>().append("foo", new StringBuilder("123")).append("baz", null));  
-		b.set("A.f4.mi", "{foo:'123',baz:456,qux:null}");  
-		b.set("A.f5.mi", null);
+		b.set("A.f1.smi", new AMap<String,String>().append("foo", "1").append("baz", "2").append("quux", null).append(null, null));  
+		b.set("A.f2.smi", new AMap<String,Object>().append("foo", 123).append("bar", "456").append("baz", null));  
+		b.set("A.f3.smi", new AMap<String,StringBuilder>().append("foo", new StringBuilder("123")).append("baz", null));  
+		b.set("A.f4.smi", "{foo:'123',baz:456,qux:null}");  
+		b.set("A.f5.smi", null);
 		ps = b.build();
-		assertObjectEquals("{A:{'f1.mi':{baz:2,foo:1},'f2.mi':{bar:456,foo:123},'f3.mi':{foo:123},'f4.mi':{baz:456,foo:123}}}", ps);
-		assertType(Map.class, ps.getProperty("A.f1.mi"));
-		assertType(Map.class, ps.getProperty("A.f2.mi"));
-		assertType(Map.class, ps.getProperty("A.f3.mi"));
-		assertType(Map.class, ps.getProperty("A.f4.mi"));
+		assertObjectEquals("{A:{'f1.smi':{baz:2,foo:1},'f2.smi':{bar:456,foo:123},'f3.smi':{foo:123},'f4.smi':{baz:456,foo:123}}}", ps);
+		assertType(Map.class, ps.getProperty("A.f1.smi"));
+		assertType(Map.class, ps.getProperty("A.f2.smi"));
+		assertType(Map.class, ps.getProperty("A.f3.smi"));
+		assertType(Map.class, ps.getProperty("A.f4.smi"));
 
 		b.clear();
-		b.set("A.f1.mi/add", "{foo:'123'}");  
-		assertObjectEquals("{A:{'f1.mi':{foo:123}}}", b.build());
+		b.set("A.f1.smi/add", "{foo:'123'}");  
+		assertObjectEquals("{A:{'f1.smi':{foo:123}}}", b.build());
 		
 		b.clear();
-		b.set("A.f1.mi/add.foo", "123");  
-		assertObjectEquals("{A:{'f1.mi':{foo:123}}}", b.build());
-		b.set("A.f1.mi/add.foo", null);  
+		b.set("A.f1.smi/add.foo", "123");  
+		assertObjectEquals("{A:{'f1.smi':{foo:123}}}", b.build());
+		b.set("A.f1.smi/add.foo", null);  
 		assertObjectEquals("{}", b.build());
 
 		b.clear();
-		b.set("A.f1.mi", null);
+		b.set("A.f1.smi", null);
 		assertObjectEquals("{}", b.build());
 				
 		b.clear();
-		b.set("A.f1.mi", "{foo:'123'}");
-		testError(b, "A.f1.mi/remove", "foo", "Cannot remove value 'foo' (String) from property 'f1.mi' (Map<String,Integer>).");
+		b.set("A.f1.smi", "{foo:'123'}");
+		testError(b, "A.f1.smi/remove", "foo", "Cannot remove value 'foo' (String) from property 'f1.smi' (Map<String,Integer>).");
 		try {
-			b.removeFrom("A.f1.mi", "foo");
+			b.removeFrom("A.f1.smi", "foo");
 			fail("Exception expected.");
 		} catch (Exception e) {
-			assertEquals("Cannot remove value 'foo' (String) from property 'f1.mi' (Map<String,Integer>).", e.getMessage());
+			assertEquals("Cannot remove value 'foo' (String) from property 'f1.smi' (Map<String,Integer>).", e.getMessage());
 		}
 	}
 	
@@ -849,34 +849,34 @@ public class PropertyStore2Test {
 	public void testMapClass() throws Exception {
 		PropertyStoreBuilder b = PropertyStore.create();
 		PropertyStore ps = null;
-		b.set("A.f1.mc", new AMap<String,Class<?>>().append("foo", String.class).append("baz", Integer.class).append("quux", null).append(null, null));  
-		b.set("A.f2.mc", new AMap<String,Object>().append("foo", String.class).append("bar", Integer.class).append("baz", null));  
-		b.set("A.f3.mc", null);
+		b.set("A.f1.smc", new AMap<String,Class<?>>().append("foo", String.class).append("baz", Integer.class).append("quux", null).append(null, null));  
+		b.set("A.f2.smc", new AMap<String,Object>().append("foo", String.class).append("bar", Integer.class).append("baz", null));  
+		b.set("A.f3.smc", null);
 		ps = b.build();
-		assertObjectEquals("{A:{'f1.mc':{baz:'java.lang.Integer',foo:'java.lang.String'},'f2.mc':{bar:'java.lang.Integer',foo:'java.lang.String'}}}", ps);
-		assertType(Map.class, ps.getProperty("A.f1.mc"));
-		assertType(Map.class, ps.getProperty("A.f2.mc"));
-		assertType(Class.class, ((Map<?,?>)ps.getProperty("A.f1.mc")).values().iterator().next());
-		assertType(Class.class, ((Map<?,?>)ps.getProperty("A.f2.mc")).values().iterator().next());
+		assertObjectEquals("{A:{'f1.smc':{baz:'java.lang.Integer',foo:'java.lang.String'},'f2.smc':{bar:'java.lang.Integer',foo:'java.lang.String'}}}", ps);
+		assertType(Map.class, ps.getProperty("A.f1.smc"));
+		assertType(Map.class, ps.getProperty("A.f2.smc"));
+		assertType(Class.class, ((Map<?,?>)ps.getProperty("A.f1.smc")).values().iterator().next());
+		assertType(Class.class, ((Map<?,?>)ps.getProperty("A.f2.smc")).values().iterator().next());
 
 		b.clear();
-		b.set("A.f1.mc/add.foo", String.class);  
-		assertObjectEquals("{A:{'f1.mc':{foo:'java.lang.String'}}}", b.build());
-		b.set("A.f1.mc/add.foo", null);  
+		b.set("A.f1.smc/add.foo", String.class);  
+		assertObjectEquals("{A:{'f1.smc':{foo:'java.lang.String'}}}", b.build());
+		b.set("A.f1.smc/add.foo", null);  
 		assertObjectEquals("{}", b.build());
 
 		b.clear();
-		b.set("A.f1.mc", null);
+		b.set("A.f1.smc", null);
 		assertObjectEquals("{}", b.build());
 				
 		b.clear();
-		b.set("A.f1.mc/add.foo", String.class);  
-		testError(b, "A.f1.mc/remove", "foo", "Cannot remove value 'foo' (String) from property 'f1.mc' (Map<String,Class>).");
+		b.set("A.f1.smc/add.foo", String.class);  
+		testError(b, "A.f1.smc/remove", "foo", "Cannot remove value 'foo' (String) from property 'f1.smc' (Map<String,Class>).");
 		try {
-			b.removeFrom("A.f1.mc", "foo");
+			b.removeFrom("A.f1.smc", "foo");
 			fail("Exception expected.");
 		} catch (Exception e) {
-			assertEquals("Cannot remove value 'foo' (String) from property 'f1.mc' (Map<String,Class>).", e.getMessage());
+			assertEquals("Cannot remove value 'foo' (String) from property 'f1.smc' (Map<String,Class>).", e.getMessage());
 		}
 	}
 	
@@ -885,40 +885,40 @@ public class PropertyStore2Test {
 		PropertyStoreBuilder b = PropertyStore.create();
 		
 		PropertyStore ps = null;
-		b.set("A.f1.mo", new AMap<String,String>().append("foo", "1").append("baz", "2").append("quux", null).append(null, null));  
-		b.set("A.f2.mo", new AMap<String,Object>().append("foo", 123).append("bar", StringBuilder.class).append("qux", null));  
-		b.set("A.f3.mo", new AMap<String,StringBuilder>().append("foo", new StringBuilder("123")).append("baz", null));  
-		b.set("A.f4.mo", "{foo:'123',baz:456,qux:null}");  
-		b.set("A.f5.mo", null);
+		b.set("A.f1.smo", new AMap<String,String>().append("foo", "1").append("baz", "2").append("quux", null).append(null, null));  
+		b.set("A.f2.smo", new AMap<String,Object>().append("foo", 123).append("bar", StringBuilder.class).append("qux", null));  
+		b.set("A.f3.smo", new AMap<String,StringBuilder>().append("foo", new StringBuilder("123")).append("baz", null));  
+		b.set("A.f4.smo", "{foo:'123',baz:456,qux:null}");  
+		b.set("A.f5.smo", null);
 		ps = b.build();
-		assertObjectEquals("{A:{'f1.mo':{baz:'2',foo:'1'},'f2.mo':{bar:'java.lang.StringBuilder',foo:123},'f3.mo':{foo:'123'},'f4.mo':{baz:456,foo:'123'}}}", ps);
-		assertType(Map.class, ps.getProperty("A.f1.mo"));
-		assertType(Map.class, ps.getProperty("A.f2.mo"));
-		assertType(Map.class, ps.getProperty("A.f3.mo"));
-		assertType(Map.class, ps.getProperty("A.f4.mo"));
+		assertObjectEquals("{A:{'f1.smo':{baz:'2',foo:'1'},'f2.smo':{bar:'java.lang.StringBuilder',foo:123},'f3.smo':{foo:'123'},'f4.smo':{baz:456,foo:'123'}}}", ps);
+		assertType(Map.class, ps.getProperty("A.f1.smo"));
+		assertType(Map.class, ps.getProperty("A.f2.smo"));
+		assertType(Map.class, ps.getProperty("A.f3.smo"));
+		assertType(Map.class, ps.getProperty("A.f4.smo"));
 
 		b.clear();
-		b.set("A.f1.mo/add", "{foo:'123'}");  
-		assertObjectEquals("{A:{'f1.mo':{foo:'123'}}}", b.build());
+		b.set("A.f1.smo/add", "{foo:'123'}");  
+		assertObjectEquals("{A:{'f1.smo':{foo:'123'}}}", b.build());
 		
 		b.clear();
-		b.set("A.f1.mo/add.foo", "123");  
-		assertObjectEquals("{A:{'f1.mo':{foo:'123'}}}", b.build());
-		b.set("A.f1.mo/add.foo", null);  
+		b.set("A.f1.smo/add.foo", "123");  
+		assertObjectEquals("{A:{'f1.smo':{foo:'123'}}}", b.build());
+		b.set("A.f1.smo/add.foo", null);  
 		assertObjectEquals("{}", b.build());
 
 		b.clear();
-		b.set("A.f1.mo", null);
+		b.set("A.f1.smo", null);
 		assertObjectEquals("{}", b.build());
 				
 		b.clear();
-		b.set("A.f1.mo", "{foo:'123'}");
-		testError(b, "A.f1.mo/remove", "foo", "Cannot remove value 'foo' (String) from property 'f1.mo' (Map<String,Object>).");
+		b.set("A.f1.smo", "{foo:'123'}");
+		testError(b, "A.f1.smo/remove", "foo", "Cannot remove value 'foo' (String) from property 'f1.smo' (Map<String,Object>).");
 		try {
-			b.removeFrom("A.f1.mo", "foo");
+			b.removeFrom("A.f1.smo", "foo");
 			fail("Exception expected.");
 		} catch (Exception e) {
-			assertEquals("Cannot remove value 'foo' (String) from property 'f1.mo' (Map<String,Object>).", e.getMessage());
+			assertEquals("Cannot remove value 'foo' (String) from property 'f1.smo' (Map<String,Object>).", e.getMessage());
 		}
 	}
 	
@@ -1304,25 +1304,25 @@ public class PropertyStore2Test {
 		PropertyStoreBuilder b1 = PropertyStore.create(), b2 = PropertyStore.create();
 		PropertyStore ps = null;
 		
-		b1.set("A.f1.ms", new AMap<String,String>().append("foo", "123").append("bar", "true").append("baz", null).append(null, null));
-		b2.set("A.f1.ms", new AMap<String,Object>().append("foo", 123).append("bar", true).append("baz", null).append(null, null));
+		b1.set("A.f1.sms", new AMap<String,String>().append("foo", "123").append("bar", "true").append("baz", null).append(null, null));
+		b2.set("A.f1.sms", new AMap<String,Object>().append("foo", 123).append("bar", true).append("baz", null).append(null, null));
 		testEquals(b1, b2);
 
-		b2.set("A.f1.ms", new AMap<String,Object>().append("foo", new StringBuilder("123")).append("bar", new StringBuilder("true")));
+		b2.set("A.f1.sms", new AMap<String,Object>().append("foo", new StringBuilder("123")).append("bar", new StringBuilder("true")));
 		testEquals(b1, b2);
 
-		b2.set("A.f1.ms", new AMap<String,Object>().append("bar", new StringBuilder("true")).append("foo", new StringBuilder("123")));
+		b2.set("A.f1.sms", new AMap<String,Object>().append("bar", new StringBuilder("true")).append("foo", new StringBuilder("123")));
 		testEquals(b1, b2);
 		
-		b2.set("A.f1.ms", new AMap<String,Object>().append("bar", false).append("foo", new StringBuilder("123")));
+		b2.set("A.f1.sms", new AMap<String,Object>().append("bar", false).append("foo", new StringBuilder("123")));
 		testNotEquals(b1, b2);
 
-		b1.set("A.f1.ms", "{foo:'bar'}");
+		b1.set("A.f1.sms", "{foo:'bar'}");
 		ps = b1.build();
-		b1.set("A.f1.ms", "{foo:'bar'}");
+		b1.set("A.f1.sms", "{foo:'bar'}");
 		assertTrue(ps == b1.build());
 
-		b1.set("A.f1.ms", "{foo:'baz'}");
+		b1.set("A.f1.sms", "{foo:'baz'}");
 		assertTrue(ps != b1.build());
 		
 		b1.clear();
@@ -1335,25 +1335,25 @@ public class PropertyStore2Test {
 		PropertyStoreBuilder b1 = PropertyStore.create(), b2 = PropertyStore.create();
 		PropertyStore ps = null;
 		
-		b1.set("A.f1.mi", new AMap<String,Integer>().append("foo", 123).append("bar", 456).append("baz", null).append(null, null));
-		b2.set("A.f1.mi", new AMap<String,Object>().append("foo", 123).append("bar", "456").append("baz", null).append(null, null));
+		b1.set("A.f1.smi", new AMap<String,Integer>().append("foo", 123).append("bar", 456).append("baz", null).append(null, null));
+		b2.set("A.f1.smi", new AMap<String,Object>().append("foo", 123).append("bar", "456").append("baz", null).append(null, null));
 		testEquals(b1, b2);
 
-		b2.set("A.f1.mi", new AMap<String,Object>().append("foo", new StringBuilder("123")).append("bar", new StringBuilder("456")));
+		b2.set("A.f1.smi", new AMap<String,Object>().append("foo", new StringBuilder("123")).append("bar", new StringBuilder("456")));
 		testEquals(b1, b2);
 
-		b2.set("A.f1.mi", new AMap<String,Object>().append("bar", new StringBuilder("456")).append("foo", new StringBuilder("123")));
+		b2.set("A.f1.smi", new AMap<String,Object>().append("bar", new StringBuilder("456")).append("foo", new StringBuilder("123")));
 		testEquals(b1, b2);
 		
-		b2.set("A.f1.mi", new AMap<String,Object>().append("bar", "457").append("foo", new StringBuilder("123")));
+		b2.set("A.f1.smi", new AMap<String,Object>().append("bar", "457").append("foo", new StringBuilder("123")));
 		testNotEquals(b1, b2);
 
-		b1.set("A.f1.mi", "{foo:'123'}");
+		b1.set("A.f1.smi", "{foo:'123'}");
 		ps = b1.build();
-		b1.set("A.f1.mi", "{foo:'123'}");
+		b1.set("A.f1.smi", "{foo:'123'}");
 		assertTrue(ps == b1.build());
 
-		b1.set("A.f1.mi", "{foo:'456'}");
+		b1.set("A.f1.smi", "{foo:'456'}");
 		assertTrue(ps != b1.build());
 		
 		b1.clear();
@@ -1366,26 +1366,26 @@ public class PropertyStore2Test {
 		PropertyStoreBuilder b1 = PropertyStore.create(), b2 = PropertyStore.create();
 		PropertyStore ps = null;
 		
-		b1.set("A.f1.mc", new AMap<String,Class<?>>().append("foo", String.class).append("bar", Integer.class).append("baz", null).append(null, null));
-		b2.set("A.f1.mc", new AMap<String,Object>().append("foo", String.class).append("bar", Integer.class).append("baz", null).append(null, null));
+		b1.set("A.f1.smc", new AMap<String,Class<?>>().append("foo", String.class).append("bar", Integer.class).append("baz", null).append(null, null));
+		b2.set("A.f1.smc", new AMap<String,Object>().append("foo", String.class).append("bar", Integer.class).append("baz", null).append(null, null));
 		testEquals(b1, b2);
 
-		b2.set("A.f1.mc", new AMap<String,Object>().append("foo", String.class).append("bar", Integer.class));
+		b2.set("A.f1.smc", new AMap<String,Object>().append("foo", String.class).append("bar", Integer.class));
 		testEquals(b1, b2);
 
-		b2.set("A.f1.mc", new AMap<String,Object>().append("bar", Integer.class).append("foo", String.class));
+		b2.set("A.f1.smc", new AMap<String,Object>().append("bar", Integer.class).append("foo", String.class));
 		testEquals(b1, b2);
 		
-		b2.set("A.f1.mc", new AMap<String,Object>().append("bar", Integer.class).append("foo", StringBuilder.class));
+		b2.set("A.f1.smc", new AMap<String,Object>().append("bar", Integer.class).append("foo", StringBuilder.class));
 		testNotEquals(b1, b2);
 
 		b1.clear();
-		b1.set("A.f1.mc/add.foo", Integer.class);
+		b1.set("A.f1.smc/add.foo", Integer.class);
 		ps = b1.build();
-		b1.set("A.f1.mc/add.foo", Integer.class);
+		b1.set("A.f1.smc/add.foo", Integer.class);
 		assertTrue(ps == b1.build());
 
-		b1.set("A.f1.mc/add.foo", String.class);
+		b1.set("A.f1.smc/add.foo", String.class);
 		assertTrue(ps != b1.build());
 		
 		b1.clear();
@@ -1398,26 +1398,26 @@ public class PropertyStore2Test {
 		PropertyStoreBuilder b1 = PropertyStore.create(), b2 = PropertyStore.create();
 		PropertyStore ps = null;
 		
-		b1.set("A.f1.mo", new AMap<String,TestEnum>().append("foo", TestEnum.ONE).append("bar", TestEnum.TWO).append("baz", null).append(null, null));
-		b2.set("A.f1.mo", new AMap<String,Object>().append("foo", TestEnum.ONE).append("bar", TestEnum.TWO).append("baz", null).append(null, null));
+		b1.set("A.f1.smo", new AMap<String,TestEnum>().append("foo", TestEnum.ONE).append("bar", TestEnum.TWO).append("baz", null).append(null, null));
+		b2.set("A.f1.smo", new AMap<String,Object>().append("foo", TestEnum.ONE).append("bar", TestEnum.TWO).append("baz", null).append(null, null));
 		testEquals(b1, b2);
 
-		b2.set("A.f1.mo", new AMap<String,Object>().append("foo", TestEnum.ONE).append("bar", TestEnum.TWO));
+		b2.set("A.f1.smo", new AMap<String,Object>().append("foo", TestEnum.ONE).append("bar", TestEnum.TWO));
 		testEquals(b1, b2);
 
-		b2.set("A.f1.mo", new AMap<String,Object>().append("bar", TestEnum.TWO).append("foo", TestEnum.ONE));
+		b2.set("A.f1.smo", new AMap<String,Object>().append("bar", TestEnum.TWO).append("foo", TestEnum.ONE));
 		testEquals(b1, b2);
 		
-		b2.set("A.f1.mo", new AMap<String,Object>().append("bar", TestEnum.ONE).append("foo", TestEnum.TWO));
+		b2.set("A.f1.smo", new AMap<String,Object>().append("bar", TestEnum.ONE).append("foo", TestEnum.TWO));
 		testNotEquals(b1, b2);
 
 		b1.clear();
-		b1.set("A.f1.mo/add.foo", TestEnum.ONE);
+		b1.set("A.f1.smo/add.foo", TestEnum.ONE);
 		ps = b1.build();
-		b1.set("A.f1.mo/add.foo", TestEnum.ONE);
+		b1.set("A.f1.smo/add.foo", TestEnum.ONE);
 		assertTrue(ps == b1.build());
 
-		b1.set("A.f1.mo/add.foo", TestEnum.TWO);
+		b1.set("A.f1.smo/add.foo", TestEnum.TWO);
 		assertTrue(ps != b1.build());
 		
 		b1.clear();
@@ -1498,27 +1498,27 @@ public class PropertyStore2Test {
 	public void testMapStringDefault() {
 		PropertyStore ps = PropertyStore.create().build();
 		
-		System.setProperty("A.f1.ms", "{foo:'bar',baz:null}");		
-		assertObjectEquals("{foo:'bar'}", ps.getProperty("A.f1.ms"));
-		System.clearProperty("A.f1.ms");
+		System.setProperty("A.f1.sms", "{foo:'bar',baz:null}");		
+		assertObjectEquals("{foo:'bar'}", ps.getProperty("A.f1.sms"));
+		System.clearProperty("A.f1.sms");
 	}
 	
 	@Test
 	public void testMapIntegerDefault() {
 		PropertyStore ps = PropertyStore.create().build();
 		
-		System.setProperty("A.f1.mi", "{foo:'123',baz:null}");		
-		assertObjectEquals("{foo:123}", ps.getProperty("A.f1.mi"));
-		System.clearProperty("A.f1.mi");
+		System.setProperty("A.f1.smi", "{foo:'123',baz:null}");		
+		assertObjectEquals("{foo:123}", ps.getProperty("A.f1.smi"));
+		System.clearProperty("A.f1.smi");
 	}
 
 	@Test
 	public void testMapObjectDefault() {
 		PropertyStore ps = PropertyStore.create().build();
 		
-		System.setProperty("A.f1.mo", "{foo:123,bar:'baz',qux:true,quux:null}");		
-		assertObjectEquals("{bar:'baz',foo:123,qux:true}", ps.getProperty("A.f1.mo"));
-		System.clearProperty("A.f1.mo");
+		System.setProperty("A.f1.smo", "{foo:123,bar:'baz',qux:true,quux:null}");		
+		assertObjectEquals("{bar:'baz',foo:123,qux:true}", ps.getProperty("A.f1.smo"));
+		System.clearProperty("A.f1.smo");
 	}
 
 	//-------------------------------------------------------------------------------------------------------------------
@@ -1598,22 +1598,22 @@ public class PropertyStore2Test {
 	public void testAddToInvalidObjectMap() {
 		PropertyStoreBuilder b = PropertyStore.create();
 		try {
-			b.addTo("A.foo.ms", "{xxx}");
+			b.addTo("A.foo.sms", "{xxx}");
 			fail("Exception expected.");
 		} catch (ConfigException e) {
-			assertEquals("Cannot add '{xxx}' (java.lang.String) to property 'foo.ms' (Map<String,String>) because it's not a valid JSON object.", e.getMessage());
+			assertEquals("Cannot add '{xxx}' (java.lang.String) to property 'foo.sms' (Map<String,String>) because it's not a valid JSON object.", e.getMessage());
 		}
 		try {
-			b.addTo("A.foo.ms", "xxx");
+			b.addTo("A.foo.sms", "xxx");
 			fail("Exception expected.");
 		} catch (ConfigException e) {
-			assertEquals("Cannot add 'xxx' (java.lang.String) to property 'foo.ms' (Map<String,String>).", e.getMessage());
+			assertEquals("Cannot add 'xxx' (java.lang.String) to property 'foo.sms' (Map<String,String>).", e.getMessage());
 		}
 		try {
-			b.addTo("A.foo.ms", new StringBuilder("foo"));
+			b.addTo("A.foo.sms", new StringBuilder("foo"));
 			fail("Exception expected.");
 		} catch (ConfigException e) {
-			assertEquals("Cannot add 'foo' (java.lang.StringBuilder) to property 'foo.ms' (Map<String,String>).", e.getMessage());
+			assertEquals("Cannot add 'foo' (java.lang.StringBuilder) to property 'foo.sms' (Map<String,String>).", e.getMessage());
 		}
 	}
 
@@ -1687,16 +1687,16 @@ public class PropertyStore2Test {
 		b.set("A.foo.li", "[123]");
 		b.set("A.foo.lc/add", String.class);
 		b.set("A.foo.lo/add", StringBuilder.class);
-		b.set("A.foo.ms", "{foo:'bar'}");
-		b.set("A.foo.mi", "{foo:123}");
-		b.set("A.foo.mc/add.foo", String.class);
-		b.set("A.foo.mo/add.foo", StringBuilder.class);
+		b.set("A.foo.sms", "{foo:'bar'}");
+		b.set("A.foo.smi", "{foo:123}");
+		b.set("A.foo.smc/add.foo", String.class);
+		b.set("A.foo.smo/add.foo", StringBuilder.class);
 		PropertyStore ps = b.build();
 		
 		b = ps.builder();
 		ps = b.build();
 		
-		assertObjectEquals("{A:{'foo.b':true,'foo.c':'java.lang.String','foo.i':123,'foo.lc':['java.lang.String'],'foo.li':[123],'foo.lo':['java.lang.StringBuilder'],'foo.ls':['bar'],'foo.mc':{foo:'java.lang.String'},'foo.mi':{foo:123},'foo.mo':{foo:'java.lang.StringBuilder'},'foo.ms':{foo:'bar'},'foo.o':'bar','foo.s':'bar','foo.sc':['java.lang.String'],'foo.si':[123],'foo.ss':['bar']}}", ps);
+		assertObjectEquals("{A:{'foo.b':true,'foo.c':'java.lang.String','foo.i':123,'foo.lc':['java.lang.String'],'foo.li':[123],'foo.lo':['java.lang.StringBuilder'],'foo.ls':['bar'],'foo.o':'bar','foo.s':'bar','foo.sc':['java.lang.String'],'foo.si':[123],'foo.smc':{foo:'java.lang.String'},'foo.smi':{foo:123},'foo.smo':{foo:'java.lang.StringBuilder'},'foo.sms':{foo:'bar'},'foo.ss':['bar']}}", ps);
 	}
 
 	@Test

http://git-wip-us.apache.org/repos/asf/juneau/blob/240182f0/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
index a0779f4..9abda9e 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
@@ -660,7 +660,7 @@ public class BeanContext extends Context {
 	 * <b>Configuration property:</b>  Implementation classes for interfaces and abstract classes.
 	 *
 	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.implClasses.mc"</js>
+	 * 	<li><b>Name:</b> <js>"BeanContext.implClasses.smc"</js>
 	 * 	<li><b>Data type:</b> <code>Map&lt;String,Class&gt;</code>
 	 * 	<li><b>Default:</b> empty map
 	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
@@ -671,13 +671,13 @@ public class BeanContext extends Context {
 	 * interface/abstract class so that instances of the implementation class are used when instantiated (e.g. during a
 	 * parse).
 	 */
-	public static final String BEAN_implClasses = PREFIX + "implClasses.mc";
+	public static final String BEAN_implClasses = PREFIX + "implClasses.smc";
 
 	/**
 	 * <b>Configuration property:</b>  Explicitly specify visible bean properties.
 	 *
 	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.includeProperties.ms"</js>
+	 * 	<li><b>Name:</b> <js>"BeanContext.includeProperties.sms"</js>
 	 * 	<li><b>Data type:</b> <code>Map&lt;String,String&gt;</code>
 	 * 	<li><b>Default:</b> <code>{}</code>
 	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
@@ -698,13 +698,13 @@ public class BeanContext extends Context {
 	 * <p>
 	 * Setting applies to specified class and all subclasses.
 	 */
-	public static final String BEAN_includeProperties = PREFIX + "includeProperties.ms";
+	public static final String BEAN_includeProperties = PREFIX + "includeProperties.sms";
 
 	/**
 	 * <b>Configuration property:</b>  Exclude specified properties from beans.
 	 *
 	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.excludeProperties.ms"</js>
+	 * 	<li><b>Name:</b> <js>"BeanContext.excludeProperties.sms"</js>
 	 * 	<li><b>Data type:</b> <code>Map&lt;String,String&gt;</code>
 	 * 	<li><b>Default:</b> <code>{}</code>
 	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
@@ -725,7 +725,7 @@ public class BeanContext extends Context {
 	 * <p>
 	 * Setting applies to specified class and all subclasses.
 	 */
-	public static final String BEAN_excludeProperties = PREFIX + "excludeProperties.ms";
+	public static final String BEAN_excludeProperties = PREFIX + "excludeProperties.sms";
 
 	/**
 	 * <b>Configuration property:</b>  Bean lookup dictionary.

http://git-wip-us.apache.org/repos/asf/juneau/blob/240182f0/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStore.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStore.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStore.java
index 39700e0..de05bdc 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStore.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStore.java
@@ -661,10 +661,14 @@ public final class PropertyStore {
 				case LIST_INTEGER:
 				case LIST_CLASS: 
 				case LIST_OBJECT: return new MutableListProperty(name, type, value);
-				case MAP_STRING: 
-				case MAP_INTEGER: 
-				case MAP_CLASS: 
-				case MAP_OBJECT: return new MutableMapProperty(name, type, value);
+				case SORTED_MAP_STRING: 
+				case SORTED_MAP_INTEGER: 
+				case SORTED_MAP_CLASS: 
+				case SORTED_MAP_OBJECT: return new MutableMapProperty(name, type, value);
+				case ORDERED_MAP_STRING: 
+				case ORDERED_MAP_INTEGER: 
+				case ORDERED_MAP_CLASS: 
+				case ORDERED_MAP_OBJECT: return new MutableLinkedMapProperty(name, type, value);
 			}
 			throw new ConfigException("Invalid type specified: ''{0}''", type);
 		}
@@ -743,9 +747,13 @@ public final class PropertyStore {
 		}
 
 		public <T> Map<String,T> asMap(Class<T> eType) {
-			if (type == MAP_STRING && eType == String.class || type == MAP_INTEGER && eType == Integer.class || type == MAP_CLASS && eType == Class.class || type == MAP_OBJECT) {
+			if (
+				eType == String.class && (type == SORTED_MAP_STRING || type == ORDERED_MAP_STRING) 
+				|| eType == Integer.class && (type == SORTED_MAP_INTEGER || type == ORDERED_MAP_INTEGER) 
+				|| eType == Class.class && (type == SORTED_MAP_CLASS || type == ORDERED_MAP_CLASS) 
+				|| (type == SORTED_MAP_OBJECT || type == ORDERED_MAP_OBJECT)) {
 				return (Map<String,T>)value;
-			} else if (type == MAP_STRING) {
+			} else if (type == SORTED_MAP_STRING || type == ORDERED_MAP_STRING) {
 				Map<String,T> m = new LinkedHashMap<>();
 				for (Map.Entry<String,String> e : ((Map<String,String>)value).entrySet()) {
 					T t = ClassUtils.fromString(eType, e.getValue());

http://git-wip-us.apache.org/repos/asf/juneau/blob/240182f0/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStoreBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStoreBuilder.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStoreBuilder.java
index a2b7267..9400dde 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStoreBuilder.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStoreBuilder.java
@@ -441,10 +441,14 @@ public class PropertyStoreBuilder {
 				case LIST_INTEGER:
 				case LIST_CLASS:
 				case LIST_OBJECT: return new MutableListProperty(name, pt, value);
-				case MAP_STRING:
-				case MAP_INTEGER:
-				case MAP_CLASS:
-				case MAP_OBJECT: return new MutableMapProperty(name, pt, value);
+				case SORTED_MAP_STRING:
+				case SORTED_MAP_INTEGER:
+				case SORTED_MAP_CLASS:
+				case SORTED_MAP_OBJECT: return new MutableMapProperty(name, pt, value);
+				case ORDERED_MAP_STRING:
+				case ORDERED_MAP_INTEGER:
+				case ORDERED_MAP_CLASS:
+				case ORDERED_MAP_OBJECT: return new MutableLinkedMapProperty(name, pt, value);
 				default: return new MutableSimpleProperty(name, PropertyType.STRING, value);
 			}
 		}
@@ -730,21 +734,26 @@ public class PropertyStoreBuilder {
 
 	@SuppressWarnings("rawtypes")
 	static class MutableMapProperty extends MutableProperty {
-		private Map<String,Object> value = new ConcurrentHashMap<>();
+		protected Map<String,Object> map;
 		
 		MutableMapProperty(String name, PropertyType type, Object value) {
 			super(name, type);
+			this.map = createMap();
 			set(value);
 		}
 		
+		protected Map<String,Object> createMap() {
+			return new ConcurrentHashMap<>();
+		}
+		
 		@Override /* MutableProperty */
 		synchronized Property build() {
-			return new Property(name, Collections.unmodifiableMap(new TreeMap<>(value)), type);
+			return new Property(name, Collections.unmodifiableMap(new TreeMap<>(map)), type);
 		}
 
 		@Override /* MutableProperty */
 		synchronized void set(Object value) {
-			this.value.clear();
+			this.map.clear();
 			add(null, value);
 		}
 
@@ -760,9 +769,9 @@ public class PropertyStoreBuilder {
 			if (arg != null) {
 				value = convert(value);
 				if (value == null)
-					this.value.remove(arg);
+					this.map.remove(arg);
 				else
-					this.value.put(arg, value);
+					this.map.put(arg, value);
 				
 			} else if (value != null) {
 				if (value instanceof Map) {
@@ -790,15 +799,36 @@ public class PropertyStoreBuilder {
 
 		@Override /* MutableProperty */
 		synchronized boolean isEmpty() {
-			return this.value.isEmpty();
+			return this.map.isEmpty();
 		}
 
 		@Override /* MutableProperty */
 		synchronized Object peek() {
-			return value;
+			return map;
 		}
 	}
 	
+	//-------------------------------------------------------------------------------------------------------------------
+	// MutableLinkedMapProperty
+	//-------------------------------------------------------------------------------------------------------------------
+	
+	static class MutableLinkedMapProperty extends MutableMapProperty {
+		
+		MutableLinkedMapProperty(String name, PropertyType type, Object value) {
+			super(name, type, value);
+			set(value);
+		}
+		
+		@Override
+		protected Map<String,Object> createMap() {
+			return Collections.synchronizedMap(new LinkedHashMap<String,Object>());
+		}
+		
+		@Override /* MutableProperty */
+		synchronized Property build() {
+			return new Property(name, Collections.unmodifiableMap(new LinkedHashMap<>(map)), type);
+		}
+	}
 	
 	//-------------------------------------------------------------------------------------------------------------------
 	// Utility methods

http://git-wip-us.apache.org/repos/asf/juneau/blob/240182f0/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyType.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyType.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyType.java
index a0d352c..167d2d1 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyType.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyType.java
@@ -58,18 +58,30 @@ public enum PropertyType {
 	/** List&lt;Object&gt; */
 	LIST_OBJECT("List<Object>", "lo", OBJECT_CONVERTER),
 
-	/** Map&lt;String,String&gt; */
-	MAP_STRING("Map<String,String>", "ms", STRING_CONVERTER), 
+	/** TreeMap&lt;String,String&gt; */
+	SORTED_MAP_STRING("Map<String,String>", "sms", STRING_CONVERTER), 
 
-	/** Map&lt;String,Integer&gt; */
-	MAP_INTEGER("Map<String,Integer>", "mi", INTEGER_CONVERTER), 
+	/** TreeMap&lt;String,Integer&gt; */
+	SORTED_MAP_INTEGER("Map<String,Integer>", "smi", INTEGER_CONVERTER), 
 
-	/** Map&lt;String,Class&gt; */
-	MAP_CLASS("Map<String,Class>", "mc", CLASS_CONVERTER),
+	/** TreeMap&lt;String,Class&gt; */
+	SORTED_MAP_CLASS("Map<String,Class>", "smc", CLASS_CONVERTER),
 
-	/** Map&lt;String,Object&gt; */
-	MAP_OBJECT("Map<String,Object>", "mo", OBJECT_CONVERTER);
+	/** TreeMap&lt;String,Object&gt; */
+	SORTED_MAP_OBJECT("Map<String,Object>", "smo", OBJECT_CONVERTER),
 	
+	/** LinkedHashMap&lt;String,String&gt; */
+	ORDERED_MAP_STRING("Map<String,String>", "oms", STRING_CONVERTER), 
+
+	/** LinkedHashMap&lt;String,Integer&gt; */
+	ORDERED_MAP_INTEGER("Map<String,Integer>", "omi", INTEGER_CONVERTER), 
+
+	/** LinkedHashMap&lt;String,Class&gt; */
+	ORDERED_MAP_CLASS("Map<String,Class>", "omc", CLASS_CONVERTER),
+
+	/** LinkedHashMap&lt;String,Object&gt; */
+	ORDERED_MAP_OBJECT("Map<String,Object>", "omo", OBJECT_CONVERTER);
+
 	private final String type, suffix;
 	final PropertyConverter<?> converter;
 	

http://git-wip-us.apache.org/repos/asf/juneau/blob/240182f0/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
----------------------------------------------------------------------
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 4a5c67a..829f9af 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
@@ -162,7 +162,7 @@ public class RestClient extends BeanContext {
 	 * <b>Configuration property:</b>  Request headers.
 	 *
 	 * <ul>
-	 * 	<li><b>Name:</b> <js>"RestClient.requestHeader.ms"</js>
+	 * 	<li><b>Name:</b> <js>"RestClient.requestHeader.sms"</js>
 	 * 	<li><b>Data type:</b> <code>Map&lt;String,String&gt;</code>
 	 * 	<li><b>Default:</b> empty map
 	 * </ul>
@@ -170,13 +170,13 @@ public class RestClient extends BeanContext {
 	 * <p>
 	 * Headers to add to every request.
 	 */
-	public static final String RESTCLIENT_headers = PREFIX + "headers.ms";
+	public static final String RESTCLIENT_headers = PREFIX + "headers.sms";
 
 	/**
 	 * <b>Configuration property:</b>  Request query parameters.
 	 *
 	 * <ul>
-	 * 	<li><b>Name:</b> <js>"RestClient.query.ms"</js>
+	 * 	<li><b>Name:</b> <js>"RestClient.query.sms"</js>
 	 * 	<li><b>Data type:</b> <code>Map&lt;String,String&gt;</code>
 	 * 	<li><b>Default:</b> empty map
 	 * </ul>
@@ -184,7 +184,7 @@ public class RestClient extends BeanContext {
 	 * <p>
 	 * Query parameters to add to every request.
 	 */
-	public static final String RESTCLIENT_query = PREFIX + "query.ms";
+	public static final String RESTCLIENT_query = PREFIX + "query.sms";
 
 	/**
 	 * <b>Configuration property:</b>  Serializer.

http://git-wip-us.apache.org/repos/asf/juneau/blob/240182f0/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
----------------------------------------------------------------------
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 9b55f39..40e4741 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
@@ -387,6 +387,57 @@ public final class RestContext extends BeanContext {
 	 */
 	public static final String REST_responseHandlers = PREFIX + "responseHandlers.lo";
 
+	/**
+	 * <b>Configuration property:</b>  Default request headers.
+	 *
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"RestContext.defaultRequestHeaders.sms"</js>
+	 * 	<li><b>Data type:</b> <code>Map&lt;String,String&gt;</code>
+	 * 	<li><b>Default:</b> empty map
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * 
+	 * <p>
+	 * Specifies default values for request headers.
+	 *
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li>Property: {@link RestContext#REST_defaultRequestHeaders}
+	 * 	<li>Annotation:  {@link RestResource#defaultRequestHeaders()} / {@link RestMethod#defaultRequestHeaders()} 
+	 * 	<li>Method: {@link RestContextBuilder#defaultRequestHeader(String,Object)} / {@link RestContextBuilder#defaultRequestHeaders(String...)}
+	 * 	<li>Affects values returned by {@link RestRequest#getHeader(String)} when the header is not present on the request.
+	 * 	<li>The most useful reason for this annotation is to provide a default <code>Accept</code> header when one is not
+	 * 		specified so that a particular default {@link Serializer} is picked.
+	 *	</ul>
+	 */
+	public static final String REST_defaultRequestHeaders = PREFIX + "defaultRequestHeaders.sms";
+
+	/**
+	 * <b>Configuration property:</b>  Default response headers.
+	 *
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"RestContext.defaultResponseHeaders.oms"</js>
+	 * 	<li><b>Data type:</b> <code>Map&lt;String,String&gt;</code>
+	 * 	<li><b>Default:</b> empty map
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * 
+	 * <p>
+	 * Specifies default values for response headers.
+	 *
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li>Property: {@link RestContext#REST_defaultResponseHeaders}
+	 * 	<li>Annotation:  {@link RestResource#defaultResponseHeaders()} 
+	 * 	<li>Method: {@link RestContextBuilder#defaultResponseHeader(String,Object)} / {@link RestContextBuilder#defaultResponseHeaders(String...)}
+	 * 	<li>This is equivalent to calling {@link RestResponse#setHeader(String, String)} programmatically in each of 
+	 * 		the Java methods.
+	 * 	<li>The header value will not be set if the header value has already been specified (hence the 'default' in the name).
+	 *	</ul>
+	 */
+	public static final String REST_defaultResponseHeaders = PREFIX + "defaultResponseHeaders.oms";
 
 	//-------------------------------------------------------------------------------------------------------------------
 	// Instance
@@ -422,8 +473,7 @@ public final class RestContext extends BeanContext {
 	private final MediaType[]
 		supportedContentTypes,
 		supportedAcceptTypes;
-	private final Map<String,String> defaultRequestHeaders;
-	private final Map<String,Object> defaultResponseHeaders;
+	private final Map<String,String> defaultRequestHeaders, defaultResponseHeaders;
 	private final BeanContext beanContext;
 	private final RestConverter[] converters;
 	private final RestGuard[] guards;
@@ -505,6 +555,12 @@ public final class RestContext extends BeanContext {
 			_paramResolvers.put(rp.forClass(), rp);
 		paramResolvers = Collections.unmodifiableMap(_paramResolvers);
 		
+		Map<String,String> _defaultRequestHeaders = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+		_defaultRequestHeaders.putAll(getMapProperty(REST_defaultRequestHeaders, String.class));
+		defaultRequestHeaders = Collections.unmodifiableMap(new LinkedHashMap<>(_defaultRequestHeaders));
+		
+		defaultResponseHeaders = getMapProperty(REST_defaultResponseHeaders, String.class);
+		
 		try {
 			this.resourceFinder = new ResourceFinder(resource.getClass());
 
@@ -520,8 +576,6 @@ public final class RestContext extends BeanContext {
 			this.supportedContentTypes = toObjectArray(b.supportedContentTypes, MediaType.class);
 			this.supportedAcceptTypes = toObjectArray(b.supportedAcceptTypes, MediaType.class);
 			this.clientVersionHeader = b.clientVersionHeader;
-			this.defaultRequestHeaders = Collections.unmodifiableMap(b.defaultRequestHeaders);
-			this.defaultResponseHeaders = Collections.unmodifiableMap(b.defaultResponseHeaders);
 			this.beanContext = b.beanContext;
 			this.mimetypesFileTypeMap = b.mimetypesFileTypeMap;
 			this.staticFilesMap = Collections.unmodifiableMap(b.staticFilesMap);
@@ -797,8 +851,6 @@ public final class RestContext extends BeanContext {
 		String clientVersionHeader = "";
 
 		List<MediaType> supportedContentTypes, supportedAcceptTypes;
-		Map<String,String> defaultRequestHeaders = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
-		Map<String,Object> defaultResponseHeaders;
 		BeanContext beanContext;
 		MimetypesFileTypeMap mimetypesFileTypeMap;
 		Map<String,String> staticFilesMap;
@@ -851,8 +903,6 @@ public final class RestContext extends BeanContext {
 			encoders = rcb.encoders.build();
 			supportedContentTypes = rcb.supportedContentTypes != null ? rcb.supportedContentTypes : serializers.getSupportedMediaTypes();
 			supportedAcceptTypes = rcb.supportedAcceptTypes != null ? rcb.supportedAcceptTypes : parsers.getSupportedMediaTypes();
-			defaultRequestHeaders.putAll(rcb.defaultRequestHeaders);
-			defaultResponseHeaders = Collections.unmodifiableMap(new LinkedHashMap<>(rcb.defaultResponseHeaders));
 			beanContext = BeanContext.create().apply(ps).add(properties).build();
 			contextPath = rcb.contextPath;
 
@@ -1776,7 +1826,7 @@ public final class RestContext extends BeanContext {
 	 *
 	 * @return The default response headers for this resource.  Never <jk>null</jk>.
 	 */
-	public Map<String,Object> getDefaultResponseHeaders() {
+	public Map<String,String> getDefaultResponseHeaders() {
 		return defaultResponseHeaders;
 	}
 

http://git-wip-us.apache.org/repos/asf/juneau/blob/240182f0/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
----------------------------------------------------------------------
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 c27aadd..30ed779 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
@@ -104,8 +104,6 @@ public class RestContextBuilder extends BeanContextBuilder implements ServletCon
 	EncoderGroupBuilder encoders = EncoderGroup.create().append(IdentityEncoder.INSTANCE);
 
 	MimetypesFileTypeMap mimeTypes = new ExtendedMimetypesFileTypeMap();
-	Map<String,String> defaultRequestHeaders = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
-	Map<String,Object> defaultResponseHeaders = new LinkedHashMap<>();
 	List<Object> childResources = new ArrayList<>();
 	List<MediaType> supportedContentTypes, supportedAcceptTypes;
 	List<Object> staticFiles;
@@ -630,102 +628,6 @@ public class RestContextBuilder extends BeanContextBuilder implements ServletCon
 	}
 
 	/**
-	 * Adds class-level default HTTP request headers to this resource.
-	 *
-	 * <p>
-	 * Default request headers are default values for when HTTP requests do not specify a header value.
-	 * For example, you can specify a default value for <code>Accept</code> if a request does not specify that header
-	 * value.
-	 *
-	 * <p>
-	 * This is the programmatic equivalent to the
-	 * {@link RestResource#defaultRequestHeaders() @RestResource.defaultRequestHeaders()} annotation.
-	 *
-	 * @param name The HTTP header name.
-	 * @param value The HTTP header value.
-	 * @return This object (for method chaining).
-	 */
-	public RestContextBuilder defaultRequestHeader(String name, Object value) {
-		this.defaultRequestHeaders.put(name, StringUtils.toString(value));
-		return this;
-	}
-
-	/**
-	 * Adds class-level default HTTP request headers to this resource.
-	 *
-	 * <p>
-	 * Default request headers are default values for when HTTP requests do not specify a header value.
-	 * For example, you can specify a default value for <code>Accept</code> if a request does not specify that header
-	 * value.
-	 *
-	 * <p>
-	 * This is the programmatic equivalent to the
-	 * {@link RestResource#defaultRequestHeaders() @RestResource.defaultRequestHeaders()} annotation.
-	 *
-	 * @param headers HTTP headers of the form <js>"Name: Value"</js>.
-	 * @return This object (for method chaining).
-	 * @throws RestServletException If header string is not correctly formatted.
-	 */
-	public RestContextBuilder defaultRequestHeaders(String...headers) throws RestServletException {
-		for (String header : headers) {
-			String[] h = RestUtils.parseHeader(header);
-			if (h == null)
-				throw new RestServletException("Invalid default request header specified: ''{0}''.  Must be in the format: ''Header-Name: header-value''", header);
-			defaultRequestHeader(h[0], h[1]);
-		}
-		return this;
-	}
-
-	/**
-	 * Adds class-level default HTTP response headers to this resource.
-	 *
-	 * <p>
-	 * Default response headers are headers that will be appended to all responses if those headers have not already been
-	 * set on the response object.
-	 *
-	 * <p>
-	 * This is the programmatic equivalent to the
-	 * {@link RestResource#defaultResponseHeaders() @RestResource.defaultResponseHeaders()} annotation.
-	 *
-	 * <p>
-	 * Values are added AFTER those found in the annotation and therefore take precedence over those defined via the
-	 * annotation.
-	 *
-	 * @param name The HTTP header name.
-	 * @param value The HTTP header value.
-	 * @return This object (for method chaining).
-	 */
-	public RestContextBuilder defaultResponseHeader(String name, Object value) {
-		this.defaultResponseHeaders.put(name, value);
-		return this;
-	}
-
-	/**
-	 * Adds class-level default HTTP response headers to this resource.
-	 *
-	 * <p>
-	 * Default response headers are headers that will be appended to all responses if those headers have not already been
-	 * set on the response object.
-	 *
-	 * <p>
-	 * This is the programmatic equivalent to the
-	 * {@link RestResource#defaultResponseHeaders() @RestResource.defaultResponseHeaders()} annotation.
-	 *
-	 * @param headers HTTP headers of the form <js>"Name: Value"</js>.
-	 * @return This object (for method chaining).
-	 * @throws RestServletException If header string is not correctly formatted.
-	 */
-	public RestContextBuilder defaultResponseHeaders(String...headers) throws RestServletException {
-		for (String header : headers) {
-			String[] h = RestUtils.parseHeader(header);
-			if (h == null)
-				throw new RestServletException("Invalid default response header specified: ''{0}''.  Must be in the format: ''Header-Name: header-value''", header);
-			defaultResponseHeader(h[0], h[1]);
-		}
-		return this;
-	}
-
-	/**
 	 * Adds a child resource to this resource.
 	 *
 	 * <p>
@@ -1618,6 +1520,130 @@ public class RestContextBuilder extends BeanContextBuilder implements ServletCon
 	}
 
 	/**
+	 * <b>Configuration property:</b>  Default request headers.
+	 *
+	 * <p>
+	 * Adds class-level default HTTP request headers to this resource.
+	 *
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li>Property: {@link RestContext#REST_defaultRequestHeaders}
+	 * 	<li>Annotation:  {@link RestResource#defaultRequestHeaders()} / {@link RestMethod#defaultRequestHeaders()} 
+	 * 	<li>Method: {@link RestContextBuilder#defaultRequestHeader(String,Object)} / {@link RestContextBuilder#defaultRequestHeaders(String...)}
+	 * 	<li>Affects values returned by {@link RestRequest#getHeader(String)} when the header is not present on the request.
+	 * 	<li>The most useful reason for this annotation is to provide a default <code>Accept</code> header when one is not
+	 * 		specified so that a particular default {@link Serializer} is picked.
+	 *	</ul>
+	 *
+	 * @param name The HTTP header name.
+	 * @param value The HTTP header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestContextBuilder defaultRequestHeader(String name, Object value) {
+		return addTo(REST_defaultRequestHeaders, name, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Default request headers.
+	 *
+	 * <p>
+	 * Adds class-level default HTTP request headers to this resource.
+	 *
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li>Property: {@link RestContext#REST_defaultRequestHeaders}
+	 * 	<li>Annotation:  {@link RestResource#defaultRequestHeaders()} / {@link RestMethod#defaultRequestHeaders()} 
+	 * 	<li>Method: {@link RestContextBuilder#defaultRequestHeader(String,Object)} / {@link RestContextBuilder#defaultRequestHeaders(String...)}
+	 * 	<li>Strings are of the format <js>"Header-Name: header-value"</js>.
+	 * 	<li>You can use either <js>':'</js> or <js>'='</js> as the key/value delimiter.
+	 * 	<li>Key and value is trimmed of whitespace.
+	 * 	<li>Only one header value can be specified per entry (i.e. it's not a delimited list of header entries).
+	 * 	<li>Affects values returned by {@link RestRequest#getHeader(String)} when the header is not present on the request.
+	 * 	<li>The most useful reason for this annotation is to provide a default <code>Accept</code> header when one is not
+	 * 		specified so that a particular default {@link Serializer} is picked.
+	 *	</ul>
+	 *
+	 * @param headers The headers in the format <js>"Header-Name: header-value"</js>.
+	 * @return This object (for method chaining).
+	 * @throws RestServletException If malformed header is found.
+	 */
+	public RestContextBuilder defaultRequestHeaders(String...headers) throws RestServletException {
+		for (String header : headers) {
+			String[] h = RestUtils.parseHeader(header);
+			if (h == null)
+				throw new RestServletException("Invalid default request header specified: ''{0}''.  Must be in the format: ''Header-Name: header-value''", header);
+			defaultRequestHeader(h[0], h[1]);
+		}
+		return this;
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Default response headers.
+	 *
+	 * <p>
+	 * Specifies default values for response headers.
+	 *
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li>Property: {@link RestContext#REST_defaultResponseHeaders}
+	 * 	<li>Annotation:  {@link RestResource#defaultResponseHeaders()} 
+	 * 	<li>Method: {@link RestContextBuilder#defaultResponseHeader(String,Object)} / {@link RestContextBuilder#defaultResponseHeaders(String...)}
+	 * 	<li>This is equivalent to calling {@link RestResponse#setHeader(String, String)} programmatically in each of 
+	 * 		the Java methods.
+	 * 	<li>The header value will not be set if the header value has already been specified (hence the 'default' in the name).
+	 * 	<li>Values are added AFTER those found in the annotation and therefore take precedence over those defined via the
+	 * 		annotation.
+	 *	</ul>
+	 *
+	 * @param name The HTTP header name.
+	 * @param value The HTTP header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestContextBuilder defaultResponseHeader(String name, Object value) {
+		return addTo(REST_defaultResponseHeaders, name, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Default response headers.
+	 *
+	 * <p>
+	 * Specifies default values for response headers.
+	 *
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li>Property: {@link RestContext#REST_defaultResponseHeaders}
+	 * 	<li>Annotation:  {@link RestResource#defaultResponseHeaders()} 
+	 * 	<li>Method: {@link RestContextBuilder#defaultResponseHeader(String,Object)} / {@link RestContextBuilder#defaultResponseHeaders(String...)}
+	 * 	<li>Strings are of the format <js>"Header-Name: header-value"</js>.
+	 * 	<li>You can use either <js>':'</js> or <js>'='</js> as the key/value delimiter.
+	 * 	<li>Key and value is trimmed of whitespace.
+	 * 	<li>Only one header value can be specified per entry (i.e. it's not a delimited list of header entries).
+	 * 	<li>This is equivalent to calling {@link RestResponse#setHeader(String, String)} programmatically in each of 
+	 * 		the Java methods.
+	 * 	<li>The header value will not be set if the header value has already been specified (hence the 'default' in the name).
+	 * 	<li>Values are added AFTER those found in the annotation and therefore take precedence over those defined via the
+	 * 		annotation.
+	 *	</ul>
+	 *
+	 * @param headers The headers in the format <js>"Header-Name: header-value"</js>.
+	 * @return This object (for method chaining).
+	 * @throws RestServletException If malformed header is found.
+	 */
+	public RestContextBuilder defaultResponseHeaders(String...headers) throws RestServletException {
+		for (String header : headers) {
+			String[] h = RestUtils.parseHeader(header);
+			if (h == null)
+				throw new RestServletException("Invalid default response header specified: ''{0}''.  Must be in the format: ''Header-Name: header-value''", header);
+			defaultResponseHeader(h[0], h[1]);
+		}
+		return this;
+	}
+
+	/**
 	 * Specifies the serializer listener class to use for listening to non-fatal serialization errors.
 	 *
 	 * <p>

http://git-wip-us.apache.org/repos/asf/juneau/blob/240182f0/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResponse.java
----------------------------------------------------------------------
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResponse.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResponse.java
index 38e0a56..63206a6 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResponse.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResponse.java
@@ -69,8 +69,8 @@ public final class RestResponse extends HttpServletResponseWrapper {
 		super(res);
 		this.request = req;
 
-		for (Map.Entry<String,Object> e : context.getDefaultResponseHeaders().entrySet())
-			setHeader(e.getKey(), e.getValue().toString());
+		for (Map.Entry<String,String> e : context.getDefaultResponseHeaders().entrySet())
+			setHeader(e.getKey(), e.getValue());
 
 		try {
 			String passThroughHeaders = req.getHeader("x-response-headers");

http://git-wip-us.apache.org/repos/asf/juneau/blob/240182f0/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
----------------------------------------------------------------------
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
index 051d7f2..b59fa2c 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
@@ -116,7 +116,7 @@ public @interface RestMethod {
 	int priority() default 0;
 
 	/**
-	 * <b>Configuration property:</b>  Method-level guards.
+	 * Method-level guards.
 	 *
 	 * <p>
 	 * Associates one or more {@link RestGuard RestGuards} with all REST methods defined in this class.
@@ -139,7 +139,7 @@ public @interface RestMethod {
 	Class<? extends RestGuard>[] guards() default {};
 
 	/**
-	 * <b>Configuration property:</b>  Method-level response converters.
+	 * Method-level response converters.
 	 *
 	 * <p>
 	 * Associates one or more {@link RestConverter converters} with a resource method.
@@ -415,23 +415,10 @@ public @interface RestMethod {
 	String[] bpx() default {};
 
 	/**
-	 * Specifies default values for request headers.
-	 *
-	 * <p>
-	 * Strings are of the format <js>"Header-Name: header-value"</js>.
-	 *
-	 * <p>
-	 * Affects values returned by {@link RestRequest#getHeader(String)} when the header is not present on the request.
-	 *
-	 * <p>
-	 * The most useful reason for this annotation is to provide a default <code>Accept</code> header when one is not
-	 * specified so that a particular default {@link Serializer} is picked.
-	 *
-	 * <p>
-	 * Only one header value can be specified per entry (i.e. it's not a delimited list of header entries).
-	 *
+	 * Default request headers.
+	 * 
 	 * <p>
-	 * Header values specified at the method level override header values specified at the servlet level.
+	 * Specifies default values for request headers.
 	 *
 	 * <h5 class='section'>Example:</h5>
 	 * <p class='bcode'>
@@ -441,10 +428,21 @@ public @interface RestMethod {
 	 * 		...
 	 * 	}
 	 * </p>
-	 *
+	 * 
 	 * <p>
-	 * You can use either <js>':'</js> or <js>'='</js> as the key/value delimiter.
-	 * Key and value is trimmed of whitespace.
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li>Property: {@link RestContext#REST_defaultRequestHeaders}
+	 * 	<li>Annotation:  {@link RestResource#defaultRequestHeaders()} / {@link RestMethod#defaultRequestHeaders()} 
+	 * 	<li>Method: {@link RestContextBuilder#defaultRequestHeader(String,Object)} / {@link RestContextBuilder#defaultRequestHeaders(String...)}
+	 * 	<li>Strings are of the format <js>"Header-Name: header-value"</js>.
+	 * 	<li>You can use either <js>':'</js> or <js>'='</js> as the key/value delimiter.
+	 * 	<li>Key and value is trimmed of whitespace.
+	 * 	<li>Only one header value can be specified per entry (i.e. it's not a delimited list of header entries).
+	 * 	<li>Affects values returned by {@link RestRequest#getHeader(String)} when the header is not present on the request.
+	 * 	<li>The most useful reason for this annotation is to provide a default <code>Accept</code> header when one is not
+	 * 		specified so that a particular default {@link Serializer} is picked.
+	 *	</ul>
 	 */
 	String[] defaultRequestHeaders() default {};
 
@@ -630,7 +628,7 @@ public @interface RestMethod {
 	HtmlDoc htmldoc() default @HtmlDoc;
 
 	/**
-	 * <b>Configuration property:</b>  Default character encoding.
+	 * Default character encoding.
 	 * 
 	 * <p>
 	 * The default character encoding for the request and response if not specified on the request.
@@ -646,7 +644,7 @@ public @interface RestMethod {
 	 */
 	String defaultCharset() default "";
 	/**
-	 * <b>Configuration property:</b>  The maximum allowed input size (in bytes) on HTTP requests.
+	 * The maximum allowed input size (in bytes) on HTTP requests.
 	 *
 	 * <p>
 	 * Useful for alleviating DoS attacks by throwing an exception when too much input is received instead of resulting

http://git-wip-us.apache.org/repos/asf/juneau/blob/240182f0/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
----------------------------------------------------------------------
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestResource.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
index 5828fbb..5fb961e 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
@@ -67,7 +67,7 @@ public @interface RestResource {
 	String messages() default "";
 
 	/**
-	 * <b>Configuration property:</b>  Class-level guards.
+	 * Class-level guards.
 	 *
 	 * <p>
 	 * Associates one or more {@link RestGuard RestGuards} with all REST methods defined in this class.
@@ -90,7 +90,7 @@ public @interface RestResource {
 	Class<? extends RestGuard>[] guards() default {};
 
 	/**
-	 * <b>Configuration property:</b>  Class-level response converters.
+	 * Class-level response converters.
 	 *
 	 * <p>
 	 * Associates one or more {@link RestConverter converters} with a resource class.
@@ -156,7 +156,7 @@ public @interface RestResource {
 	Class<?>[] pojoSwaps() default {};
 
 	/**
-	 * <b>Configuration property:</b>  Java method parameter resolvers.
+	 * Java method parameter resolvers.
 	 *
 	 * <p>
 	 * By default, the Juneau framework will automatically Java method parameters of various types (e.g.
@@ -265,7 +265,7 @@ public @interface RestResource {
 	Class<? extends HttpPartParser> partParser() default UonPartParser.class;
 
 	/**
-	 * <b>Configuration property:</b>  Response handlers.
+	 * Response handlers.
 	 *
 	 * <p>
 	 * Specifies a list of {@link ResponseHandler} classes that know how to convert POJOs returned by REST methods or
@@ -318,20 +318,10 @@ public @interface RestResource {
 	Class<? extends Encoder>[] encoders() default {};
 
 	/**
-	 * Specifies default values for request headers.
-	 *
-	 * <p>
-	 * Strings are of the format <js>"Header-Name: header-value"</js>.
-	 *
-	 * <p>
-	 * Affects values returned by {@link RestRequest#getHeader(String)} when the header is not present on the request.
-	 *
-	 * <p>
-	 * The most useful reason for this annotation is to provide a default <code>Accept</code> header when one is not
-	 * specified so that a particular default {@link Serializer} is picked.
-	 *
+	 * Default request headers.
+	 * 
 	 * <p>
-	 * Only one header value can be specified per entry (i.e. it's not a delimited list of header entries).
+	 * Specifies default values for request headers.
 	 *
 	 * <h5 class='section'>Example:</h5>
 	 * <p class='bcode'>
@@ -341,28 +331,29 @@ public @interface RestResource {
 	 * 		...
 	 * 	}
 	 * </p>
-	 *
+	 * 
 	 * <p>
-	 * The programmatic equivalent to this annotation are the {@link RestContextBuilder#defaultRequestHeader(String, Object)}/
-	 * {@link RestContextBuilder#defaultRequestHeaders(String...)} methods.
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li>Property: {@link RestContext#REST_defaultRequestHeaders}
+	 * 	<li>Annotation:  {@link RestResource#defaultRequestHeaders()} / {@link RestMethod#defaultRequestHeaders()} 
+	 * 	<li>Method: {@link RestContextBuilder#defaultRequestHeader(String,Object)} / {@link RestContextBuilder#defaultRequestHeaders(String...)}
+	 * 	<li>Strings are of the format <js>"Header-Name: header-value"</js>.
+	 * 	<li>You can use either <js>':'</js> or <js>'='</js> as the key/value delimiter.
+	 * 	<li>Key and value is trimmed of whitespace.
+	 * 	<li>Only one header value can be specified per entry (i.e. it's not a delimited list of header entries).
+	 * 	<li>Affects values returned by {@link RestRequest#getHeader(String)} when the header is not present on the request.
+	 * 	<li>The most useful reason for this annotation is to provide a default <code>Accept</code> header when one is not
+	 * 		specified so that a particular default {@link Serializer} is picked.
+	 *	</ul>
 	 */
 	String[] defaultRequestHeaders() default {};
 
 	/**
-	 * Specifies default values for response headers.
-	 *
-	 * <p>
-	 * Strings are of the format <js>"Header-Name: header-value"</js>.
-	 *
-	 * <p>
-	 * This is equivalent to calling {@link RestResponse#setHeader(String, String)} programmatically in each of the Java
-	 * methods.
-	 *
-	 * <p>
-	 * The header value will not be set if the header value has already been specified (hence the 'default' in the name).
+	 * Default response headers.
 	 *
 	 * <p>
-	 * Only one header value can be specified per entry (i.e. it's not a delimited list of header entries).
+	 * Specifies default values for response headers.
 	 *
 	 * <h5 class='section'>Example:</h5>
 	 * <p class='bcode'>
@@ -374,8 +365,21 @@ public @interface RestResource {
 	 * </p>
 	 *
 	 * <p>
-	 * The programmatic equivalent to this annotation are the {@link RestContextBuilder#defaultResponseHeader(String, Object)}/
-	 * {@link RestContextBuilder#defaultResponseHeaders(String...)} methods.
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li>Property: {@link RestContext#REST_defaultResponseHeaders}
+	 * 	<li>Annotation:  {@link RestResource#defaultResponseHeaders()} 
+	 * 	<li>Method: {@link RestContextBuilder#defaultResponseHeader(String,Object)} / {@link RestContextBuilder#defaultResponseHeaders(String...)}
+	 * 	<li>Strings are of the format <js>"Header-Name: header-value"</js>.
+	 * 	<li>You can use either <js>':'</js> or <js>'='</js> as the key/value delimiter.
+	 * 	<li>Key and value is trimmed of whitespace.
+	 * 	<li>Only one header value can be specified per entry (i.e. it's not a delimited list of header entries).
+	 * 	<li>This is equivalent to calling {@link RestResponse#setHeader(String, String)} programmatically in each of 
+	 * 		the Java methods.
+	 * 	<li>The header value will not be set if the header value has already been specified (hence the 'default' in the name).
+	 * 	<li>Values are added AFTER those found in the annotation and therefore take precedence over those defined via the
+	 * 		annotation.
+	 *	</ul>
 	 */
 	String[] defaultResponseHeaders() default {};
 
@@ -753,7 +757,7 @@ public @interface RestResource {
 	String contextPath() default "";
 
 	/**
-	 * <b>Configuration property:</b>  Allow header URL parameters.
+	 * Allow header URL parameters.
 	 *
 	 * <p>
 	 * When enabled, headers such as <js>"Accept"</js> and <js>"Content-Type"</js> to be passed in as URL query
@@ -774,7 +778,7 @@ public @interface RestResource {
 	String allowHeaderParams() default "";
 
 	/**
-	 * <b>Configuration property:</b>  Allowed method parameters.
+	 * Allowed method parameters.
 	 *
 	 * <p>
 	 * When specified, the HTTP method can be overridden by passing in a <js>"method"</js> URL parameter on a regular
@@ -801,7 +805,7 @@ public @interface RestResource {
 	String allowedMethodParams() default "";
 
 	/**
-	 * <b>Configuration property:</b>  Allow body URL parameter.
+	 * Allow body URL parameter.
 	 *
 	 * <ul>
 	 * 	<li><b>Name:</b> <js>"RestContext.allowBodyParam.b"</js>
@@ -830,7 +834,7 @@ public @interface RestResource {
 	String allowBodyParam() default "";
 
 	/**
-	 * <b>Configuration property:</b>  Render response stack traces in responses.
+	 * Render response stack traces in responses.
 	 *
 	 * <p>
 	 * Render stack traces in HTTP response bodies when errors occur.
@@ -849,7 +853,7 @@ public @interface RestResource {
 	String renderResponseStackTraces() default "";
 
 	/**
-	 * <b>Configuration property:</b>  Use stack trace hashes.
+	 * Use stack trace hashes.
 	 *
 	 * <p>
 	 * When enabled, the number of times an exception has occurred will be determined based on stack trace hashsums,
@@ -867,7 +871,7 @@ public @interface RestResource {
 	String useStackTraceHashes() default "";
 
 	/**
-	 * <b>Configuration property:</b>  Default character encoding.
+	 * Default character encoding.
 	 * 
 	 * <p>
 	 * The default character encoding for the request and response if not specified on the request.
@@ -884,7 +888,7 @@ public @interface RestResource {
 	String defaultCharset() default "";
 
 	/**
-	 * <b>Configuration property:</b>  The maximum allowed input size (in bytes) on HTTP requests.
+	 * The maximum allowed input size (in bytes) on HTTP requests.
 	 *
 	 * <p>
 	 * Useful for alleviating DoS attacks by throwing an exception when too much input is received instead of resulting


Mime
View raw message