This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new 229faf1  Tests.
229faf1 is described below

commit 229faf1c83d5db5462518ea64277ba2242479e02
Author: JamesBognar <[email protected]>
AuthorDate: Sat May 12 16:35:46 2018 -0400

    Tests.
---
 .../org/apache/juneau/jena/RdfParserSession.java   |   2 +-
 .../main/java/org/apache/juneau/BeanSession.java   |   7 +-
 .../org/apache/juneau/html/HtmlParserSession.java  |   4 +-
 .../org/apache/juneau/internal/ClassUtils.java     |   6 +-
 .../org/apache/juneau/internal/StringUtils.java    |  20 +-
 .../java/org/apache/juneau/internal/Transform.java |  15 +-
 .../org/apache/juneau/internal/TransformCache.java |  24 +-
 .../org/apache/juneau/json/JsonParserSession.java  |   5 +-
 .../org/apache/juneau/parser/ParserSession.java    |   2 +-
 .../org/apache/juneau/uon/UonParserSession.java    |   3 +-
 .../org/apache/juneau/xml/XmlParserSession.java    |   5 +-
 .../juneau/yaml/proto/YamlParserSession.java       |   4 +-
 .../apache/juneau/rest/test/ParamsResource.java    | 103 ------
 .../org/apache/juneau/rest/test/ParamsTest.java    | 164 ---------
 .../juneau/rest/mock/MockServletRequest.java       |   2 +-
 .../juneau/rest/response/DefaultHandler.java       |  12 +
 .../{annotation => }/DefaultContentTypesTest.java  |   3 +-
 .../rest/{annotation => }/StatusCodesTest.java     |   3 +-
 .../juneau/rest/annotation/BodyAnnotationTest.java |  66 ++--
 .../rest/annotation/FormDataAnnotationTest.java    |  21 +-
 .../juneau/rest/annotation/PathAnnotationTest.java | 392 +++++++++++++++++++++
 ...sTest.java => PathRemainderAnnotationTest.java} |  40 ++-
 .../rest/annotation/QueryAnnotationTest.java       |  21 +-
 23 files changed, 541 insertions(+), 383 deletions(-)

diff --git 
a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java
 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java
index 5387a91..8ceca1a 100644
--- 
a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java
+++ 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java
@@ -301,7 +301,7 @@ public class RdfParserSession extends ReaderParserSession {
                } else if (sType.isCharSequence()) {
                        o = decodeString(getValue(n, outer));
                } else if (sType.isChar()) {
-                       o = decodeString(getValue(n, outer)).charAt(0);
+                       o = parseCharacter(decodeString(getValue(n, outer)));
                } else if (sType.isNumber()) {
                        o = parseNumber(getValue(n, outer).toString(), (Class<? 
extends Number>)sType.getInnerClass());
                } else if (sType.isMap()) {
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
index e518e49..5dc8b02 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
@@ -423,8 +423,7 @@ public class BeanSession extends Session {
                                                }
                                        }
                                } else if (type.isChar()) {
-                                       String s = value.toString();
-                                       return (T)Character.valueOf(s.length() 
== 0 ? 0 : s.charAt(0));
+                                       return (T)parseCharacter(value);
                                } else if (type.isBoolean()) {
                                        if (value instanceof Number) {
                                                int i = 
((Number)value).intValue();
@@ -495,9 +494,9 @@ public class BeanSession extends Session {
                                }
                        }
 
-                       if (type.isChar()) {
+                       if (type.isChar() && value.toString().length() == 1) {
                                String s = value.toString();
-                               return (T)Character.valueOf(s.length() == 0 ? 0 
: s.charAt(0));
+                               return (T)Character.valueOf(s.charAt(0));
                        }
 
                        // Handle setting of array properties
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParserSession.java
index 72b3be3..408c619 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParserSession.java
@@ -135,7 +135,7 @@ public final class HtmlParserSession extends 
XmlParserSession {
                        if (sType.isObject() || sType.isCharSequence())
                                o = text;
                        else if (sType.isChar())
-                               o = text.charAt(0);
+                               o = parseCharacter(text);
                        else if (sType.isBoolean())
                                o = Boolean.parseBoolean(text);
                        else if (sType.isNumber())
@@ -153,7 +153,7 @@ public final class HtmlParserSession extends 
XmlParserSession {
                        if (sType.isObject() || sType.isCharSequence())
                                o = text;
                        else if (sType.isChar())
-                               o = text.charAt(0);
+                               o = parseCharacter(text);
                        else if (sType.canCreateNewInstanceFromString(outer))
                                o = sType.newInstanceFromString(outer, text);
                        else if (sType.canCreateNewInstanceFromNumber(outer))
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ClassUtils.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ClassUtils.java
index da6c49b..5421f6d 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ClassUtils.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ClassUtils.java
@@ -1277,8 +1277,12 @@ public final class ClassUtils {
                        return (Constructor<T>)bestMatch;
                } 
                
+               final boolean isMemberClass = c.isMemberClass() && ! 
isStatic(c);
                for (Constructor<?> n : c.getConstructors()) {
-                       if (argsMatch(n.getParameterTypes(), argTypes) && 
vis.isVisible(n)) {
+                       Class<?>[] paramTypes = n.getParameterTypes();
+                       if (isMemberClass)
+                               paramTypes = Arrays.copyOfRange(paramTypes, 1, 
paramTypes.length);
+                       if (argsMatch(paramTypes, argTypes) && 
vis.isVisible(n)) {
                                CONSTRUCTOR_CACHE.put(c, new 
ConstructorCacheEntry(c, n));
                                return (Constructor<T>)n;
                        }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
index 9ec58cc..d3c50d1 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
@@ -211,7 +211,25 @@ public final class StringUtils {
        private static final Pattern fpRegex = Pattern.compile(
                
"[+-]?(NaN|Infinity|((((\\p{Digit}+)(\\.)?((\\p{Digit}+)?)([eE][+-]?(\\p{Digit}+))?)|(\\.((\\p{Digit}+))([eE][+-]?(\\p{Digit}+))?)|(((0[xX](\\p{XDigit}+)(\\.)?)|(0[xX](\\p{XDigit}+)?(\\.)(\\p{XDigit}+)))[pP][+-]?(\\p{Digit}+)))[fFdD]?))[\\x00-\\x20]*"
        );
-
+       
+       /**
+        * Converts a <code>String</code> to a <code>Character</code>
+        * 
+        * @param o The string to convert.
+        * @return The first character of the string if the string is of length 
0, or <jk>null</jk> if the string is <jk>null</jk> or empty.
+        * @throws ParseException If string has a length greater than 1.
+        */
+       public static Character parseCharacter(Object o) throws ParseException {
+               if (o == null)
+                       return null;
+               String s = o.toString();
+               if (s.length() == 0)
+                       return null;
+               if (s.length() == 1)
+                       return s.charAt(0);
+               throw new ParseException("Invalid character: ''{0}''", s);
+       }
+       
        /**
         * Returns <jk>true</jk> if this string can be parsed by {@link 
#parseNumber(String, Class)}.
         * 
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/Transform.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/Transform.java
index 9d673aa..c33ea6c 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/Transform.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/Transform.java
@@ -18,7 +18,7 @@ package org.apache.juneau.internal;
  * @param <I> Input type.
  * @param <O> Output type.
  */
-public interface Transform<I,O> {
+public abstract class Transform<I,O> {
        
        /**
         * Method for instantiating an object from another object.
@@ -26,5 +26,16 @@ public interface Transform<I,O> {
         * @param in The input object.
         * @return The output object.
         */
-       public O transform(I in);
+       public O transform(I in) {
+               return transform(null, in);
+       }
+
+       /**
+        * Method for instantiating an object from another object.
+        * 
+        * @param outer The context object. 
+        * @param in The input object.
+        * @return The output object.
+        */
+       public abstract O transform(Object outer, I in);
 }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/TransformCache.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/TransformCache.java
index 0869e05..e4fef08 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/TransformCache.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/TransformCache.java
@@ -13,6 +13,9 @@
 package org.apache.juneau.internal;
 
 import java.util.concurrent.*;
+
+import static org.apache.juneau.internal.ClassUtils.*;
+
 import java.lang.reflect.*;
 import java.util.*;
 
@@ -27,7 +30,7 @@ public class TransformCache {
         */
        public static final Transform<Object,Object> NULL = new 
Transform<Object,Object>() {
                @Override
-               public Object transform(Object in) {
+               public Object transform(Object outer, Object in) {
                        return null;
                }
        };
@@ -38,14 +41,14 @@ public class TransformCache {
                // TimeZone doesn't follow any standard conventions.
                add(String.class, TimeZone.class,
                        new Transform<String,TimeZone>() {
-                               @Override public TimeZone transform(String in) {
+                               @Override public TimeZone transform(Object 
outer, String in) {
                                        return TimeZone.getTimeZone(in);
                                }
                        }
                );
                add(TimeZone.class, String.class, 
                        new Transform<TimeZone,String>() {
-                               @Override public String transform(TimeZone in) {
+                               @Override public String transform(Object outer, 
TimeZone in) {
                                        return in.getID();
                                }
                        }
@@ -55,7 +58,7 @@ public class TransformCache {
                add(String.class, Locale.class,
                        new Transform<String,Locale>() {
                                @Override
-                               public Locale transform(String in) {
+                               public Locale transform(Object outer, String 
in) {
                                        return 
Locale.forLanguageTag(in.replace('_', '-'));
                                }
                        }
@@ -113,7 +116,7 @@ public class TransformCache {
                
                if (ic == oc) {
                        t = new Transform<I,O>() {
-                               @Override public O transform(I in) {
+                               @Override public O transform(Object outer, I 
in) {
                                        return (O)in;
                                }
                        };
@@ -121,7 +124,7 @@ public class TransformCache {
                        if (oc.isEnum()) {
                                t = new Transform<String,O>() {
                                        @Override
-                                       public O transform(String in) {
+                                       public O transform(Object outer, String 
in) {
                                                return (O)Enum.valueOf((Class<? 
extends Enum>)oc, in);
                                        }
                                };
@@ -130,7 +133,7 @@ public class TransformCache {
                                if (fromStringMethod != null) {
                                        t = new Transform<String,O>() {
                                                @Override
-                                               public O transform(String in) {
+                                               public O transform(Object 
outer, String in) {
                                                        try {
                                                                return 
(O)fromStringMethod.invoke(null, in);
                                                        } catch (Exception e) {
@@ -150,7 +153,7 @@ public class TransformCache {
                                final Method cm = createMethod;
                                t = new Transform<I,O>() {
                                        @Override
-                                       public O transform(I in) {
+                                       public O transform(Object context, I 
in) {
                                                try {
                                                        return 
(O)cm.invoke(null, in);
                                                } catch (Exception e) {
@@ -160,11 +163,14 @@ public class TransformCache {
                                };
                        } else {
                                final Constructor<?> c = 
ClassUtils.findPublicConstructor(oc, ic);
+                               final boolean isMemberClass = 
oc.isMemberClass() && ! isStatic(oc);
                                if (c != null && ! ClassUtils.isDeprecated(c)) {
                                        t = new Transform<I,O>() {
                                                @Override
-                                               public O transform(I in) {
+                                               public O transform(Object 
outer, I in) {
                                                        try {
+                                                               if 
(isMemberClass)
+                                                                       return 
(O)c.newInstance(outer, in);
                                                                return 
(O)c.newInstance(in);
                                                        } catch (Exception e) {
                                                                throw new 
RuntimeException(e);
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParserSession.java
index 0694963..0dc02f7 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParserSession.java
@@ -155,7 +155,7 @@ public final class JsonParserSession extends 
ReaderParserSession {
                        } else if (c == '\'' || c == '"') {
                                o = parseString(r);
                                if (sType.isChar())
-                                       o = o.toString().charAt(0);
+                                       o = parseCharacter(o);
                        } else if (c >= '0' && c <= '9' || c == '-' || c == 
'.') {
                                o = parseNumber(r, null);
                        } else if (c == 't') {
@@ -170,7 +170,7 @@ public final class JsonParserSession extends 
ReaderParserSession {
                } else if (sType.isCharSequence()) {
                        o = parseString(r);
                } else if (sType.isChar()) {
-                       o = parseString(r).charAt(0);
+                       o = parseCharacter(parseString(r));
                } else if (sType.isNumber()) {
                        o = parseNumber(r, (Class<? extends 
Number>)sType.getInnerClass());
                } else if (sType.isMap()) {
@@ -293,7 +293,6 @@ public final class JsonParserSession extends 
ReaderParserSession {
                }
        }
 
-
        private <K,V> Map<K,V> parseIntoMap2(ParserReader r, Map<K,V> m, 
ClassMeta<K> keyType,
                        ClassMeta<V> valueType, BeanPropertyMeta pMeta) throws 
Exception {
 
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSession.java
index b03477e..475909a 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSession.java
@@ -693,7 +693,7 @@ public abstract class ParserSession extends BeanSession {
 
                Object o = s;
                if (sType.isChar())
-                       o = s.charAt(0);
+                       o = parseCharacter(s);
                else if (sType.isNumber())
                        if (type.canCreateNewInstanceFromNumber(outer))
                                o = type.newInstanceFromNumber(this, outer, 
parseNumber(s, type.getNewInstanceFromNumberClass()));
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParserSession.java
index 7dfc149..6b2e2f4 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParserSession.java
@@ -186,8 +186,7 @@ public class UonParserSession extends ReaderParserSession {
                } else if (sType.isCharSequence()) {
                        o = parseString(r, isUrlParamValue);
                } else if (sType.isChar()) {
-                       String s = parseString(r, isUrlParamValue);
-                       o = s == null ? null : s.charAt(0);
+                       o = parseCharacter(parseString(r, isUrlParamValue));
                } else if (sType.isNumber()) {
                        o = parseNumber(r, (Class<? extends 
Number>)sType.getInnerClass());
                } else if (sType.isMap()) {
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParserSession.java
index ffd936c..5c4597e 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParserSession.java
@@ -334,7 +334,7 @@ public class XmlParserSession extends ReaderParserSession {
                        else if (jsonType == STRING) {
                                o = getElementText(r);
                                if (sType.isChar())
-                                       o = o.toString().charAt(0);
+                                       o = parseCharacter(o);
                        }
                        else if (jsonType == NUMBER)
                                o = parseNumber(getElementText(r), null);
@@ -347,8 +347,7 @@ public class XmlParserSession extends ReaderParserSession {
                } else if (sType.isCharSequence()) {
                        o = getElementText(r);
                } else if (sType.isChar()) {
-                       String s = getElementText(r);
-                       o = s.length() == 0 ? 0 : s.charAt(0);
+                       o = parseCharacter(getElementText(r));
                } else if (sType.isMap()) {
                        Map m = (sType.canCreateNewInstance(outer) ? 
(Map)sType.newInstance(outer) : new ObjectMap(this));
                        o = parseIntoMap(r, m, sType.getKeyType(), 
sType.getValueType(), pMeta);
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/yaml/proto/YamlParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/yaml/proto/YamlParserSession.java
index de9e3be..54f2ce2 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/yaml/proto/YamlParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/yaml/proto/YamlParserSession.java
@@ -148,7 +148,7 @@ public final class YamlParserSession extends 
ReaderParserSession {
                        } else if (c == '\'' || c == '"') {
                                o = parseString(r);
                                if (sType.isChar())
-                                       o = o.toString().charAt(0);
+                                       o = parseCharacter(o);
                        } else if (c >= '0' && c <= '9' || c == '-' || c == 
'.') {
                                o = parseNumber(r, null);
                        } else if (c == 't') {
@@ -163,7 +163,7 @@ public final class YamlParserSession extends 
ReaderParserSession {
                } else if (sType.isCharSequence()) {
                        o = parseString(r);
                } else if (sType.isChar()) {
-                       o = parseString(r).charAt(0);
+                       o = parseCharacter(parseString(r));
                } else if (sType.isNumber()) {
                        o = parseNumber(r, (Class<? extends 
Number>)sType.getInnerClass());
                } else if (sType.isMap()) {
diff --git 
a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/ParamsResource.java
 
b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/ParamsResource.java
index e15ca28..d9d1270 100644
--- 
a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/ParamsResource.java
+++ 
b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/ParamsResource.java
@@ -19,12 +19,10 @@ import java.io.*;
 import java.util.*;
 
 import javax.servlet.*;
-import javax.servlet.http.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.config.*;
 import org.apache.juneau.dto.swagger.*;
-import org.apache.juneau.examples.addressbook.*;
 import org.apache.juneau.http.*;
 import org.apache.juneau.httppart.*;
 import org.apache.juneau.json.*;
@@ -51,92 +49,6 @@ public class ParamsResource extends BasicRestServlet {
        private static final long serialVersionUID = 1L;
 
        
//====================================================================================================
-       // Basic tests
-       
//====================================================================================================
-       @RestMethod(name=GET, path="/")
-       public void doGet(RestResponse res) {
-               res.setOutput(GET);
-       }
-
-       @RestMethod(name=GET, path="/get1")
-       public String doGet1() {
-               return "GET /get1";
-       }
-
-       @RestMethod(name=GET, path="/get1/{foo}")
-       public void doGet1a(RestResponse res, @Path("foo") String foo) {
-               res.setOutput("GET /get1a " + foo);
-       }
-
-       @RestMethod(name=GET, path="/get1/{foo}/{bar}")
-       public void doGet1b(RestResponse res, @Path("foo") String foo, 
@Path("bar") String bar) {
-               res.setOutput("GET /get1b " + foo + "," + bar);
-       }
-
-       @RestMethod(name=GET, path="/get3/{foo}/{bar}/*")
-       public void doGet3(HttpServletRequest reqx, HttpServletResponse resx, 
@Path("foo") String foo, @Path("bar") int bar) {
-               RestRequest req = (RestRequest)reqx;
-               RestResponse res = (RestResponse)resx;
-               res.setOutput("GET /get3/"+foo+"/"+bar+" 
remainder="+req.getPathMatch().getRemainder());
-       }
-
-       // Test method name with overlapping name, remainder allowed.
-       @RestMethod(name="GET2")
-       public void get2(RestRequest req, RestResponse res) {
-               res.setOutput("GET2 
remainder="+req.getPathMatch().getRemainder());
-       }
-
-       // Default POST
-       @RestMethod(name=POST)
-       public void doPost(RestRequest req, RestResponse res) {
-               res.setOutput("POST 
remainder="+req.getPathMatch().getRemainder());
-       }
-
-       // Bean parameter
-       @RestMethod(name=POST, path="/person/{person}")
-       public void doPost(RestRequest req, RestResponse res, @Path("person") 
Person p) {
-               res.setOutput("POST 
/person/{name="+p.name+",birthDate.year="+p.birthDate.get(Calendar.YEAR)+"} 
remainder="+req.getPathMatch().getRemainder());
-       }
-
-       // Various primitive types
-       @RestMethod(name=PUT, 
path="/primitives/{xInt}/{xShort}/{xLong}/{xChar}/{xFloat}/{xDouble}/{xByte}/{xBoolean}")
-       public void doPut1(
-                       RestResponse res, 
-                       @Path("xInt") int xInt, 
-                       @Path("xShort") short xShort, 
-                       @Path("xLong") long xLong, 
-                       @Path("xChar") char xChar, 
-                       @Path("xFloat") float xFloat, 
-                       @Path("xDouble") double xDouble, 
-                       @Path("xByte") byte xByte, 
-                       @Path("xBoolean") boolean xBoolean
-               ) {
-               res.setOutput("PUT 
/primitives/"+xInt+"/"+xShort+"/"+xLong+"/"+xChar+"/"+xFloat+"/"+xDouble+"/"+xByte+"/"+xBoolean);
-       }
-
-       // Various primitive objects
-       @RestMethod(name=PUT, 
path="/primitiveObjects/{xInt}/{xShort}/{xLong}/{xChar}/{xFloat}/{xDouble}/{xByte}/{xBoolean}")
-       public void doPut2(
-                       RestResponse res, 
-                       @Path("xInt") Integer xInt, 
-                       @Path("xShort") Short xShort, 
-                       @Path("xLong") Long xLong, 
-                       @Path("xChar") Character xChar, 
-                       @Path("xFloat") Float xFloat, 
-                       @Path("xDouble") Double xDouble, 
-                       @Path("xByte") Byte xByte, 
-                       @Path("xBoolean") Boolean xBoolean
-               ) {
-               res.setOutput("PUT 
/primitiveObjects/"+xInt+"/"+xShort+"/"+xLong+"/"+xChar+"/"+xFloat+"/"+xDouble+"/"+xByte+"/"+xBoolean);
-       }
-
-       // Object with forString(String) method
-       @RestMethod(name=PUT, path="/uuid/{uuid}")
-       public void doPut1(RestResponse res, @Path("uuid") UUID uuid) {
-               res.setOutput("PUT /uuid/"+uuid);
-       }
-
-       
//====================================================================================================
        // @FormData annotation - GET
        
//====================================================================================================
        @RestMethod(name=GET, path="/testParamGet/*")
@@ -245,21 +157,6 @@ public class ParamsResource extends BasicRestServlet {
        }
 
        
//====================================================================================================
-       // Form POSTS with @Body parameter
-       
//====================================================================================================
-       @RestMethod(name=POST, path="/testFormPostAsContent/*")
-       public String testFormPostAsContent(@Body Test6Bean bean,
-                       @HasQuery("p1") boolean hqp1, @HasQuery("p2") boolean 
hqp2,
-                       @Query("p1") String qp1, @Query("p2") int qp2) throws 
Exception {
-               return 
"bean=["+JsonSerializer.DEFAULT_LAX.toString(bean)+"],qp1=["+qp1+"],qp2=["+qp2+"],hqp1=["+hqp1+"],hqp2=["+hqp2+"]";
-       }
-
-       public static class Test6Bean {
-               public String p1;
-               public int p2;
-       }
-
-       
//====================================================================================================
        // Test @FormData and @Query annotations when using multi-part 
parameters (e.g. &key=val1,&key=val2).
        
//====================================================================================================
        @RestMethod(name=GET, path="/testMultiPartParams")
diff --git 
a/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/ParamsTest.java
 
b/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/ParamsTest.java
index 72cd276..723a5fd 100644
--- 
a/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/ParamsTest.java
+++ 
b/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/ParamsTest.java
@@ -12,8 +12,6 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.rest.test;
 
-import static javax.servlet.http.HttpServletResponse.*;
-import static org.apache.juneau.microservice.testutils.TestUtils.*;
 import static org.junit.Assert.*;
 
 import java.io.*;
@@ -30,149 +28,10 @@ import org.junit.*;
 public class ParamsTest extends RestTestcase {
 
        private static String URL = "/testParams";
-       private static boolean debug = false;
 
        private static RestClient CLIENT = TestMicroservice.DEFAULT_CLIENT;
 
        
//====================================================================================================
-       // Basic tests
-       
//====================================================================================================
-       @Test
-       public void testBasic() throws Exception {
-               RestClient client = TestMicroservice.DEFAULT_CLIENT;
-               RestCall r;
-
-               //              @Override
-               //              @RestMethod(name=GET,pattern="/")
-               //              public void doGet(RestRequest req, RestResponse 
res) {
-               //                      res.setOutput("No args");
-               //              }
-               r = client.doGet(URL);
-               assertEquals("GET", r.getResponse(String.class));
-
-               r = client.doGet(URL + "/getx?noTrace=true");
-               try {
-                       r.connect();
-                       fail("Connection should have failed.");
-               } catch (RestCallException e) {
-                       checkErrorResponse(debug, e, SC_NOT_FOUND, "Method 
'GET' not found on resource with matching pattern on path '/getx'");
-               }
-
-               //      @RestMethod(name=GET,pattern="/get1")
-               //      public void doGet1(RestRequest req, RestResponse res) {
-               //              res.setOutput("/get1");
-               //      }
-               r = client.doGet(URL + "/get1");
-               assertEquals("GET /get1", r.getResponse(String.class));
-
-               r = client.doGet(URL + "/get1a?noTrace=true");
-               try {
-                       r.connect();
-                       fail("Connection should have failed.");
-               } catch (RestCallException e) {
-                       checkErrorResponse(debug, e, SC_NOT_FOUND, "Method 
'GET' not found on resource with matching pattern on path '/get1a'");
-               }
-
-               //      @RestMethod(name=GET,pattern="/get1/{foo}")
-               //      public void doGet(RestRequest req, RestResponse res, 
String foo) {
-               //              res.setOutput("/get1/" + foo);
-               //      }
-               r = client.doGet(URL + "/get1/foo");
-               assertEquals("GET /get1a foo", r.getResponse(String.class));
-
-               // URL-encoded part should not get decoded before finding 
method to invoke.
-               // This should match /get1/{foo} and not /get1/{foo}/{bar}
-               // NOTE:  When testing on Tomcat, must specify the following 
system property:
-               // 
-Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
-               String x = "x%2Fy";  // [x/y]
-               r = client.doGet(URL + "/get1/"+x);
-               assertEquals("GET /get1a x/y", r.getResponse(String.class));
-
-               r = client.doGet(URL + "/get1/"+x+"/"+x);
-               assertEquals("GET /get1b x/y,x/y", r.getResponse(String.class));
-
-               r = client.doGet(URL + "/get1/foo");
-               assertEquals("GET /get1a foo", r.getResponse(String.class));
-
-               r = client.doGet(URL + "/get1/foo/bar/baz?noTrace=true");
-               try {
-                       r.connect();
-                       fail("Connection should have failed.");
-               } catch (RestCallException e) {
-                       checkErrorResponse(debug, e, SC_NOT_FOUND, "Method 
'GET' not found on resource with matching pattern on path '/get1/foo/bar/baz'");
-               }
-
-               //      @RestMethod(name=GET,pattern="/get3/{foo}/{bar}/*")
-               //      public void doGet3(RestRequest req, RestResponse res, 
String foo, int bar) {
-               //              res.setOutput("/get3/"+foo+"/"+bar+", 
remainder="+req.getRemainder());
-               //      }
-               r = client.doGet(URL + "/get3/foo/123");
-               assertEquals("GET /get3/foo/123 remainder=null", 
r.getResponse(String.class));
-
-               r = client.doGet(URL + "/get3/foo/123/xxx");
-               assertEquals("GET /get3/foo/123 remainder=xxx", 
r.getResponse(String.class));
-
-               //      // Test method name with overlapping name, remainder 
allowed.
-               //      @RestMethod(name="GET2")
-               //      public void get2(RestRequest req, RestResponse res) {
-               //              res.setOutput("GET2, 
remainder="+req.getRemainder());
-               //      }
-               r = client.doGet(URL + "?method=get2");
-               assertEquals("GET2 remainder=null", 
r.getResponse(String.class));
-               r = client.doGet(URL + "/foo/bar?method=get2");
-               assertEquals("GET2 remainder=foo/bar", 
r.getResponse(String.class));
-               r = client.doGet(URL + "/foo/bar?method=GET2");
-               assertEquals("GET2 remainder=foo/bar", 
r.getResponse(String.class));
-
-               //      // Default POST
-               //      @Override
-               //      public void doPost(RestRequest req, RestResponse res) {
-               //              res.setOutput("POST, 
remainder="+req.getRemainder());
-               //      }
-               r = client.doPost(URL, "");
-               assertEquals("POST remainder=null", 
r.getResponse(String.class));
-               r = client.doPost(URL + "/foo", "");
-               assertEquals("POST remainder=foo", r.getResponse(String.class));
-
-               //      // Bunch of different argument types
-               //      @RestMethod(name=POST,pattern="/person/{person}")
-               //      public void doPost(RestRequest req, RestResponse res, 
Person p) {
-               //              res.setOutput("POST, /person, name="+p.name+", 
age="+p.age+" remainder="+req.getRemainder());
-               //      }
-               r = client.doPost(URL + 
"/person/(name='John+Smith',birthDate='Jan+12,+1952')", "");
-               assertEquals("POST /person/{name=John 
Smith,birthDate.year=1952} remainder=null", r.getResponse(String.class));
-
-               // Fall through to top-level POST
-               r = client.doPost(URL + 
"/person/(name:'John+Smith',age:123)/foo", "");
-               assertEquals("POST remainder=person/(name:'John 
Smith',age:123)/foo", r.getResponse(String.class));
-
-               //      // Various primitive types
-               //      
@RestMethod(name=PUT,pattern="/primitives/{xInt}.{xShort},{xLong}/{xChar}/{xFloat}/{xDouble}/{xByte}/{xBoolean}")
-               //      public void doPut1(RestRequest req, RestResponse res, 
int xInt, short xShort, long xLong, char xChar, float xFloat, double xDouble, 
byte xByte, boolean xBoolean) {
-               //              res.setOutput("PUT, 
/primitives/"+xInt+"."+xShort+","+xLong+"/"+xChar+"/"+xFloat+"/"+xDouble+"/"+xByte+"/"+xBoolean);
-               //      }
-               r = client.doPut(URL + "/primitives/1/2/3/x/4/5/6/true", "");
-               assertEquals("PUT /primitives/1/2/3/x/4.0/5.0/6/true", 
r.getResponse(String.class));
-
-               //      // Various primitive objects
-               //      
@RestMethod(name=PUT,pattern="/primitiveObjects/{xInt}/{xShort}/{xLong}/{xChar}/{xFloat}/{xDouble}/{xByte}/{xBoolean}")
-               //      public void doPut1(RestRequest req, RestResponse res, 
Integer xInt, Short xShort, Long xLong, Character xChar, Float xFloat, Double 
xDouble, Byte xByte, Boolean xBoolean) {
-               //              res.setOutput("PUT 
/primitives/"+xInt+"/"+xShort+"/"+xLong+"/"+xChar+"/"+xFloat+"/"+xDouble+"/"+xByte+"/"+xBoolean);
-               //      }
-               r = client.doPut(URL + "/primitiveObjects/1/2/3/x/4/5/6/true", 
"");
-               assertEquals("PUT /primitiveObjects/1/2/3/x/4.0/5.0/6/true", 
r.getResponse(String.class));
-
-               //      // Object with forString(String) method
-               //      @RestMethod(name=PUT,pattern="/uuid/{uuid}")
-               //      public void doPut1(RestRequest req, RestResponse res, 
UUID uuid) {
-               //              res.setOutput("PUT /uuid/"+uuid);
-               //      }
-               UUID uuid = UUID.randomUUID();
-               r = client.doPut(URL + "/uuid/"+uuid, "");
-               assertEquals("PUT /uuid/"+uuid, r.getResponse(String.class));
-       }
-
-       
//====================================================================================================
        // @FormData annotation - GET
        
//====================================================================================================
        @Test
@@ -526,29 +385,6 @@ public class ParamsTest extends RestTestcase {
                client.closeQuietly();
        }
 
-       
//====================================================================================================
-       // Form POSTS with @Body parameter
-       
//====================================================================================================
-       @Test
-       public void testFormPostAsContent() throws Exception {
-               RestClient client = 
TestMicroservice.client().accept("text/plain").build();
-               String r;
-               String url = URL + "/testFormPostAsContent";
-
-               r = client.doFormPost(url, new 
ObjectMap("{p1:'p1',p2:2}")).getResponseAsString();
-               
assertEquals("bean=[{p1:'p1',p2:2}],qp1=[null],qp2=[0],hqp1=[false],hqp2=[false]",
 r);
-
-               r = client.doFormPost(url, new 
ObjectMap("{}")).getResponseAsString();
-               
assertEquals("bean=[{p2:0}],qp1=[null],qp2=[0],hqp1=[false],hqp2=[false]", r);
-
-               r = client.doFormPost(url+"?p1=p3&p2=4", new 
ObjectMap("{p1:'p1',p2:2}")).getResponseAsString();
-               
assertEquals("bean=[{p1:'p1',p2:2}],qp1=[p3],qp2=[4],hqp1=[true],hqp2=[true]", 
r);
-
-               r = client.doFormPost(url+"?p1=p3&p2=4", new 
ObjectMap("{}")).getResponseAsString();
-               
assertEquals("bean=[{p2:0}],qp1=[p3],qp2=[4],hqp1=[true],hqp2=[true]", r);
-
-               client.closeQuietly();
-       }
 
        
//====================================================================================================
        // Test @FormData and @Query annotations when using multi-part 
parameters (e.g. &key=val1,&key=val2).
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockServletRequest.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockServletRequest.java
index 5369758..a615df7 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockServletRequest.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockServletRequest.java
@@ -187,7 +187,7 @@ public class MockServletRequest implements 
HttpServletRequest {
         * @return This object (for method chaining).
         */
        public MockServletRequest uri(String uri) {
-               this.uri = uri;
+               this.uri = emptyIfNull(uri);
                return this;
        }
        
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/DefaultHandler.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/DefaultHandler.java
index 9cad6ea..b1e51b5 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/DefaultHandler.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/DefaultHandler.java
@@ -15,6 +15,7 @@ package org.apache.juneau.rest.response;
 import java.io.*;
 import java.util.*;
 
+import org.apache.juneau.*;
 import org.apache.juneau.http.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.rest.*;
@@ -48,6 +49,7 @@ public class DefaultHandler implements ResponseHandler {
                SerializerGroup g = res.getSerializers();
                String accept = req.getHeaders().getString("Accept", "");
                SerializerMatch sm = g.getSerializerMatch(accept);
+               
                if (sm != null) {
                        Serializer s = sm.getSerializer();
                        MediaType mediaType = res.getMediaType();
@@ -95,6 +97,16 @@ public class DefaultHandler implements ResponseHandler {
                        } catch (SerializeException e) {
                                throw new InternalServerError(e);
                        }
+               
+               // Non-existent Accept or plain/text can just be serialized 
as-is.
+               } else if ("".equals(accept) || "plain/text".equals(accept)) {
+                       FinishablePrintWriter w = res.getNegotiatedWriter();
+                       ClassMeta<?> cm = 
req.getBeanSession().getClassMetaForObject(output);
+                       if (cm != null) 
+                               w.append(cm.toString(output));
+                       w.flush();
+                       w.finish();
+               
                } else {
                        throw new NotAcceptable(
                                "Unsupported media-type in request header 
''Accept'': ''{0}''\n\tSupported media-types: {1}",
diff --git 
a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/DefaultContentTypesTest.java
 
b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/DefaultContentTypesTest.java
similarity index 97%
rename from 
juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/DefaultContentTypesTest.java
rename to 
juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/DefaultContentTypesTest.java
index 3a9907b..9206686 100644
--- 
a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/DefaultContentTypesTest.java
+++ 
b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/DefaultContentTypesTest.java
@@ -10,12 +10,13 @@
 // * "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.rest.annotation;
+package org.apache.juneau.rest;
 
 import static org.apache.juneau.http.HttpMethodName.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.parser.*;
+import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.rest.mock.*;
 import org.apache.juneau.serializer.*;
 import org.junit.*;
diff --git 
a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/StatusCodesTest.java
 
b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/StatusCodesTest.java
similarity index 96%
copy from 
juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/StatusCodesTest.java
copy to 
juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/StatusCodesTest.java
index 546844a..ce9d03b 100644
--- 
a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/StatusCodesTest.java
+++ 
b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/StatusCodesTest.java
@@ -10,12 +10,13 @@
 // * "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.rest.annotation;
+package org.apache.juneau.rest;
 
 import static org.apache.juneau.http.HttpMethodName.*;
 
 import java.io.*;
 
+import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.rest.mock.*;
 import org.junit.*;
 
diff --git 
a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/BodyAnnotationTest.java
 
b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/BodyAnnotationTest.java
index 8836379..c343f87 100644
--- 
a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/BodyAnnotationTest.java
+++ 
b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/BodyAnnotationTest.java
@@ -38,71 +38,57 @@ public class BodyAnnotationTest {
        
        @RestResource(serializers=JsonSerializer.Simple.class, 
parsers=JsonParser.class)
        public static class A {
-               
                @RestMethod(name=PUT, path="/String")
                public String a01(@Body String b) {
                        return b;
                }
-
                @RestMethod(name=PUT, path="/Integer")
                public Integer a02(@Body Integer b) {
                        return b;
                }
-
                @RestMethod(name=PUT, path="/int")
                public Integer a03(@Body int b) {
                        return b;
                }
-
                @RestMethod(name=PUT, path="/Boolean")
                public Boolean a04(@Body Boolean b) {
                        return b;
                }
-
                @RestMethod(name=PUT, path="/boolean")
                public Boolean a05(@Body boolean b) {
                        return b;
                }
-
                @RestMethod(name=PUT, path="/float")
                public float a06(@Body float f) {
                        return f;
                }
-
                @RestMethod(name=PUT, path="/Float")
                public Float a07(@Body Float f) {
                        return f;
                }
-               
                @RestMethod(name=PUT, path="/Map")
                public TreeMap<String,Integer> a08(@Body 
TreeMap<String,Integer> m) {
                        return m;
                }
-
                @RestMethod(name=PUT, path="/enum")
                public TestEnum a09(@Body TestEnum e) {
                        return e;
                }
-
                public static class A11 {
                        public String f1;
                }
-               
                @RestMethod(name=PUT, path="/Bean")
                public A11 a11(@Body A11 b) {
                        return b;
                }
-
                @RestMethod(name=PUT, path="/InputStream")
                public String a12(@Body InputStream b) throws Exception {
                        return IOUtils.read(b);
                }
-
                @RestMethod(name=PUT, path="/Reader")
                public String a13(@Body Reader b) throws Exception {
                        return IOUtils.read(b);
                }
-
                @RestMethod(name=PUT, path="/InputStreamTransform")
                public A14 a14(@Body A14 b) throws Exception {
                        return b;
@@ -112,7 +98,6 @@ public class BodyAnnotationTest {
                        public A14(InputStream in) throws Exception { this.s = 
IOUtils.read(in); }
                        @Override public String toString() { return s; }
                }
-               
                @RestMethod(name=PUT, path="/ReaderTransform")
                public A15 a15(@Body A15 b) throws Exception {
                        return b;
@@ -122,7 +107,6 @@ public class BodyAnnotationTest {
                        public A15(Reader in) throws Exception { this.s = 
IOUtils.read(in); }
                        @Override public String toString() { return s; }
                }
-               
                @RestMethod(name=PUT, path="/StringTransform")
                public A16 a16(@Body A16 b) throws Exception { return b; }
                public static class A16 {
@@ -130,9 +114,7 @@ public class BodyAnnotationTest {
                        public A16(String s) throws Exception { this.s = s; }
                        @Override public String toString() { return s; }
                }
-               
        }
-       
        private static MockRest a = MockRest.create(A.class);
        
        @Test
@@ -279,7 +261,6 @@ public class BodyAnnotationTest {
        
        @RestResource(serializers=JsonSerializer.Simple.class, 
parsers=JsonParser.class)
        public static class B {
-               
                @RestMethod(name=PUT, path="/StringTransform")
                public B01 b01(B01 b) {
                        return b;
@@ -290,7 +271,6 @@ public class BodyAnnotationTest {
                        public B01(String val) { this.val = val; }
                        @Override public String toString() { return val; }
                }
-               
                @RestMethod(name=PUT, path="/Bean")
                public B02 b02(B02 b) {
                        return b;
@@ -299,14 +279,12 @@ public class BodyAnnotationTest {
                public static class B02 {
                        public String f1;
                }
-               
                @RestMethod(name=PUT, path="/BeanList")
                public B03 b03(B03 b) {
                        return b;
                }
                @Body
                public static class B03 extends LinkedList<B02> {}
-               
                @RestMethod(name=PUT, path="/InputStreamTransform")
                public B04 b04(B04 b) throws Exception {
                        return b;
@@ -317,7 +295,6 @@ public class BodyAnnotationTest {
                        public B04(InputStream in) throws Exception { this.s = 
IOUtils.read(in); }
                        @Override public String toString() { return s; }
                }
-               
                @RestMethod(name=PUT, path="/ReaderTransform")
                public B05 b05(B05 b) throws Exception {
                        return b;
@@ -328,9 +305,7 @@ public class BodyAnnotationTest {
                        public B05(Reader in) throws Exception { this.s = 
IOUtils.read(in); }
                        @Override public String toString() { return s; }
                }
-               
        }
-       
        private static MockRest b = MockRest.create(B.class);
 
        @Test
@@ -481,22 +456,18 @@ public class BodyAnnotationTest {
        
        @RestResource
        public static class D {
-               
                @RestMethod(name=PUT, path="/String")
                public Reader d01(@Body Reader b) throws Exception {
                        return b;
                }
-
                @RestMethod(name=PUT, path="/InputStream")
                public InputStream d02(@Body InputStream b) throws Exception {
                        return b;
                }
-
                @RestMethod(name=PUT, path="/Reader")
                public Reader d03(@Body Reader b) throws Exception {
                        return b;
                }
-               
                @RestMethod(name=PUT, path="/StringTransform")
                public Reader d04(@Body D04 b) throws Exception {
                        return new StringReader(b.toString());
@@ -506,7 +477,6 @@ public class BodyAnnotationTest {
                        public D04(String in) throws Exception { this.s = in; }
                        @Override public String toString() { return s; }
                }
-               
                @RestMethod(name=PUT, path="/InputStreamTransform")
                public Reader d05(@Body D05 b) throws Exception {
                        return new StringReader(b.toString());
@@ -516,7 +486,6 @@ public class BodyAnnotationTest {
                        public D05(InputStream in) throws Exception { this.s = 
IOUtils.read(in); }
                        @Override public String toString() { return s; }
                }
-               
                @RestMethod(name=PUT, path="/ReaderTransform")
                public Reader d06(@Body D06 b) throws Exception {
                        return new StringReader(b.toString());
@@ -526,7 +495,6 @@ public class BodyAnnotationTest {
                        public D06(Reader in) throws Exception{ this.s = 
IOUtils.read(in); }
                        @Override public String toString() { return s; }
                }
-               
                @RestMethod(name=PUT, path="/StringTransformBodyOnPojo")
                public Reader d07(D07 b) throws Exception {
                        return new StringReader(b.toString());
@@ -537,7 +505,6 @@ public class BodyAnnotationTest {
                        public D07(String in) throws Exception { this.s = in; }
                        @Override public String toString() { return s; }
                }
-               
                @RestMethod(name=PUT, path="/InputStreamTransformBodyOnPojo")
                public Reader d08(D08 b) throws Exception {
                        return new StringReader(b.toString());
@@ -560,7 +527,6 @@ public class BodyAnnotationTest {
                        @Override public String toString() { return s; }
                }
        }
-       
        private static MockRest d = MockRest.create(D.class);
        
        @Test
@@ -643,18 +609,15 @@ public class BodyAnnotationTest {
        
        @RestResource(serializers=JsonSerializer.Simple.class, 
parsers=JsonParser.class)
        public static class E {
-       
                @RestMethod(name=PUT, path="/B")
                public DTOs.B testPojo1(@Body DTOs.B b) {
                        return b;
                }
-       
                @RestMethod(name=PUT, path="/C")
                public DTOs.C testPojo2(@Body DTOs.C c) {
                        return c;
                }
        }
-       
        private static MockRest e = MockRest.create(E.class);
        
        @Test
@@ -677,4 +640,33 @@ public class BodyAnnotationTest {
                String expected = 
"{f01:['a','b'],f02:['c','d'],f03:[1,2],f04:[3,4],f05:[['e','f'],['g','h']],f06:[['i','j'],['k','l']],f07:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f08:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f09:[[{a:'a',b:1,c:true}],[{a:'a',b:1,c:true}]],f10:[[{a:'a',b:1,c:true}],[{a:'a',b:1,c:true}]],f11:['a','b'],f12:['c','d'],f13:[1,2],f14:[3,4],f15:[['e','f'],['g','h']],f16:[['i','j'],['k','l']],f17:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f18:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}
 [...]
                e.request("PUT", "/C?body=" + 
UonSerializer.DEFAULT.serialize(DTOs.B.INSTANCE)).body("a").execute().assertBody(expected);
        }
+       
+       
+       
//====================================================================================================
+       // Form POSTS with @Body parameter
+       
//====================================================================================================
+       
+       @RestResource(serializers=JsonSerializer.class,parsers=JsonParser.class)
+       public static class F {
+               @RestMethod(name=POST, path="/*")
+               public Reader formPostAsContent(
+                               @Body F01 bean,
+                               @HasQuery("p1") boolean hqp1, @HasQuery("p2") 
boolean hqp2,
+                               @Query("p1") String qp1, @Query("p2") int qp2) 
throws Exception {
+                       return new 
StringReader("bean=["+JsonSerializer.DEFAULT_LAX.toString(bean)+"],qp1=["+qp1+"],qp2=["+qp2+"],hqp1=["+hqp1+"],hqp2=["+hqp2+"]");
+               }
+               public static class F01 {
+                       public String p1;
+                       public int p2;
+               }
+       }
+       static MockRest f = MockRest.create(F.class);
+
+       @Test
+       public void f01_formPostAsContent() throws Exception {
+               f.request("POST", 
"/").body("{p1:'p1',p2:2}").json().execute().assertBody("bean=[{p1:'p1',p2:2}],qp1=[null],qp2=[0],hqp1=[false],hqp2=[false]");
+               f.request("POST", 
"/").body("{}").json().execute().assertBody("bean=[{p2:0}],qp1=[null],qp2=[0],hqp1=[false],hqp2=[false]");
+               f.request("POST", 
"?p1=p3&p2=4").body("{p1:'p1',p2:2}").json().execute().assertBody("bean=[{p1:'p1',p2:2}],qp1=[p3],qp2=[4],hqp1=[true],hqp2=[true]");
+               f.request("POST", 
"?p1=p3&p2=4").body("{}").json().execute().assertBody("bean=[{p2:0}],qp1=[p3],qp2=[4],hqp1=[true],hqp2=[true]");
+       }
 }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/Transform.java
 
b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/FormDataAnnotationTest.java
similarity index 79%
copy from 
juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/Transform.java
copy to 
juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/FormDataAnnotationTest.java
index 9d673aa..5eda750 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/Transform.java
+++ 
b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/FormDataAnnotationTest.java
@@ -10,21 +10,14 @@
 // * "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.internal;
+package org.apache.juneau.rest.annotation;
+
+import org.junit.*;
+import org.junit.runners.*;
 
 /**
- * An interface for creating objects from other objects such as a 
<code>String</code> or <code>Reader</code>.
- * 
- * @param <I> Input type.
- * @param <O> Output type.
+ * Tests related to @FormData annotation.
  */
-public interface Transform<I,O> {
-       
-       /**
-        * Method for instantiating an object from another object.
-        * 
-        * @param in The input object.
-        * @return The output object.
-        */
-       public O transform(I in);
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class FormDataAnnotationTest {
 }
diff --git 
a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/PathAnnotationTest.java
 
b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/PathAnnotationTest.java
new file mode 100644
index 0000000..0cdb81f
--- /dev/null
+++ 
b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/PathAnnotationTest.java
@@ -0,0 +1,392 @@
+// 
***************************************************************************************************************************
+// * 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.rest.annotation;
+
+import static org.apache.juneau.http.HttpMethodName.*;
+
+import java.util.*;
+
+import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.mock.*;
+import org.junit.*;
+import org.junit.runners.*;
+
+/**
+ * Tests related to @Path annotation.
+ */
+@SuppressWarnings({"javadoc"})
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class PathAnnotationTest {
+       
+       
//=================================================================================================================
+       // Basic tests
+       
//=================================================================================================================
+
+       @RestResource
+       public static class A  {
+               @RestMethod(name=GET, path="/")
+               public void noPath(RestResponse res) {
+                       res.setOutput(GET);
+               }
+               @RestMethod(name=GET, path="/a")
+               public String simplePath() {
+                       return "GET /a";
+               }
+               @RestMethod(name=GET, path="/a/{foo}")
+               public String simplePathOneVar(RestResponse res, @Path("foo") 
String foo) {
+                       return "GET /a " + foo;
+               }
+               @RestMethod(name=GET, path="/a/{foo}/{bar}")
+               public String simplePathTwoVars(RestResponse res, @Path("foo") 
String foo, @Path("bar") String bar) {
+                       return "GET /a " + foo + "," + bar;
+               }
+               @RestMethod(name=GET, path="/a/{foo}/{bar}/*")
+               public String simplePathWithRemainder(@Path("foo") String foo, 
@Path("bar") int bar, @PathRemainder String remainder) {
+                       return "GET /a "+foo+","+bar+",r="+remainder;
+               }
+       }
+       static MockRest a = MockRest.create(A.class);
+       
+       @Test
+       public void a00_nonExistentPath() throws Exception {
+               a.request("GET", 
"/bad?noTrace=true").execute().assertStatus(404);
+       }
+       @Test
+       public void a01_noPath() throws Exception {
+               a.request("GET", null).execute().assertBody("GET");
+               a.request("GET", "").execute().assertBody("GET");
+       }
+       @Test
+       public void a02_simplePath() throws Exception {
+               a.request("GET", "/a").execute().assertBody("GET /a");
+       }
+       @Test
+       public void a03_simplePathOneVar() throws Exception {
+               a.request("GET", "/a/foo").execute().assertBody("GET /a foo");
+       }
+       @Test
+       public void a04_simplePathTwoVars() throws Exception {
+               a.request("GET", "/a/foo/bar").execute().assertBody("GET /a 
foo,bar");
+       }
+       @Test
+       public void a05_simplePathWithRemainder() throws Exception {
+               a.request("GET", "/a/foo/123/baz").execute().assertBody("GET /a 
foo,123,r=baz");
+       }
+       @Test
+       public void a06_urlEncodedPathPart() throws Exception {
+               // URL-encoded part should not get decoded before finding 
method to invoke.
+               // This should match /get1/{foo} and not /get1/{foo}/{bar}
+               // NOTE:  When testing on Tomcat, must specify the following 
system property:
+               // 
-Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
+               a.request("GET", "/a/x%2Fy").execute().assertBody("GET /a x/y");
+               a.request("GET", "/a/x%2Fy/x%2Fy").execute().assertBody("GET /a 
x/y,x/y");
+       }
+
+       
//=================================================================================================================
+       // Primitives
+       
//=================================================================================================================
+
+       @RestResource
+       public static class B  {
+               @RestMethod(name=GET, path="/int/{x}/foo")
+               public String b01(@Path("x") int x) {
+                       return String.valueOf(x);
+               }
+               @RestMethod(name=GET, path="/short/{x}/foo")
+               public String b02(@Path("x") short x) {
+                       return String.valueOf(x);
+               }
+               @RestMethod(name=GET, path="/long/{x}/foo")
+               public String b03(@Path("x") long x) {
+                       return String.valueOf(x);
+               }
+               @RestMethod(name=GET, path="/char/{x}/foo")
+               public String b04(@Path("x") char x) {
+                       return String.valueOf(x);
+               }
+               @RestMethod(name=GET, path="/float/{x}/foo")
+               public String b05(@Path("x") float x) {
+                       return String.valueOf(x);
+               }
+               @RestMethod(name=GET, path="/double/{x}/foo")
+               public String b06(@Path("x") double x) {
+                       return String.valueOf(x);
+               }
+               @RestMethod(name=GET, path="/byte/{x}/foo")
+               public String b07(@Path("x") byte x) {
+                       return String.valueOf(x);
+               }
+               @RestMethod(name=GET, path="/boolean/{x}/foo")
+               public String b08(@Path("x") boolean x) {
+                       return String.valueOf(x);
+               }
+       }       
+       static MockRest b = MockRest.create(B.class);
+
+       @Test
+       public void b01_int() throws Exception {
+               b.request("GET", "/int/123/foo").execute().assertBody("123");
+               b.request("GET", 
"/int/bad/foo?noTrace=true").execute().assertStatus(400);
+       }
+       @Test
+       public void b02_short() throws Exception {
+               b.request("GET", "/short/123/foo").execute().assertBody("123");
+               b.request("GET", 
"/short/bad/foo?noTrace=true").execute().assertStatus(400);
+       }
+       @Test
+       public void b03_long() throws Exception {
+               b.request("GET", "/long/123/foo").execute().assertBody("123");
+               b.request("GET", 
"/long/bad/foo?noTrace=true").execute().assertStatus(400);
+       }
+       @Test
+       public void b04_char() throws Exception {
+//             b.request("GET", "/char/c/foo").execute().assertBody("c");
+               b.request("GET", 
"/char/bad/foo?noTrace=true").execute().assertStatus(400);
+       }
+       @Test
+       public void b05_float() throws Exception {
+               b.request("GET", 
"/float/1.23/foo").execute().assertBody("1.23");
+               b.request("GET", 
"/float/bad/foo?noTrace=true").execute().assertStatus(400);
+       }
+       @Test
+       public void b06_double() throws Exception {
+               b.request("GET", 
"/double/1.23/foo").execute().assertBody("1.23");
+               b.request("GET", 
"/double/bad/foo?noTrace=true").execute().assertStatus(400);
+       }
+       @Test
+       public void b07_byte() throws Exception {
+               b.request("GET", "/byte/123/foo").execute().assertBody("123");
+               b.request("GET", 
"/byte/bad/foo?noTrace=true").execute().assertStatus(400);
+       }
+       @Test
+       public void b08_boolean() throws Exception {
+               b.request("GET", 
"/boolean/true/foo").execute().assertBody("true");
+               b.request("GET", 
"/boolean/bad/foo?noTrace=true").execute().assertStatus(400);
+       }
+       
+       
//=================================================================================================================
+       // Primitive objects
+       
//=================================================================================================================
+
+       @RestResource
+       public static class C  {
+               @RestMethod(name=GET, path="/Integer/{x}/foo")
+               public String c01(@Path("x") Integer x) {
+                       return String.valueOf(x);
+               }
+               @RestMethod(name=GET, path="/Short/{x}/foo")
+               public String c02(@Path("x") Short x) {
+                       return String.valueOf(x);
+               }
+               @RestMethod(name=GET, path="/Long/{x}/foo")
+               public String c03(@Path("x") Long x) {
+                       return String.valueOf(x);
+               }
+               @RestMethod(name=GET, path="/Character/{x}/foo")
+               public String c04(@Path("x") Character x) {
+                       return String.valueOf(x);
+               }
+               @RestMethod(name=GET, path="/Float/{x}/foo")
+               public String c05(@Path("x") Float x) {
+                       return String.valueOf(x);
+               }
+               @RestMethod(name=GET, path="/Double/{x}/foo")
+               public String c06(@Path("x") Double x) {
+                       return String.valueOf(x);
+               }
+               @RestMethod(name=GET, path="/Byte/{x}/foo")
+               public String c07(@Path("x") Byte x) {
+                       return String.valueOf(x);
+               }
+               @RestMethod(name=GET, path="/Boolean/{x}/foo")
+               public String c08(@Path("x") Boolean x) {
+                       return String.valueOf(x);
+               }
+       }       
+       static MockRest c = MockRest.create(C.class);
+
+       @Test
+       public void c01_Integer() throws Exception {
+               c.request("GET", 
"/Integer/123/foo").execute().assertBody("123");
+               c.request("GET", 
"/Integer/bad/foo?noTrace=true").execute().assertStatus(400);
+       }
+       @Test
+       public void c02_Short() throws Exception {
+               c.request("GET", "/Short/123/foo").execute().assertBody("123");
+               c.request("GET", 
"/Short/bad/foo?noTrace=true").execute().assertStatus(400);
+       }
+       @Test
+       public void c03_Long() throws Exception {
+               c.request("GET", "/Long/123/foo").execute().assertBody("123");
+               c.request("GET", 
"/Long/bad/foo?noTrace=true").execute().assertStatus(400);
+       }
+       @Test
+       public void c04_Char() throws Exception {
+               c.request("GET", "/Character/c/foo").execute().assertBody("c");
+               c.request("GET", 
"/Character/bad/foo?noTrace=true").execute().assertStatus(400);
+       }
+       @Test
+       public void c05_Float() throws Exception {
+               c.request("GET", 
"/Float/1.23/foo").execute().assertBody("1.23");
+               c.request("GET", 
"/Float/bad/foo?noTrace=true").execute().assertStatus(400);
+       }
+       @Test
+       public void c06_Double() throws Exception {
+               c.request("GET", 
"/Double/1.23/foo").execute().assertBody("1.23");
+               c.request("GET", 
"/Double/bad/foo?noTrace=true").execute().assertStatus(400);
+       }
+       @Test
+       public void c07_Byte() throws Exception {
+               c.request("GET", "/Byte/123/foo").execute().assertBody("123");
+               c.request("GET", 
"/Byte/bad/foo?noTrace=true").execute().assertStatus(400);
+       }
+       @Test
+       public void c08_Boolean() throws Exception {
+               c.request("GET", 
"/Boolean/true/foo").execute().assertBody("true");
+               c.request("GET", 
"/Boolean/bad/foo?noTrace=true").execute().assertStatus(400);
+       }
+
+       
//=================================================================================================================
+       // POJOs convertible from strings
+       
//=================================================================================================================
+
+       @RestResource
+       public static class D {
+               // Object with forString(String) method
+               @RestMethod(name=GET, path="/uuid/{uuid}")
+               public UUID uuid(RestResponse res, @Path("uuid") UUID uuid) {
+                       return uuid;
+               }
+       }
+       static MockRest d = MockRest.create(D.class);
+
+       @Test
+       public void d01_uuid() throws Exception {
+               UUID uuid = UUID.randomUUID();
+               d.request("GET", "/uuid/" + 
uuid).execute().assertBody(uuid.toString());
+       }
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
//=================================================================================================================
+       // Overlapping method names
+       
//=================================================================================================================
+
+//
+//             //      // Bunch of different argument types
+//             //      @RestMethod(name=POST,pattern="/person/{person}")
+//             //      public void doPost(RestRequest req, RestResponse res, 
Person p) {
+//             //              res.setOutput("POST, /person, name="+p.name+", 
age="+p.age+" remainder="+req.getRemainder());
+//             //      }
+//             r = client.doPost(URL + 
"/person/(name='John+Smith',birthDate='Jan+12,+1952')", "");
+//             assertEquals("POST /person/{name=John 
Smith,birthDate.year=1952} remainder=null", r.getResponse(String.class));
+//
+//             // Fall through to top-level POST
+//             r = client.doPost(URL + 
"/person/(name:'John+Smith',age:123)/foo", "");
+//             assertEquals("POST remainder=person/(name:'John 
Smith',age:123)/foo", r.getResponse(String.class));
+//
+//             //      // Various primitive types
+//             //      
@RestMethod(name=PUT,pattern="/primitives/{xInt}.{xShort},{xLong}/{xChar}/{xFloat}/{xDouble}/{xByte}/{xBoolean}")
+//             //      public void doPut1(RestRequest req, RestResponse res, 
int xInt, short xShort, long xLong, char xChar, float xFloat, double xDouble, 
byte xByte, boolean xBoolean) {
+//             //              res.setOutput("PUT, 
/primitives/"+xInt+"."+xShort+","+xLong+"/"+xChar+"/"+xFloat+"/"+xDouble+"/"+xByte+"/"+xBoolean);
+//             //      }
+//             r = client.doPut(URL + "/primitives/1/2/3/x/4/5/6/true", "");
+//             assertEquals("PUT /primitives/1/2/3/x/4.0/5.0/6/true", 
r.getResponse(String.class));
+//
+//             //      // Various primitive objects
+//             //      
@RestMethod(name=PUT,pattern="/primitiveObjects/{xInt}/{xShort}/{xLong}/{xChar}/{xFloat}/{xDouble}/{xByte}/{xBoolean}")
+//             //      public void doPut1(RestRequest req, RestResponse res, 
Integer xInt, Short xShort, Long xLong, Character xChar, Float xFloat, Double 
xDouble, Byte xByte, Boolean xBoolean) {
+//             //              res.setOutput("PUT 
/primitives/"+xInt+"/"+xShort+"/"+xLong+"/"+xChar+"/"+xFloat+"/"+xDouble+"/"+xByte+"/"+xBoolean);
+//             //      }
+//             r = client.doPut(URL + "/primitiveObjects/1/2/3/x/4/5/6/true", 
"");
+//             assertEquals("PUT /primitiveObjects/1/2/3/x/4.0/5.0/6/true", 
r.getResponse(String.class));
+//
+//             //      // Object with forString(String) method
+//             //      @RestMethod(name=PUT,pattern="/uuid/{uuid}")
+//             //      public void doPut1(RestRequest req, RestResponse res, 
UUID uuid) {
+//             //              res.setOutput("PUT /uuid/"+uuid);
+//             //      }
+//             UUID uuid = UUID.randomUUID();
+//             r = client.doPut(URL + "/uuid/"+uuid, "");
+//             assertEquals("PUT /uuid/"+uuid, r.getResponse(String.class));
+       }
+       
+       
+               
+//
+//             // Test method name with overlapping name, remainder allowed.
+//             @RestMethod(name="GET2")
+//             public void get2(RestRequest req, RestResponse res) {
+//                     res.setOutput("GET2 
remainder="+req.getPathMatch().getRemainder());
+//             }
+//
+//             // Default POST
+//             @RestMethod(name=POST)
+//             public void doPost(RestRequest req, RestResponse res) {
+//                     res.setOutput("POST 
remainder="+req.getPathMatch().getRemainder());
+//             }
+//
+//             // Bean parameter
+//             @RestMethod(name=POST, path="/person/{person}")
+//             public void doPost(RestRequest req, RestResponse res, 
@Path("person") Person p) {
+//                     res.setOutput("POST 
/person/{name="+p.name+",birthDate.year="+p.birthDate.get(Calendar.YEAR)+"} 
remainder="+req.getPathMatch().getRemainder());
+//             }
+//
+//             // Various primitive types
+//             @RestMethod(name=PUT, 
path="/primitives/{xInt}/{xShort}/{xLong}/{xChar}/{xFloat}/{xDouble}/{xByte}/{xBoolean}")
+//             public void doPut1(
+//                             RestResponse res, 
+//                             @Path("xInt") int xInt, 
+//                             @Path("xShort") short xShort, 
+//                             @Path("xLong") long xLong, 
+//                             @Path("xChar") char xChar, 
+//                             @Path("xFloat") float xFloat, 
+//                             @Path("xDouble") double xDouble, 
+//                             @Path("xByte") byte xByte, 
+//                             @Path("xBoolean") boolean xBoolean
+//                     ) {
+//                     res.setOutput("PUT 
/primitives/"+xInt+"/"+xShort+"/"+xLong+"/"+xChar+"/"+xFloat+"/"+xDouble+"/"+xByte+"/"+xBoolean);
+//             }
+//
+//             // Various primitive objects
+//             @RestMethod(name=PUT, 
path="/primitiveObjects/{xInt}/{xShort}/{xLong}/{xChar}/{xFloat}/{xDouble}/{xByte}/{xBoolean}")
+//             public void doPut2(
+//                             RestResponse res, 
+//                             @Path("xInt") Integer xInt, 
+//                             @Path("xShort") Short xShort, 
+//                             @Path("xLong") Long xLong, 
+//                             @Path("xChar") Character xChar, 
+//                             @Path("xFloat") Float xFloat, 
+//                             @Path("xDouble") Double xDouble, 
+//                             @Path("xByte") Byte xByte, 
+//                             @Path("xBoolean") Boolean xBoolean
+//                     ) {
+//                     res.setOutput("PUT 
/primitiveObjects/"+xInt+"/"+xShort+"/"+xLong+"/"+xChar+"/"+xFloat+"/"+xDouble+"/"+xByte+"/"+xBoolean);
+//             }
+//
+//             // Object with forString(String) method
+//             @RestMethod(name=PUT, path="/uuid/{uuid}")
+//             public void doPut1(RestResponse res, @Path("uuid") UUID uuid) {
+//                     res.setOutput("PUT /uuid/"+uuid);
+//             }
+//     }
diff --git 
a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/StatusCodesTest.java
 
b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/PathRemainderAnnotationTest.java
similarity index 72%
rename from 
juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/StatusCodesTest.java
rename to 
juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/PathRemainderAnnotationTest.java
index 546844a..91d20ed 100644
--- 
a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/StatusCodesTest.java
+++ 
b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/PathRemainderAnnotationTest.java
@@ -14,35 +14,41 @@ package org.apache.juneau.rest.annotation;
 
 import static org.apache.juneau.http.HttpMethodName.*;
 
-import java.io.*;
-
 import org.apache.juneau.rest.mock.*;
 import org.junit.*;
+import org.junit.runners.*;
 
 /**
- * Validates that the correct status codes are returned on REST requests.
+ * Tests related to @PathREmainder annotation.
  */
-@SuppressWarnings("javadoc")
-public class StatusCodesTest {
-
+@SuppressWarnings({"javadoc"})
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class PathRemainderAnnotationTest {
+       
        
//=================================================================================================================
-       // OK
+       // Simple tests
        
//=================================================================================================================
-       
+
        @RestResource
-       public static class A {
-               @RestMethod(name=PUT)
-               public Reader a01(@Body String b) {
-                       return new StringReader(b);
+       public static class A  {
+               @RestMethod(name=GET, path="/*")
+               public String b(@PathRemainder String remainder) {
+                       return remainder;
                }
        }
        
-       private static MockRest a = MockRest.create(A.class);
+       static MockRest a = MockRest.create(A.class); 
        
        @Test
-       public void a01a_OK() throws Exception {
-               a.request("PUT", "/").body("foo").execute().assertStatus(200);
+       public void a01_withoutRemainder() throws Exception {
+               a.request("GET", "/").execute().assertBody("");
+       }
+       @Test
+       public void a02_withRemainder() throws Exception {
+               a.request("GET", "/foo").execute().assertBody("foo");
+       }
+       @Test
+       public void a03_withRemainder2() throws Exception {
+               a.request("GET", "/foo/bar").execute().assertBody("foo/bar");
        }
-       
-       // TODO - Test all the status codes
 }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/Transform.java
 
b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/QueryAnnotationTest.java
similarity index 79%
copy from 
juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/Transform.java
copy to 
juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/QueryAnnotationTest.java
index 9d673aa..41bcbd8 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/Transform.java
+++ 
b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/QueryAnnotationTest.java
@@ -10,21 +10,14 @@
 // * "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.internal;
+package org.apache.juneau.rest.annotation;
+
+import org.junit.*;
+import org.junit.runners.*;
 
 /**
- * An interface for creating objects from other objects such as a 
<code>String</code> or <code>Reader</code>.
- * 
- * @param <I> Input type.
- * @param <O> Output type.
+ * Tests related to @Query annotation.
  */
-public interface Transform<I,O> {
-       
-       /**
-        * Method for instantiating an object from another object.
-        * 
-        * @param in The input object.
-        * @return The output object.
-        */
-       public O transform(I in);
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class QueryAnnotationTest {
 }

-- 
To stop receiving notification emails like this one, please contact
[email protected].

Reply via email to