You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2017/06/16 00:10:50 UTC

[1/2] incubator-juneau git commit: Add @RestMethod.bpInclude/bpExclude

Repository: incubator-juneau
Updated Branches:
  refs/heads/master feaa916d9 -> 1a4670def


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/mouse.png
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/mouse.png b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/mouse.png
new file mode 100644
index 0000000..5308006
Binary files /dev/null and b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/mouse.png differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/rabbit.png
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/rabbit.png b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/rabbit.png
new file mode 100644
index 0000000..f013470
Binary files /dev/null and b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/rabbit.png differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/snake.png
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/snake.png b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/snake.png
new file mode 100644
index 0000000..7f17660
Binary files /dev/null and b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/snake.png differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
index fd2b66a..ed1d272 100644
--- a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
+++ b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
@@ -1426,6 +1426,42 @@ public class RestClientBuilder extends CoreObjectBuilder {
 	}
 
 	@Override /* CoreObjectBuilder */
+	public RestClientBuilder includeProperties(Map<String,String> values) {
+		super.includeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder includeProperties(String beanClassName, String properties) {
+		super.includeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder includeProperties(Class<?> beanClass, String properties) {
+		super.includeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder excludeProperties(Map<String,String> values) {
+		super.excludeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder excludeProperties(String beanClassName, String properties) {
+		super.excludeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder excludeProperties(Class<?> beanClass, String properties) {
+		super.excludeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
 	public RestClientBuilder beanDictionary(Class<?>...values) {
 		super.beanDictionary(values);
 		return this;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java b/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java
index aae0586..bcb00db 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java
@@ -141,6 +141,7 @@ class CallMethod implements Comparable<CallMethod>  {
 		private Response[] responses;
 		private Map<String,Widget> widgets;
 
+		@SuppressWarnings({ "unchecked", "rawtypes" })
 		private Builder(Object servlet, java.lang.reflect.Method method, RestContext context) throws RestServletException {
 			try {
 
@@ -194,7 +195,7 @@ class CallMethod implements Comparable<CallMethod>  {
 				ParserGroupBuilder pgb = null;
 				UrlEncodingParserBuilder uepb = null;
 
-				if (m.serializers().length > 0 || m.parsers().length > 0 || m.properties().length > 0 || m.beanFilters().length > 0 || m.pojoSwaps().length > 0) {
+				if (m.serializers().length > 0 || m.parsers().length > 0 || m.properties().length > 0 || m.beanFilters().length > 0 || m.pojoSwaps().length > 0 || m.bpIncludes().length() > 0 || m.bpExcludes().length() > 0) {
 					sgb = new SerializerGroupBuilder();
 					pgb = new ParserGroupBuilder();
 					uepb = new UrlEncodingParserBuilder(urlEncodingParser.createPropertyStore());
@@ -254,6 +255,10 @@ class CallMethod implements Comparable<CallMethod>  {
 						sgb.properties(properties);
 					for (Property p1 : m.properties())
 						sgb.property(p1.name(), p1.value());
+					if (! m.bpIncludes().isEmpty())
+						sgb.includeProperties((Map)JsonParser.DEFAULT.parse(m.bpIncludes(), Map.class, String.class, String.class));
+					if (! m.bpExcludes().isEmpty())
+						sgb.excludeProperties((Map)JsonParser.DEFAULT.parse(m.bpExcludes(), Map.class, String.class, String.class));
 					sgb.beanFilters(m.beanFilters());
 					sgb.pojoSwaps(m.pojoSwaps());
 				}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
index fc770a5..3a9d1bf 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
@@ -17,6 +17,7 @@ import static java.lang.annotation.RetentionPolicy.*;
 
 import java.lang.annotation.*;
 
+import org.apache.juneau.*;
 import org.apache.juneau.encoders.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.remoteable.*;
@@ -269,6 +270,77 @@ public @interface RestMethod {
 	Class<?>[] pojoSwaps() default {};
 
 	/**
+	 * Shortcut for specifying the {@link BeanContext#BEAN_includeProperties} property on all serializers.
+	 * <p>
+	 * The typical use case is when you're rendering summary and details views of the same bean in a resource and
+	 * 	you want to expose or hide specific properties depending on the level of detail you want.
+	 * <p>
+	 * In the example below, our 'summary' view is a list of beans where we only want to show the ID property,
+	 * 	and our detail view is a single bean where we want to expose different fields:
+	 * <p class='bcode'>
+	 *	<jc>// Our bean</jc>
+	 * 	<jk>public class</jk> MyBean {
+	 * 
+	 * 		<jc>// Summary properties</jc>
+	 * 		<ja>@Html</ja>(link=<js>"servlet:/mybeans/{id}"</js>)
+	 * 		<jk>public</jk> String <jf>id</jf>;
+	 *
+	 * 		<jc>// Detail properties</jc>
+	 * 		<jk>public</jk> String <jf>a</jf>, <jf>b</jf>;
+	 * 	}
+	 *
+	 *	<jc>// Only render "id" property.</jc>
+	 * 	<ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/mybeans"</js>, bpIncludes=<js>"{MyBean:'id'}"</js>)
+	 * 	<jk>public</jk> List&lt;MyBean&gt; getBeanSummary();
+	 *
+	 *	<jc>// Only render "a" and "b" properties.</jc>
+	 * 	<ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/mybeans/{id}"</js>, bpIncludes=<js>"{MyBean:'a,b'}"</js>)
+	 * 	<jk>public</jk> MyBean getBeanDetails(<ja>@Path</ja> String id);
+	 * </p>
+	 * <p>
+	 * The format of this value is a lax JSON object.
+	 * <br>Keys can be fully-qualified or short class names or <js>"*"</js> to represent all classes.
+	 * <br>Values are comma-delimited lists of bean property names.
+	 * <br>Properties apply to specified class and all subclasses.
+	 */
+	String bpIncludes() default "";
+
+	/**
+	 * Shortcut for specifying the {@link BeanContext#BEAN_excludeProperties} property on all serializers.
+	 * <p>
+	 * Same as {@link #bpIncludes()} except you specify a list of bean property names that you want to exclude from
+	 * 	serialization.
+	 * <p>
+	 * In the example below, our 'summary' view is a list of beans where we want to exclude some properties:
+	 * <p class='bcode'>
+	 *	<jc>// Our bean</jc>
+	 * 	<jk>public class</jk> MyBean {
+	 *
+	 * 		<jc>// Summary properties</jc>
+	 * 		<ja>@Html</ja>(link=<js>"servlet:/mybeans/{id}"</js>)
+	 * 		<jk>public</jk> String <jf>id</jf>;
+	 *
+	 * 		<jc>// Detail properties</jc>
+	 * 		<jk>public</jk> String <jf>a</jf>, <jf>b</jf>;
+	 * 	}
+	 *
+	 *	<jc>// Don't show "a" and "b" properties.</jc>
+	 * 	<ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/mybeans"</js>, bpExcludes=<js>"{MyBean:'a,b'}"</js>)
+	 * 	<jk>public</jk> List&lt;MyBean&gt; getBeanSummary();
+	 *
+	 *	<jc>// Render all properties.</jc>
+	 * 	<ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/mybeans/{id}"</js>)
+	 * 	<jk>public</jk> MyBean getBeanDetails(<ja>@Path</ja> String id);
+	 * </p>
+	 * <p>
+	 * The format of this value is a lax JSON object.
+	 * <br>Keys can be fully-qualified or short class names or <js>"*"</js> to represent all classes.
+	 * <br>Values are comma-delimited lists of bean property names.
+	 * <br>Properties apply to specified class and all subclasses.
+	 */
+	String bpExcludes() default "";
+
+	/**
 	 * Specifies default values for request headers.
 	 * <p>
 	 * Strings are of the format <js>"Header-Name: header-value"</js>.


[2/2] incubator-juneau git commit: Add @RestMethod.bpInclude/bpExclude

Posted by ja...@apache.org.
Add @RestMethod.bpInclude/bpExclude

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

Branch: refs/heads/master
Commit: 1a4670def5ba561f00602234082d65de0f8e22ac
Parents: feaa916
Author: JamesBognar <ja...@apache.org>
Authored: Thu Jun 15 20:10:46 2017 -0400
Committer: JamesBognar <ja...@apache.org>
Committed: Thu Jun 15 20:10:46 2017 -0400

----------------------------------------------------------------------
 .../juneau/jena/RdfSerializerBuilder.java       |  36 +++++
 .../org/apache/juneau/PropertyStoreTest.java    |  20 +--
 .../java/org/apache/juneau/BeanContext.java     | 107 ++++++++++++++
 .../main/java/org/apache/juneau/BeanMeta.java   |  13 +-
 .../org/apache/juneau/BeanPropertyMeta.java     |   3 +
 .../java/org/apache/juneau/BeanSession.java     |   3 +
 .../org/apache/juneau/CoreObjectBuilder.java    | 140 +++++++++++++++++++
 .../apache/juneau/annotation/BeanProperty.java  |  16 +++
 .../apache/juneau/csv/CsvSerializerBuilder.java |  36 +++++
 .../org/apache/juneau/html/HtmlSerializer.java  |  76 +++++++---
 .../juneau/html/HtmlSerializerBuilder.java      |  36 +++++
 .../apache/juneau/jso/JsoSerializerBuilder.java |  36 +++++
 .../json/JsonSchemaSerializerBuilder.java       |  36 +++++
 .../juneau/json/JsonSerializerBuilder.java      |  36 +++++
 .../msgpack/MsgPackSerializerBuilder.java       |  36 +++++
 .../plaintext/PlainTextSerializerBuilder.java   |  36 +++++
 .../juneau/serializer/SerializerBuilder.java    |  36 +++++
 .../serializer/SerializerGroupBuilder.java      |  74 ++++++++++
 .../juneau/soap/SoapXmlSerializerBuilder.java   |  36 +++++
 .../juneau/transforms/StringFormatSwap.java     |  45 ++++++
 .../apache/juneau/uon/UonSerializerBuilder.java |  36 +++++
 .../UrlEncodingSerializerBuilder.java           |  36 +++++
 .../juneau/xml/XmlSchemaSerializerBuilder.java  |  36 +++++
 .../apache/juneau/xml/XmlSerializerBuilder.java |  36 +++++
 juneau-core/src/main/javadoc/overview.html      |  12 +-
 .../apache/juneau/examples/rest/PetStore.json   |  17 +++
 .../juneau/examples/rest/PetStoreResource.java  | 108 ++++++++++++++
 .../juneau/examples/rest/RootResources.java     |   1 +
 .../apache/juneau/examples/rest/htdocs/bird.png | Bin 0 -> 1925 bytes
 .../apache/juneau/examples/rest/htdocs/cat.png  | Bin 0 -> 1878 bytes
 .../apache/juneau/examples/rest/htdocs/dog.png  | Bin 0 -> 1980 bytes
 .../apache/juneau/examples/rest/htdocs/fish.png | Bin 0 -> 2198 bytes
 .../juneau/examples/rest/htdocs/mouse.png       | Bin 0 -> 1551 bytes
 .../juneau/examples/rest/htdocs/rabbit.png      | Bin 0 -> 1603 bytes
 .../juneau/examples/rest/htdocs/snake.png       | Bin 0 -> 1824 bytes
 .../juneau/rest/client/RestClientBuilder.java   |  36 +++++
 .../java/org/apache/juneau/rest/CallMethod.java |   7 +-
 .../juneau/rest/annotation/RestMethod.java      |  72 ++++++++++
 38 files changed, 1218 insertions(+), 36 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerBuilder.java b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerBuilder.java
index f254734..0f82cec 100644
--- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerBuilder.java
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerBuilder.java
@@ -789,6 +789,42 @@ public class RdfSerializerBuilder extends SerializerBuilder {
 	}
 
 	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder includeProperties(Map<String,String> values) {
+		super.includeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder includeProperties(String beanClassName, String properties) {
+		super.includeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder includeProperties(Class<?> beanClass, String properties) {
+		super.includeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder excludeProperties(Map<String,String> values) {
+		super.excludeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder excludeProperties(String beanClassName, String properties) {
+		super.excludeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder excludeProperties(Class<?> beanClass, String properties) {
+		super.excludeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
 	public RdfSerializerBuilder beanDictionary(Class<?>...values) {
 		super.beanDictionary(values);
 		return this;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-core-test/src/test/java/org/apache/juneau/PropertyStoreTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/PropertyStoreTest.java b/juneau-core-test/src/test/java/org/apache/juneau/PropertyStoreTest.java
index de00d7c..93144eb 100644
--- a/juneau-core-test/src/test/java/org/apache/juneau/PropertyStoreTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/PropertyStoreTest.java
@@ -251,7 +251,7 @@ public class PropertyStoreTest {
 			.test(String.class, "'true'")
 			.test(Class.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Boolean' to type 'java.lang.Class'.  Value=true.")
 			.test(TestEnum.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Boolean' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=true.")
-			.test(String[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Boolean' to type 'java.lang.String[]'.  Value=true.")
+			.test(String[].class, "['true']")
 			.test(Class[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Boolean' to type 'java.lang.Class[]'.  Value=true.")
 			.test(TestEnum[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Boolean' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value=true.")
 			.testMap(String.class, String.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Boolean' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=true.")
@@ -267,7 +267,7 @@ public class PropertyStoreTest {
 			.test(String.class, "'123'")
 			.test(Class.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Integer' to type 'java.lang.Class'.  Value=123.")
 			.test(TestEnum.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Integer' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=123.")
-			.test(String[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Integer' to type 'java.lang.String[]'.  Value=123.")
+			.test(String[].class, "['123']")
 			.test(Class[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Integer' to type 'java.lang.Class[]'.  Value=123.")
 			.test(TestEnum[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Integer' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value=123.")
 			.testMap(String.class, String.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Integer' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=123.")
@@ -283,7 +283,7 @@ public class PropertyStoreTest {
 			.test(String.class, "'java.lang.String'")
 			.test(Class.class, "'java.lang.String'")
 			.test(TestEnum.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Class' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value='java.lang.String'.")
-			.test(String[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Class' to type 'java.lang.String[]'.  Value='java.lang.String'.")
+			.test(String[].class, "['class java.lang.String']")
 			.test(Class[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Class' to type 'java.lang.Class[]'.  Value='java.lang.String'.")
 			.test(TestEnum[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Class' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value='java.lang.String'.")
 			.testMap(String.class, String.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Class' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value='java.lang.String'.")
@@ -299,7 +299,7 @@ public class PropertyStoreTest {
 			.test(String.class, "'foo'")
 			.test(Class.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.String' to type 'java.lang.Class'.  Value='foo'.")
 			.test(TestEnum.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.String' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value='foo'.")
-			.test(String[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.String' to type 'java.lang.String[]'.  Value='foo'.")
+			.test(String[].class, "['foo']")
 			.test(Class[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.String' to type 'java.lang.Class[]'.  Value='foo'.")
 			.test(TestEnum[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.String' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value='foo'.")
 			.testMap(String.class, String.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.String' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value='foo'.")
@@ -327,9 +327,9 @@ public class PropertyStoreTest {
 			.test(String.class, "'ONE'")
 			.test(Class.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.PropertyStoreTest$TestEnum' to type 'java.lang.Class'.  Value='ONE'.")
 			.test(TestEnum.class, "'ONE'")
-			.test(String[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.PropertyStoreTest$TestEnum' to type 'java.lang.String[]'.  Value='ONE'.")
+			.test(String[].class, "['ONE']")
 			.test(Class[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.PropertyStoreTest$TestEnum' to type 'java.lang.Class[]'.  Value='ONE'.")
-			.test(TestEnum[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.PropertyStoreTest$TestEnum' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value='ONE'.")
+			.test(TestEnum[].class, "['ONE']")
 			.testMap(String.class, String.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.PropertyStoreTest$TestEnum' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value='ONE'.")
 			.testMap(Class.class, Class.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.PropertyStoreTest$TestEnum' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value='ONE'.")
 		;
@@ -402,7 +402,7 @@ public class PropertyStoreTest {
 			.test(String.class, "'{foo:\\'bar\\'}'")
 			.test(Class.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'java.lang.Class'.  Value={foo:'bar'}.")
 			.test(TestEnum.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value={foo:'bar'}.")
-			.test(String[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'java.lang.String[]'.  Value={foo:'bar'}.")
+			.test(String[].class, "['{foo=bar}']")
 			.test(Class[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'java.lang.Class[]'.  Value={foo:'bar'}.")
 			.test(TestEnum[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value={foo:'bar'}.")
 			.testMap(String.class, String.class, "{foo:'bar'}")
@@ -420,7 +420,7 @@ public class PropertyStoreTest {
 			.test(String.class, "'{\\'java.lang.String\\':\\'java.lang.Integer\\'}'")
 			.test(Class.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'java.lang.Class'.  Value={'java.lang.String':'java.lang.Integer'}.")
 			.test(TestEnum.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value={'java.lang.String':'java.lang.Integer'}.")
-			.test(String[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'java.lang.String[]'.  Value={'java.lang.String':'java.lang.Integer'}.")
+			.test(String[].class, "['{class java.lang.String=class java.lang.Integer}']")
 			.test(Class[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'java.lang.Class[]'.  Value={'java.lang.String':'java.lang.Integer'}.")
 			.test(TestEnum[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value={'java.lang.String':'java.lang.Integer'}.")
 			.testMap(String.class, String.class, "{'java.lang.String':'java.lang.Integer'}")
@@ -740,7 +740,7 @@ public class PropertyStoreTest {
 			.test(String.class, "'{foo:\\'bar\\'}'")
 			.test(Class.class, "Could not retrieve property store property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'java.lang.Class'.  Value={foo:'bar'}.")
 			.test(TestEnum.class, "Could not retrieve property store property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value={foo:'bar'}.")
-			.test(String[].class, "Could not retrieve property store property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'java.lang.String[]'.  Value={foo:'bar'}.")
+			.test(String[].class, "['{foo=bar}']")
 			.test(Class[].class, "Could not retrieve property store property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'java.lang.Class[]'.  Value={foo:'bar'}.")
 			.test(TestEnum[].class, "Could not retrieve property store property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value={foo:'bar'}.")
 			.testMap(String.class, String.class, "{foo:'bar'}")
@@ -758,7 +758,7 @@ public class PropertyStoreTest {
 			.test(String.class, "'{\\'java.lang.String\\':\\'java.lang.Integer\\'}'")
 			.test(Class.class, "Could not retrieve property store property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'java.lang.Class'.  Value={'java.lang.String':'java.lang.Integer'}.")
 			.test(TestEnum.class, "Could not retrieve property store property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value={'java.lang.String':'java.lang.Integer'}.")
-			.test(String[].class, "Could not retrieve property store property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'java.lang.String[]'.  Value={'java.lang.String':'java.lang.Integer'}.")
+			.test(String[].class, "['{class java.lang.String=class java.lang.Integer}']")
 			.test(Class[].class, "Could not retrieve property store property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'java.lang.Class[]'.  Value={'java.lang.String':'java.lang.Integer'}.")
 			.test(TestEnum[].class, "Could not retrieve property store property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value={'java.lang.String':'java.lang.Integer'}.")
 			.testMap(String.class, String.class, "{'java.lang.String':'java.lang.Integer'}")

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-core/src/main/java/org/apache/juneau/BeanContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanContext.java b/juneau-core/src/main/java/org/apache/juneau/BeanContext.java
index 53a8cc0..c9e2d1c 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanContext.java
@@ -24,6 +24,7 @@ import java.util.concurrent.*;
 
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.http.*;
+import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.serializer.*;
@@ -610,6 +611,62 @@ public class BeanContext extends Context {
 	public static final String BEAN_implClasses_put = "BeanContext.implClasses.map.put";
 
 	/**
+	 * <b>Configuration property:</b>  Explicitly specify visible bean properties.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.includeProperties"</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>
+	 * </ul>
+	 * <p>
+	 * Specifies to only include the specified list of properties for the specified bean classes.
+	 * <p>
+	 * The keys are either fully-qualified or simple class names, and the values are comma-delimited lists of property
+	 * 	names.
+	 * The key <js>"*"</js> means all bean classes.
+	 * <p>
+	 * For example, <code>{Bean1:<js>'foo,bar'</js>}</code> means only serialize the <code>foo</code> and <code>bar</code>
+	 * 	properties on the specified bean.
+	 * <p>
+	 * Setting applies to specified class and all subclasses.
+	 */
+	public static final String BEAN_includeProperties = "BeanContext.includeProperties.map";
+
+	/**
+	 * <b>Configuration property:</b>  Explicitly specify visible bean properties.
+	 */
+	public static final String BEAN_includeProperties_put = "BeanContext.includeProperties.map.put";
+
+	/**
+	 * <b>Configuration property:</b>  Exclude specified properties from beans.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.excludeProperties"</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>
+	 * </ul>
+	 * <p>
+	 * Specifies to exclude the specified list of properties for the specified bean class.
+	 * <p>
+	 * The keys are either fully-qualified or simple class names, and the values are comma-delimited lists of property
+	 * names.
+	 * The key <js>"*"</js> means all bean classes.
+	 * <p>
+	 * For example, <code>{Bean1:<js>'foo,bar'</js>}</code> means don't serialize the <code>foo</code> and <code>bar</code>
+	 * 	properties on the specified bean.
+	 * <p>
+	 * Setting applies to specified class and all subclasses.
+	 */
+	public static final String BEAN_excludeProperties = "BeanContext.excludeProperties.map";
+
+	/**
+	 * <b>Configuration property:</b>  Exclude specified properties from beans.
+	 */
+	public static final String BEAN_excludeProperties_put = "BeanContext.excludeProperties.map.put";
+
+	/**
 	 * <b>Configuration property:</b>  Bean lookup dictionary.
 	 * <p>
 	 * <ul>
@@ -814,6 +871,7 @@ public class BeanContext extends Context {
 	final Locale locale;
 	final TimeZone timeZone;
 	final MediaType mediaType;
+	final Map<String,String[]> includeProperties, excludeProperties;
 
 	final Map<Class,ClassMeta> cmCache;
 	final ClassMeta<Object> cmObject;  // Reusable ClassMeta that represents general Objects.
@@ -904,6 +962,11 @@ public class BeanContext extends Context {
 		implKeyClasses = implClasses.keySet().toArray(new Class[0]);
 		implValueClasses = implClasses.values().toArray(new Class[0]);
 
+		Map<String,String[]> m2 = pm.getMap(BEAN_includeProperties, String.class, String[].class, null);
+		includeProperties = m2 == null ? Collections.EMPTY_MAP : Collections.unmodifiableMap(m2);
+		m2 = pm.getMap(BEAN_excludeProperties, String.class, String[].class, null);
+		excludeProperties = m2 == null ? Collections.EMPTY_MAP : Collections.unmodifiableMap(m2);
+
 		locale = pm.get(BEAN_locale, Locale.class, null);
 		timeZone = pm.get(BEAN_timeZone, TimeZone.class, null);
 		mediaType = pm.get(BEAN_mediaType, MediaType.class, null);
@@ -1472,6 +1535,50 @@ public class BeanContext extends Context {
 	}
 
 	/**
+	 * Returns the {@link #BEAN_includeProperties} setting for the specified class.
+	 *
+	 * @param c The class.
+	 * @return The properties to include for the specified class, or <jk>null</jk> if it's not defined for the class.
+	 */
+	public String[] getIncludeProperties(Class<?> c) {
+		if (includeProperties.isEmpty())
+			return null;
+		String[] s = null;
+		for (Iterator<Class<?>> i = ClassUtils.getParentClasses(c, false, true); i.hasNext();) {
+			Class<?> c2 = i.next();
+			s = includeProperties.get(c2.getName());
+			if (s != null)
+				return s;
+			s = includeProperties.get(c2.getSimpleName());
+			if (s != null)
+				return s;
+		}
+		return includeProperties.get("*");
+	}
+
+	/**
+	 * Returns the {@link #BEAN_excludeProperties} setting for the specified class.
+	 *
+	 * @param c The class.
+	 * @return The properties to exclude for the specified class, or <jk>null</jk> if it's not defined for the class.
+	 */
+	public String[] getExcludeProperties(Class<?> c) {
+		if (excludeProperties.isEmpty())
+			return null;
+		String[] s = null;
+		for (Iterator<Class<?>> i = ClassUtils.getParentClasses(c, false, true); i.hasNext();) {
+			Class<?> c2 = i.next();
+			s = excludeProperties.get(c2.getName());
+			if (s != null)
+				return s;
+			s = excludeProperties.get(c2.getSimpleName());
+			if (s != null)
+				return s;
+		}
+		return excludeProperties.get("*");
+	}
+
+	/**
 	 * Returns a reusable {@link ClassMeta} representation for the class <code>Object</code>.
 	 * <p>
 	 * This <code>ClassMeta</code> is often used to represent "any object type" when an object type

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java b/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java
index bcbf705..770236b 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java
@@ -234,11 +234,13 @@ public class BeanMeta<T> {
 
 				// Explicitly defined property names in @Bean annotation.
 				Set<String> fixedBeanProps = new LinkedHashSet<String>();
+				String[] includeProperties = ctx.getIncludeProperties(c);
+				String[] excludeProperties = ctx.getExcludeProperties(c);
 
 				if (beanFilter != null) {
 
 					// Get the 'properties' attribute if specified.
-					if (beanFilter.getProperties() != null)
+					if (beanFilter.getProperties() != null && includeProperties == null)
 						for (String p : beanFilter.getProperties())
 							fixedBeanProps.add(p);
 
@@ -246,6 +248,9 @@ public class BeanMeta<T> {
 						propertyNamer = beanFilter.getPropertyNamer();
 				}
 
+				if (includeProperties != null)
+					fixedBeanProps.addAll(Arrays.asList(includeProperties));
+
 				if (propertyNamer == null)
 					propertyNamer = new PropertyNamerDefault();
 
@@ -367,7 +372,7 @@ public class BeanMeta<T> {
 					// Eliminated excluded properties if BeanFilter.excludeKeys is specified.
 					String[] includeKeys = beanFilter.getProperties();
 					String[] excludeKeys = beanFilter.getExcludeProperties();
-					if (excludeKeys != null) {
+					if (excludeKeys != null && excludeProperties == null) {
 						for (String k : excludeKeys)
 							properties.remove(k);
 
@@ -383,6 +388,10 @@ public class BeanMeta<T> {
 					}
 				}
 
+				if (excludeProperties != null)
+					for (String ep : excludeProperties)
+						properties.remove(ep);
+
 				if (pNames != null) {
 					Map<String,BeanPropertyMeta> properties2 = new LinkedHashMap<String,BeanPropertyMeta>();
 					for (String k : pNames) {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java b/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java
index fd0f8b9..a54ad8e 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java
@@ -30,6 +30,7 @@ import org.apache.juneau.internal.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.serializer.*;
 import org.apache.juneau.transform.*;
+import org.apache.juneau.transforms.*;
 import org.apache.juneau.utils.*;
 
 /**
@@ -222,6 +223,8 @@ public class BeanPropertyMeta {
 		}
 
 		private static PojoSwap getPropertyPojoSwap(BeanProperty p) throws Exception {
+			if (! p.format().isEmpty())
+				return newInstance(PojoSwap.class, StringFormatSwap.class, p.format());
 			Class<?> c = p.swap();
 			if (c == Null.class)
 				return null;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-core/src/main/java/org/apache/juneau/BeanSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanSession.java b/juneau-core/src/main/java/org/apache/juneau/BeanSession.java
index a40881e..2e5ab64 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanSession.java
@@ -22,6 +22,7 @@ import java.util.*;
 import java.util.concurrent.atomic.*;
 
 import org.apache.juneau.http.*;
+import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.serializer.*;
@@ -486,6 +487,8 @@ public class BeanSession extends Session {
 					return (T)toArray(type, Arrays.asList((Object[])value));
 				else if (startsWith(value.toString(), '['))
 					return (T)toArray(type, new ObjectList(value.toString()).setBeanSession(this));
+				else
+					return (T)toArray(type, new ObjectList((Object[])StringUtils.split(value.toString(), ',')).setBeanSession(this));
 			}
 
 			// Target type is some sort of Map that needs to be converted.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-core/src/main/java/org/apache/juneau/CoreObjectBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/CoreObjectBuilder.java b/juneau-core/src/main/java/org/apache/juneau/CoreObjectBuilder.java
index 5c67e6d..8e00384 100644
--- a/juneau-core/src/main/java/org/apache/juneau/CoreObjectBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/CoreObjectBuilder.java
@@ -1153,6 +1153,146 @@ public abstract class CoreObjectBuilder {
 	}
 
 	/**
+	 * <b>Configuration property:</b>  Explicitly specify visible bean properties.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.includeProperties"</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>
+	 * </ul>
+	 * <p>
+	 * Specifies to only include the specified list of properties for the specified bean classes.
+	 * <p>
+	 * The keys are either fully-qualified or simple class names, and the values are comma-delimited lists of property
+	 * names.
+	 * The key <js>"*"</js> means all bean classes.
+	 * <p>
+	 * For example, <code>{Bean1:<js>"foo,bar"</js>}</code> means only serialize the <code>foo</code> and <code>bar</code>
+	 * 	properties on the specified bean.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_includeProperties</jsf>, values)</code>.
+	 * </ul>
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_includeProperties
+	 */
+	public CoreObjectBuilder includeProperties(Map<String,String> values) {
+		return property(BEAN_includeProperties, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Explicitly specify visible bean properties.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>putToProperty(<jsf>BEAN_includeProperties</jsf>, beanClassName, properties)</code>
+	 * 		or <code>property(<jsf>BEAN_includeProperties_put</jsf>, beanClassName, properties)</code>.
+	 * </ul>
+	 *
+	 * @param beanClassName The bean class name.  Can be a simple name, fully-qualified name, or <js>"*"</js>.
+	 * @param properties Comma-delimited list of property names.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_includeProperties
+	 * @see BeanContext#BEAN_includeProperties_put
+	 */
+	public CoreObjectBuilder includeProperties(String beanClassName, String properties) {
+		return putToProperty(BEAN_includeProperties, beanClassName, properties);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Explicitly specify visible bean properties.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>putToProperty(<jsf>BEAN_includeProperties</jsf>, beanClass.getName(), properties)</code>
+	 * 		or <code>property(<jsf>BEAN_includeProperties_put</jsf>, beanClass.getName(), properties)</code>.
+	 * </ul>
+	 *
+	 * @param beanClass The bean class.
+	 * @param properties Comma-delimited list of property names.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_includeProperties
+	 * @see BeanContext#BEAN_includeProperties_put
+	 */
+	public CoreObjectBuilder includeProperties(Class<?> beanClass, String properties) {
+		return putToProperty(BEAN_includeProperties, beanClass.getName(), properties);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Exclude specified properties from beans.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.excludeProperties"</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>
+	 * </ul>
+	 * <p>
+	 * Specifies to exclude the specified list of properties for the specified bean classes.
+	 * <p>
+	 * The keys are either fully-qualified or simple class names, and the values are comma-delimited lists of property
+	 * names.
+	 * The key <js>"*"</js> means all bean classes.
+	 * <p>
+	 * For example, <code>{Bean1:<js>"foo,bar"</js>}</code> means don't serialize the <code>foo</code> and <code>bar</code>
+	 * 	properties on the specified bean.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_excludeProperties</jsf>, values)</code>.
+	 * </ul>
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_excludeProperties
+	 */
+	public CoreObjectBuilder excludeProperties(Map<String,String> values) {
+		return property(BEAN_excludeProperties, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Exclude specified properties from beans.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>putToProperty(<jsf>BEAN_excludeProperties</jsf>, beanClassName, properties)</code>
+	 * 		or <code>property(<jsf>BEAN_excludeProperties_put</jsf>, beanClassName, properties)</code>.
+	 * </ul>
+	 *
+	 * @param beanClassName The bean class name.  Can be a simple name, fully-qualified name, or <js>"*"</js>.
+	 * @param properties Comma-delimited list of property names.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_excludeProperties
+	 * @see BeanContext#BEAN_excludeProperties_put
+	 */
+	public CoreObjectBuilder excludeProperties(String beanClassName, String properties) {
+		return putToProperty(BEAN_excludeProperties, beanClassName, properties);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Exclude specified properties from beans.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>putToProperty(<jsf>BEAN_excludeProperties</jsf>, beanClass.getName(), properties)</code>
+	 * 		or <code>property(<jsf>BEAN_excludeProperties_put</jsf>, beanClass.getName(), properties)</code>.
+	 * </ul>
+	 *
+	 * @param beanClass The bean class.
+	 * @param properties Comma-delimited list of property names.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_excludeProperties
+	 * @see BeanContext#BEAN_excludeProperties_put
+	 */
+	public CoreObjectBuilder excludeProperties(Class<?> beanClass, String properties) {
+		return putToProperty(BEAN_excludeProperties, beanClass.getName(), properties);
+	}
+
+	/**
 	 * <b>Configuration property:</b>  Bean lookup dictionary.
 	 * <p>
 	 * <ul>

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-core/src/main/java/org/apache/juneau/annotation/BeanProperty.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/annotation/BeanProperty.java b/juneau-core/src/main/java/org/apache/juneau/annotation/BeanProperty.java
index d574f21..fbd8f3d 100644
--- a/juneau-core/src/main/java/org/apache/juneau/annotation/BeanProperty.java
+++ b/juneau-core/src/main/java/org/apache/juneau/annotation/BeanProperty.java
@@ -249,4 +249,20 @@ public @interface BeanProperty {
 	 * </ul>
 	 */
 	Class<?>[] beanDictionary() default {};
+
+	/**
+	 * Specifies a String format for converting the bean property value to a formatted string.
+	 * <p>
+	 * Note that this is usually a one-way conversion during serialization.
+	 * <p>
+	 * During parsing, we will attempt to convert the value to the original form by using the {@link BeanSession#convertToType(Object, Class)}
+	 * 	but there is no guarantee that this will succeed.
+	 *
+	 * <h5 class='section'>Example:</h5>
+	 * <p class='bcode'>
+	 * 	<ja>@BeanProperty</ja>(format=<js>"$%.2f"</js>)
+	 * 	<jk>public float</jk> <jf>price</jf>;
+	 * </p>
+	 */
+	String format() default "";
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializerBuilder.java
index c09fd02..d35d7cd 100644
--- a/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializerBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializerBuilder.java
@@ -433,6 +433,42 @@ public class CsvSerializerBuilder extends SerializerBuilder {
 	}
 
 	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder includeProperties(Map<String,String> values) {
+		super.includeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder includeProperties(String beanClassName, String properties) {
+		super.includeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder includeProperties(Class<?> beanClass, String properties) {
+		super.includeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder excludeProperties(Map<String,String> values) {
+		super.excludeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder excludeProperties(String beanClassName, String properties) {
+		super.excludeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder excludeProperties(Class<?> beanClass, String properties) {
+		super.excludeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
 	public CsvSerializerBuilder beanDictionary(Class<?>...values) {
 		super.beanDictionary(values);
 		return this;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java
index f227456..bbd5050 100644
--- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java
@@ -22,6 +22,7 @@ import java.util.*;
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.http.*;
+import org.apache.juneau.internal.*;
 import org.apache.juneau.serializer.*;
 import org.apache.juneau.transform.*;
 import org.apache.juneau.xml.*;
@@ -272,6 +273,10 @@ public class HtmlSerializer extends XmlSerializer {
 			}
 
 			HtmlClassMeta html = sType.getExtendedMeta(HtmlClassMeta.class);
+			HtmlRender render = html.getRender();
+
+			if (o != null && render != null)
+				return serializeAnything(session, out, render.getContent(session, o), null, typeName, 2, pMeta, false);
 
 			if (html.isAsXml() || (pMeta != null && pMeta.getExtendedMeta(HtmlBeanPropertyMeta.class).isAsXml())) {
 				super.serializeAnything(session, out, o, null, null, null, false, XmlFormat.MIXED, false, false, null);
@@ -384,9 +389,19 @@ public class HtmlSerializer extends XmlSerializer {
 				session.onError(t, "Could not call getValue() on property ''{0}'', {1}", e.getKey(), t.getLocalizedMessage());
 			}
 
+			String link = getLink(ppMeta);
+			String style = getStyle(session, ppMeta, value);
+
 			out.sTag(i+1, "tr").nl(i+2);
-			out.sTag(i+2, "td");
+			out.oTag(i+2, "td");
+			if (style != null)
+				out.attr("style", style);
+			out.cTag();
+			if (link != null)
+				out.oTag(i+3, "a").attrUri("href", link.replace("{#}", StringUtils.toString(value))).cTag();
 			ContentResult cr = serializeAnything(session, out, key, keyType, null, 2, null, false);
+			if (link != null)
+				out.eTag("a");
 			if (cr == CR_NORMAL)
 				out.i(i+2);
 			out.eTag("td").nl(i+2);
@@ -400,7 +415,6 @@ public class HtmlSerializer extends XmlSerializer {
 		out.ie(i).eTag("table").nl(i);
 	}
 
-	@SuppressWarnings({ "rawtypes", "unchecked" })
 	private void serializeBeanMap(HtmlSerializerSession session, HtmlWriter out, BeanMap<?> m, ClassMeta<?> eType, BeanPropertyMeta ppMeta) throws Exception {
 		int i = session.getIndent();
 
@@ -421,11 +435,6 @@ public class HtmlSerializer extends XmlSerializer {
 		for (BeanPropertyValue p : m.getValues(session.isTrimNulls())) {
 			BeanPropertyMeta pMeta = p.getMeta();
 			ClassMeta<?> cMeta = p.getClassMeta();
-			HtmlBeanPropertyMeta hbpMeta = pMeta.getExtendedMeta(HtmlBeanPropertyMeta.class);
-			String link = hbpMeta.getLink();
-			HtmlRender render = hbpMeta.getRender();
-			if (render == null)
-				render = cMeta.getExtendedMeta(HtmlClassMeta.class).getRender();
 
 			String key = p.getName();
 			Object value = p.getValue();
@@ -436,10 +445,12 @@ public class HtmlSerializer extends XmlSerializer {
 			if (session.canIgnoreValue(cMeta, key, value))
 				continue;
 
+			String link = cMeta.isCollectionOrArray() ? null : getLink(pMeta);
+
 			out.sTag(i+1, "tr").nl(i+1);
 			out.sTag(i+2, "td").text(key).eTag("td").nl(i+2);
 			out.oTag(i+2, "td");
-			String style = render == null ? null : render.getStyle(session, value);
+			String style = getStyle(session, pMeta, value);
 			if (style != null)
 				out.attr("style", style);
 			out.cTag();
@@ -447,7 +458,7 @@ public class HtmlSerializer extends XmlSerializer {
 			try {
 				if (link != null)
 					out.oTag(i+3, "a").attrUri("href", m.resolveVars(link)).cTag();
-				ContentResult cr = serializeAnything(session, out, render == null ? value : render.getContent(session, value), cMeta, key, 2, pMeta, false);
+				ContentResult cr = serializeAnything(session, out, value, cMeta, key, 2, pMeta, false);
 				if (cr == CR_NORMAL)
 					out.i(i+2);
 				if (link != null)
@@ -548,24 +559,16 @@ public class HtmlSerializer extends XmlSerializer {
 					for (Object k : th) {
 						BeanMapEntry p = m2.getProperty(session.toString(k));
 						BeanPropertyMeta pMeta = p.getMeta();
-						HtmlBeanPropertyMeta hpMeta = pMeta.getExtendedMeta(HtmlBeanPropertyMeta.class);
-						String link = hpMeta.getLink();
-
+						String link = pMeta.getClassMeta().isCollectionOrArray() ? null : getLink(pMeta);
 						Object value = p.getValue();
-						ClassMeta<?> cMeta = session.getClassMetaForObject(value);
-
-						HtmlRender render = hpMeta.getRender();
-						if (render == null && cMeta != null)
-							render = cMeta.getExtendedMeta(HtmlClassMeta.class).getRender();
-
+						String style = getStyle(session, pMeta, value);
 						out.oTag(i+2, "td");
-						String style = render == null ? null : render.getStyle(session, value);
 						if (style != null)
 							out.attr("style", style);
 						out.cTag();
 						if (link != null)
 							out.oTag(i+3, "a").attrUri("href", m2.resolveVars(link)).cTag();
-						ContentResult cr = serializeAnything(session, out, render == null ? value : render.getContent(session, value), pMeta.getClassMeta(), p.getKey().toString(), 2, pMeta, false);
+						ContentResult cr = serializeAnything(session, out, value, pMeta.getClassMeta(), p.getKey().toString(), 2, pMeta, false);
 						if (cr == CR_NORMAL)
 							out.i(i+2);
 						if (link != null)
@@ -583,8 +586,17 @@ public class HtmlSerializer extends XmlSerializer {
 				out.attr(btpn, type2);
 			out.append('>').nl(i+1);
 			for (Object o : c) {
-				out.sTag(i+1, "li");
+				out.oTag(i+1, "li");
+				String style = getStyle(session, ppMeta, o);
+				String link = getLink(ppMeta);
+				if (style != null)
+					out.attr("style", style);
+				out.cTag();
+				if (link != null)
+					out.oTag(i+2, "a").attrUri("href", link.replace("{#}", StringUtils.toString(o))).cTag();
 				ContentResult cr = serializeAnything(session, out, o, eType.getElementType(), name, 1, null, false);
+				if (link != null)
+					out.eTag("a");
 				if (cr == CR_NORMAL)
 					out.ie(i+1);
 				out.eTag("li").nl(i+1);
@@ -593,6 +605,28 @@ public class HtmlSerializer extends XmlSerializer {
 		}
 	}
 
+	private static HtmlRender<?> getRender(HtmlSerializerSession session, BeanPropertyMeta pMeta, Object value) {
+		if (pMeta == null)
+			return null;
+		HtmlBeanPropertyMeta hpMeta = pMeta.getExtendedMeta(HtmlBeanPropertyMeta.class);
+		HtmlRender<?> render = hpMeta.getRender();
+		if (render != null)
+			return render;
+		ClassMeta<?> cMeta = session.getClassMetaForObject(value);
+		render = cMeta == null ? null : cMeta.getExtendedMeta(HtmlClassMeta.class).getRender();
+		return render;
+	}
+
+	@SuppressWarnings({"rawtypes","unchecked"})
+	private static String getStyle(HtmlSerializerSession session, BeanPropertyMeta pMeta, Object value) {
+		HtmlRender render = getRender(session, pMeta, value);
+		return render == null ? null : render.getStyle(session, value);
+	}
+
+	private static String getLink(BeanPropertyMeta pMeta) {
+		return pMeta == null ? null : pMeta.getExtendedMeta(HtmlBeanPropertyMeta.class).getLink();
+	}
+
 	/*
 	 * Returns the table column headers for the specified collection of objects.
 	 * Returns null if collection should not be serialized as a 2-dimensional table.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerBuilder.java
index 13aa762..5073f67 100644
--- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerBuilder.java
@@ -605,6 +605,42 @@ public class HtmlSerializerBuilder extends XmlSerializerBuilder {
 	}
 
 	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder includeProperties(Map<String,String> values) {
+		super.includeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder includeProperties(String beanClassName, String properties) {
+		super.includeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder includeProperties(Class<?> beanClass, String properties) {
+		super.includeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder excludeProperties(Map<String,String> values) {
+		super.excludeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder excludeProperties(String beanClassName, String properties) {
+		super.excludeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder excludeProperties(Class<?> beanClass, String properties) {
+		super.excludeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
 	public HtmlSerializerBuilder beanDictionary(Class<?>...values) {
 		super.beanDictionary(values);
 		return this;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-core/src/main/java/org/apache/juneau/jso/JsoSerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/jso/JsoSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/jso/JsoSerializerBuilder.java
index 39a4d63..5bb072d 100644
--- a/juneau-core/src/main/java/org/apache/juneau/jso/JsoSerializerBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/jso/JsoSerializerBuilder.java
@@ -433,6 +433,42 @@ public class JsoSerializerBuilder extends SerializerBuilder {
 	}
 
 	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder includeProperties(Map<String,String> values) {
+		super.includeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder includeProperties(String beanClassName, String properties) {
+		super.includeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder includeProperties(Class<?> beanClass, String properties) {
+		super.includeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder excludeProperties(Map<String,String> values) {
+		super.excludeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder excludeProperties(String beanClassName, String properties) {
+		super.excludeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder excludeProperties(Class<?> beanClass, String properties) {
+		super.excludeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
 	public JsoSerializerBuilder beanDictionary(Class<?>...values) {
 		super.beanDictionary(values);
 		return this;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-core/src/main/java/org/apache/juneau/json/JsonSchemaSerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/json/JsonSchemaSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/json/JsonSchemaSerializerBuilder.java
index e9ee47f..df08b02 100644
--- a/juneau-core/src/main/java/org/apache/juneau/json/JsonSchemaSerializerBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonSchemaSerializerBuilder.java
@@ -445,6 +445,42 @@ public class JsonSchemaSerializerBuilder extends JsonSerializerBuilder {
 	}
 
 	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder includeProperties(Map<String,String> values) {
+		super.includeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder includeProperties(String beanClassName, String properties) {
+		super.includeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder includeProperties(Class<?> beanClass, String properties) {
+		super.includeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder excludeProperties(Map<String,String> values) {
+		super.excludeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder excludeProperties(String beanClassName, String properties) {
+		super.excludeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder excludeProperties(Class<?> beanClass, String properties) {
+		super.excludeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
 	public JsonSchemaSerializerBuilder beanDictionary(Class<?>...values) {
 		super.beanDictionary(values);
 		return this;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerBuilder.java
index 97e0daa..1454d67 100644
--- a/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerBuilder.java
@@ -498,6 +498,42 @@ public class JsonSerializerBuilder extends SerializerBuilder {
 	}
 
 	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder includeProperties(Map<String,String> values) {
+		super.includeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder includeProperties(String beanClassName, String properties) {
+		super.includeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder includeProperties(Class<?> beanClass, String properties) {
+		super.includeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder excludeProperties(Map<String,String> values) {
+		super.excludeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder excludeProperties(String beanClassName, String properties) {
+		super.excludeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder excludeProperties(Class<?> beanClass, String properties) {
+		super.excludeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
 	public JsonSerializerBuilder beanDictionary(Class<?>...values) {
 		super.beanDictionary(values);
 		return this;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerBuilder.java
index 6eb01fe..330ad04 100644
--- a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerBuilder.java
@@ -433,6 +433,42 @@ public class MsgPackSerializerBuilder extends SerializerBuilder {
 	}
 
 	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder includeProperties(Map<String,String> values) {
+		super.includeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder includeProperties(String beanClassName, String properties) {
+		super.includeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder includeProperties(Class<?> beanClass, String properties) {
+		super.includeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder excludeProperties(Map<String,String> values) {
+		super.excludeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder excludeProperties(String beanClassName, String properties) {
+		super.excludeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder excludeProperties(Class<?> beanClass, String properties) {
+		super.excludeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
 	public MsgPackSerializerBuilder beanDictionary(Class<?>...values) {
 		super.beanDictionary(values);
 		return this;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextSerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextSerializerBuilder.java
index 222e502..dd61eeb 100644
--- a/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextSerializerBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextSerializerBuilder.java
@@ -433,6 +433,42 @@ public class PlainTextSerializerBuilder extends SerializerBuilder {
 	}
 
 	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder includeProperties(Map<String,String> values) {
+		super.includeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder includeProperties(String beanClassName, String properties) {
+		super.includeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder includeProperties(Class<?> beanClass, String properties) {
+		super.includeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder excludeProperties(Map<String,String> values) {
+		super.excludeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder excludeProperties(String beanClassName, String properties) {
+		super.excludeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder excludeProperties(Class<?> beanClass, String properties) {
+		super.excludeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
 	public PlainTextSerializerBuilder beanDictionary(Class<?>...values) {
 		super.beanDictionary(values);
 		return this;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerBuilder.java
index a1ee7c8..3a7ec4f 100644
--- a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerBuilder.java
@@ -861,6 +861,42 @@ public class SerializerBuilder extends CoreObjectBuilder {
 	}
 
 	@Override /* CoreObjectBuilder */
+	public CoreObjectBuilder includeProperties(Map<String,String> values) {
+		super.includeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CoreObjectBuilder includeProperties(String beanClassName, String properties) {
+		super.includeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CoreObjectBuilder includeProperties(Class<?> beanClass, String properties) {
+		super.includeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CoreObjectBuilder excludeProperties(Map<String,String> values) {
+		super.excludeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CoreObjectBuilder excludeProperties(String beanClassName, String properties) {
+		super.excludeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CoreObjectBuilder excludeProperties(Class<?> beanClass, String properties) {
+		super.excludeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
 	public SerializerBuilder beanDictionary(Class<?>...values) {
 		super.beanDictionary(values);
 		return this;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroupBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroupBuilder.java b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroupBuilder.java
index 9601e94..a29449b 100644
--- a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroupBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroupBuilder.java
@@ -907,6 +907,80 @@ public class SerializerGroupBuilder {
 	}
 
 	/**
+	 * Sets the {@link BeanContext#BEAN_includeProperties} property on all serializers in this group.
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_includeProperties
+	 */
+	public SerializerGroupBuilder includeProperties(Map<String,String> values) {
+		return property(BEAN_includeProperties, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_includeProperties_put} property on all serializers in this group.
+	 *
+	 * @param beanClassName The bean class name.  Can be a simple name, fully-qualified name, or <js>"*"</js>.
+	 * @param properties Comma-delimited list of property names.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_includeProperties
+	 * @see BeanContext#BEAN_includeProperties_put
+	 */
+	public SerializerGroupBuilder includeProperties(String beanClassName, String properties) {
+		return putToProperty(BEAN_includeProperties, beanClassName, properties);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_includeProperties_put} property on all serializers in this group.
+	 *
+	 * @param beanClass The bean class.
+	 * @param properties Comma-delimited list of property names.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_includeProperties
+	 * @see BeanContext#BEAN_includeProperties_put
+	 */
+	public SerializerGroupBuilder includeProperties(Class<?> beanClass, String properties) {
+		return putToProperty(BEAN_includeProperties, beanClass.getName(), properties);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_excludeProperties} property on all serializers in this group.
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_excludeProperties
+	 */
+	public SerializerGroupBuilder excludeProperties(Map<String,String> values) {
+		return property(BEAN_excludeProperties, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_excludeProperties_put} property on all serializers in this group.
+	 *
+	 * @param beanClassName The bean class name.  Can be a simple name, fully-qualified name, or <js>"*"</js>.
+	 * @param properties Comma-delimited list of property names.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_excludeProperties
+	 * @see BeanContext#BEAN_excludeProperties_put
+	 */
+	public SerializerGroupBuilder excludeProperties(String beanClassName, String properties) {
+		return putToProperty(BEAN_excludeProperties, beanClassName, properties);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_excludeProperties_put} property on all serializers in this group.
+	 *
+	 * @param beanClass The bean class.
+	 * @param properties Comma-delimited list of property names.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_excludeProperties
+	 * @see BeanContext#BEAN_excludeProperties_put
+	 */
+	public SerializerGroupBuilder excludeProperties(Class<?> beanClass, String properties) {
+		return putToProperty(BEAN_excludeProperties, beanClass.getName(), properties);
+	}
+
+	/**
 	 * Sets the {@link BeanContext#BEAN_beanDictionary_add} property on all serializers in this group.
 	 *
 	 * @param values The new value for this property.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-core/src/main/java/org/apache/juneau/soap/SoapXmlSerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/soap/SoapXmlSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/soap/SoapXmlSerializerBuilder.java
index c95c349..0b6e50e 100644
--- a/juneau-core/src/main/java/org/apache/juneau/soap/SoapXmlSerializerBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/soap/SoapXmlSerializerBuilder.java
@@ -489,6 +489,42 @@ public class SoapXmlSerializerBuilder extends XmlSerializerBuilder {
 	}
 
 	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder includeProperties(Map<String,String> values) {
+		super.includeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder includeProperties(String beanClassName, String properties) {
+		super.includeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder includeProperties(Class<?> beanClass, String properties) {
+		super.includeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder excludeProperties(Map<String,String> values) {
+		super.excludeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder excludeProperties(String beanClassName, String properties) {
+		super.excludeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder excludeProperties(Class<?> beanClass, String properties) {
+		super.excludeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
 	public SoapXmlSerializerBuilder beanDictionary(Class<?>...values) {
 		super.beanDictionary(values);
 		return this;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-core/src/main/java/org/apache/juneau/transforms/StringFormatSwap.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/transforms/StringFormatSwap.java b/juneau-core/src/main/java/org/apache/juneau/transforms/StringFormatSwap.java
new file mode 100644
index 0000000..842b261
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/transforms/StringFormatSwap.java
@@ -0,0 +1,45 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.transforms;
+
+import org.apache.juneau.*;
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.transform.*;
+
+/**
+ * Built-in POJO swap implementation class for the {@link BeanProperty#format()} annotation.
+ */
+public class StringFormatSwap extends StringSwap<Object> {
+
+	private final String format;
+
+	/**
+	 * Constructor.
+	 * @param format The string format string.
+	 */
+	public StringFormatSwap(String format) {
+		this.format = format;
+	}
+
+	@Override /* PojoSwap */
+	public String swap(BeanSession session, Object o) throws SerializeException {
+		return String.format(format, o);
+	}
+
+	@Override /* PojoSwap */
+	public Object unswap(BeanSession session, String f, ClassMeta<?> hint) throws ParseException {
+		return session.convertToType(f, hint);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerBuilder.java
index bc1d18b..8443578 100644
--- a/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerBuilder.java
@@ -475,6 +475,42 @@ public class UonSerializerBuilder extends SerializerBuilder {
 	}
 
 	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder includeProperties(Map<String,String> values) {
+		super.includeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder includeProperties(String beanClassName, String properties) {
+		super.includeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder includeProperties(Class<?> beanClass, String properties) {
+		super.includeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder excludeProperties(Map<String,String> values) {
+		super.excludeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder excludeProperties(String beanClassName, String properties) {
+		super.excludeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder excludeProperties(Class<?> beanClass, String properties) {
+		super.excludeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
 	public UonSerializerBuilder beanDictionary(Class<?>...values) {
 		super.beanDictionary(values);
 		return this;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerBuilder.java
index 4c307b5..0af49c0 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerBuilder.java
@@ -532,6 +532,42 @@ public class UrlEncodingSerializerBuilder extends UonSerializerBuilder {
 	}
 
 	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder includeProperties(Map<String,String> values) {
+		super.includeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder includeProperties(String beanClassName, String properties) {
+		super.includeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder includeProperties(Class<?> beanClass, String properties) {
+		super.includeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder excludeProperties(Map<String,String> values) {
+		super.excludeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder excludeProperties(String beanClassName, String properties) {
+		super.excludeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder excludeProperties(Class<?> beanClass, String properties) {
+		super.excludeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
 	public UrlEncodingSerializerBuilder beanDictionary(Class<?>...values) {
 		super.beanDictionary(values);
 		return this;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializerBuilder.java
index 7fba517..dcb590c 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializerBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializerBuilder.java
@@ -469,6 +469,42 @@ public class XmlSchemaSerializerBuilder extends XmlSerializerBuilder {
 	}
 
 	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder includeProperties(Map<String,String> values) {
+		super.includeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder includeProperties(String beanClassName, String properties) {
+		super.includeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder includeProperties(Class<?> beanClass, String properties) {
+		super.includeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder excludeProperties(Map<String,String> values) {
+		super.excludeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder excludeProperties(String beanClassName, String properties) {
+		super.excludeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder excludeProperties(Class<?> beanClass, String properties) {
+		super.excludeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
 	public XmlSchemaSerializerBuilder beanDictionary(Class<?>...values) {
 		super.beanDictionary(values);
 		return this;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerBuilder.java
index bcf450f..56b2fff 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerBuilder.java
@@ -621,6 +621,42 @@ public class XmlSerializerBuilder extends SerializerBuilder {
 	}
 
 	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder includeProperties(Map<String,String> values) {
+		super.includeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder includeProperties(String beanClassName, String properties) {
+		super.includeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder includeProperties(Class<?> beanClass, String properties) {
+		super.includeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder excludeProperties(Map<String,String> values) {
+		super.excludeProperties(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder excludeProperties(String beanClassName, String properties) {
+		super.excludeProperties(beanClassName, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder excludeProperties(Class<?> beanClass, String properties) {
+		super.excludeProperties(beanClass, properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
 	public XmlSerializerBuilder beanDictionary(Class<?>...values) {
 		super.beanDictionary(values);
 		return this;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-core/src/main/javadoc/overview.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/javadoc/overview.html b/juneau-core/src/main/javadoc/overview.html
index f9eafcc..a2c57dd 100644
--- a/juneau-core/src/main/javadoc/overview.html
+++ b/juneau-core/src/main/javadoc/overview.html
@@ -6318,6 +6318,12 @@
 				</ul>
 			<li>{@link org.apache.juneau.annotation.NameProperty @NameProperty} and {@link org.apache.juneau.annotation.ParentProperty @ParentProperty}
 				can now be applied to fields.  
+			<li>New properties on {@link org.apache.juneau.BeanContext}:
+				<ul>
+					<li>{@link org.apache.juneau.BeanContext#BEAN_includeProperties BEAN_includeProperties}
+					<li>{@link org.apache.juneau.BeanContext#BEAN_excludeProperties BEAN_excludeProperties}
+				</ul>
+			<li>New annotation property: {@link org.apache.juneau.annotation.BeanProperty#format()}.
 		</ul>
 
 		<h6 class='topic'>org.apache.juneau.rest</h6>
@@ -6433,8 +6439,10 @@
 				at the end of the HTTP call.
 			<li>New anntotations added to {@link org.apache.juneau.rest.annotation.RestMethod @RestMethod}:
 				<ul>
-					<li>{@link org.apache.juneau.rest.annotation.RestMethod#defaultQuery defaultQuery()}
-					<li>{@link org.apache.juneau.rest.annotation.RestMethod#defaultFormData defaultFormData()}
+					<li>{@link org.apache.juneau.rest.annotation.RestMethod#defaultQuery() defaultQuery()}
+					<li>{@link org.apache.juneau.rest.annotation.RestMethod#defaultFormData() defaultFormData()}
+					<li>{@link org.apache.juneau.rest.annotation.RestMethod#bpIncludes() bpIncludes()}
+					<li>{@link org.apache.juneau.rest.annotation.RestMethod#bpExcludes() bpExcludes()}
 				</ul>
 			<li>Default values on header, query, and form-data annotations:
 				<ul>

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PetStore.json
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PetStore.json b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PetStore.json
new file mode 100644
index 0000000..e8d3800
--- /dev/null
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PetStore.json
@@ -0,0 +1,17 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+{
+	1: {kind:'CAT',name:'Mr. Frisky',price:39.99,breed:'Persian',getsAlongWith:['CAT','FISH','RABBIT']},
+	2: {kind:'DOG',name:'Kibbles',price:99.99,breed:'Husky',getsAlongWith:['DOG','BIRD','FISH','MOUSE','RABBIT']},
+	3: {kind:'RABBIT',name:'Hoppy',price:49.99,breed:'Angora',getsAlongWith:['DOG','BIRD','FISH','MOUSE']}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PetStoreResource.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PetStoreResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PetStoreResource.java
new file mode 100644
index 0000000..381c897
--- /dev/null
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PetStoreResource.java
@@ -0,0 +1,108 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.examples.rest;
+
+import java.util.*;
+import java.util.Map;
+
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.dto.html5.*;
+import org.apache.juneau.html.*;
+import org.apache.juneau.html.annotation.Html;
+import org.apache.juneau.json.*;
+import org.apache.juneau.microservice.*;
+import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.serializer.*;
+
+/**
+ * Sample REST resource that renders summary and detail views of the same bean.
+ */
+@RestResource(
+	title="Pet Store",
+	description="An example of a typical REST resource where beans are rendered in summary and details views.",
+	path="/petstore",
+	htmldoc=@HtmlDoc(
+		links="{up:'request:/..',options:'servlet:/?method=OPTIONS',source:'$C{Source/gitHub}/org/apache/juneau/examples/rest/PetStoreResource.java'}",
+		aside=""
+			+ "<div style='max-width:400px' class='text'>"
+			+ "	<p>This page shows a standard REST resource that renders bean summaries and details.</p>"
+			+ "	<p>It shows how different properties can be rendered on the same bean in different views.</p>"
+			+ "	<p>It also shows examples of HtmlRender classes and @BeanProperty(format) annotations.</p>"
+			+ "</div>"
+	)
+)
+public class PetStoreResource extends Resource {
+	private static final long serialVersionUID = 1L;
+
+	// Our database.
+	private Map<Integer,Pet> petDB;
+	
+	@Override /* Servlet */
+	public synchronized void init(RestConfig config) throws Exception {
+		// Load our database from a local JSON file.
+		petDB = JsonParser.DEFAULT.parse(getClass().getResourceAsStream("PetStore.json"), LinkedHashMap.class, Integer.class, Pet.class);
+		super.init(config);
+	}
+	
+	// Exclude the 'breed' and 'getsAlongWith' properties from the beans.
+	@RestMethod(name="GET", path="/", summary="The complete list of pets in the store", bpExcludes="{Pet:'breed,getsAlongWith'}")
+	public Collection<Pet> getPets() {
+		return petDB.values();
+	}
+
+	// Shows all bean properties.
+	@RestMethod(name="GET", path="/{id}", summary="Pet details")
+	public Pet getPet(@Path("id") Integer id) {
+		return petDB.get(id);
+	}
+
+	// Our bean class.
+	public static class Pet {
+		
+		@Html(link="servlet:/{id}")  // Creates a hyperlink in HTML view.
+		@NameProperty                // Links the parent key to this bean.
+		public int id;
+		
+		public String name;
+		public Kind kind;
+		public String breed;
+		public List<Kind> getsAlongWith;
+		
+		@BeanProperty(format="$%.2f")  // Renders price in dollars.
+		public float price;
+	}
+	
+	@Html(render=KindRender.class)  // Render as an icon in HTML.
+	public static enum Kind {
+		CAT, 
+		DOG, 
+		BIRD,
+		FISH,
+		MOUSE,
+		RABBIT,
+		SNAKE
+	}
+
+	public static class KindRender extends HtmlRender<Kind> {
+		@Override
+		public Object getContent(SerializerSession session, Kind value) {
+			return new Img().src("servlet:/htdocs/"+value.toString().toLowerCase()+".png");
+		}
+		@Override
+		public String getStyle(SerializerSession session, Kind value) {
+			return "background-color:#FDF2E9";
+		}
+	}
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RootResources.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RootResources.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RootResources.java
index 14adedc..d829209 100644
--- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RootResources.java
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RootResources.java
@@ -44,6 +44,7 @@ import org.apache.juneau.rest.widget.*;
 	},
 	children={
 		HelloWorldResource.class,
+		PetStoreResource.class,
 		SystemPropertiesResource.class,
 		MethodExampleResource.class,
 		RequestEchoResource.class,

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/bird.png
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/bird.png b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/bird.png
new file mode 100644
index 0000000..636ecf8
Binary files /dev/null and b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/bird.png differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/cat.png
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/cat.png b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/cat.png
new file mode 100644
index 0000000..917abc6
Binary files /dev/null and b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/cat.png differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/dog.png
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/dog.png b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/dog.png
new file mode 100644
index 0000000..e100eb2
Binary files /dev/null and b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/dog.png differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1a4670de/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/fish.png
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/fish.png b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/fish.png
new file mode 100644
index 0000000..ca76a46
Binary files /dev/null and b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/htdocs/fish.png differ