diff --git a/rapidoid-http-fast/src/main/java/org/rapidoid/http/Req.java b/rapidoid-http-fast/src/main/java/org/rapidoid/http/Req.java index 459da25c65..089d6a9e2d 100644 --- a/rapidoid-http-fast/src/main/java/org/rapidoid/http/Req.java +++ b/rapidoid-http-fast/src/main/java/org/rapidoid/http/Req.java @@ -131,6 +131,11 @@ public interface Req { */ String param(String name, String defaultValue); + /** + * Returns a new instance of the specified bean type, with properties initialized from the URL parameters of the HTTP request. + */ + T param(Class beanType); + /* POSTED PARAMETERS IN THE REQUEST BODY: */ /** @@ -150,6 +155,11 @@ public interface Req { */ T posted(String name, T defaultValue); + /** + * Returns a new instance of the specified bean type, with properties initialized from the posted parameters of the HTTP request. + */ + T posted(Class beanType); + /* UPLOADED FILES IN THE REQUEST BODY: */ /** @@ -188,6 +198,11 @@ public interface Req { */ T data(String name, T defaultValue); + /** + * Returns a new instance of the specified bean type, with properties initialized from the data parameters of the HTTP request. + */ + T data(Class beanType); + /* EXTRA ATTRIBUTES ATTACHED TO THE REQUEST: */ /** diff --git a/rapidoid-http-fast/src/main/java/org/rapidoid/http/ReqImpl.java b/rapidoid-http-fast/src/main/java/org/rapidoid/http/ReqImpl.java index b3c078041f..cefb498b27 100644 --- a/rapidoid-http-fast/src/main/java/org/rapidoid/http/ReqImpl.java +++ b/rapidoid-http-fast/src/main/java/org/rapidoid/http/ReqImpl.java @@ -25,6 +25,7 @@ import org.rapidoid.buffer.Buf; import org.rapidoid.cls.Cls; import org.rapidoid.commons.MediaType; +import org.rapidoid.commons.Str; import org.rapidoid.io.Upload; import org.rapidoid.log.Log; import org.rapidoid.net.abstracts.Channel; @@ -225,6 +226,11 @@ public String param(String name, String defaultValue) { return withDefault(params().get(name), defaultValue); } + @Override + public T param(Class beanType) { + return beanFrom(beanType, params()); + } + @Override public String header(String name) { return U.notNull(headers().get(name), "HEADERS[%s]", name); @@ -256,6 +262,11 @@ public T posted(String name, T defaultValue) { return withDefault(posted().get(name), defaultValue); } + @Override + public T posted(Class beanType) { + return beanFrom(beanType, posted()); + } + @Override public List files(String name) { return U.notNull(files().get(name), "FILES[%s]", name); @@ -310,6 +321,20 @@ public T data(String name, T defaultValue) { return withDefault(value, defaultValue); } + @Override + public T data(Class beanType) { + return beanFrom(beanType, data()); + } + + private T beanFrom(Class beanType, Map properties) { + String paramName = Str.uncapitalized(beanType.getSimpleName()); + try { + return (T) http.custom().beanParameterFactory().getParamValue(this, beanType, paramName, (Map) properties); + } catch (Exception e) { + throw new RuntimeException("Couldn't instantiate a bean of type: " + beanType.getName()); + } + } + @Override public Map attrs() { return attrs; diff --git a/rapidoid-http-fast/src/main/java/org/rapidoid/http/customize/BeanParameterFactory.java b/rapidoid-http-fast/src/main/java/org/rapidoid/http/customize/BeanParameterFactory.java index e045cb5659..a208480734 100644 --- a/rapidoid-http-fast/src/main/java/org/rapidoid/http/customize/BeanParameterFactory.java +++ b/rapidoid-http-fast/src/main/java/org/rapidoid/http/customize/BeanParameterFactory.java @@ -24,10 +24,12 @@ import org.rapidoid.annotation.Since; import org.rapidoid.http.Req; +import java.util.Map; + @Authors("Nikolche Mihajlovski") @Since("5.1.0") public interface BeanParameterFactory { - Object getParamValue(Req req, Class paramType, String paramName) throws Exception; + Object getParamValue(Req req, Class paramType, String paramName, Map properties) throws Exception; } diff --git a/rapidoid-http-fast/src/main/java/org/rapidoid/http/customize/DefaultBeanParameterFactory.java b/rapidoid-http-fast/src/main/java/org/rapidoid/http/customize/DefaultBeanParameterFactory.java index c3bd826723..5ec7d70fab 100644 --- a/rapidoid-http-fast/src/main/java/org/rapidoid/http/customize/DefaultBeanParameterFactory.java +++ b/rapidoid-http-fast/src/main/java/org/rapidoid/http/customize/DefaultBeanParameterFactory.java @@ -25,13 +25,15 @@ import org.rapidoid.data.JSON; import org.rapidoid.http.Req; +import java.util.Map; + @Authors("Nikolche Mihajlovski") @Since("5.1.0") public class DefaultBeanParameterFactory implements BeanParameterFactory { @Override - public Object getParamValue(Req req, Class paramType, String paramName) throws Exception { - return JSON.MAPPER.convertValue(req.data(), paramType); + public Object getParamValue(Req req, Class paramType, String paramName, Map properties) throws Exception { + return JSON.MAPPER.convertValue(properties, paramType); } } diff --git a/rapidoid-http-server/src/main/java/org/rapidoid/http/handler/param/BeanParamRetriever.java b/rapidoid-http-server/src/main/java/org/rapidoid/http/handler/param/BeanParamRetriever.java index edbbb1780e..f35297b59f 100644 --- a/rapidoid-http-server/src/main/java/org/rapidoid/http/handler/param/BeanParamRetriever.java +++ b/rapidoid-http-server/src/main/java/org/rapidoid/http/handler/param/BeanParamRetriever.java @@ -43,7 +43,7 @@ public BeanParamRetriever(Customization customization, Class type, String nam @Override public Object getParamValue(Req req) { try { - return customization.beanParameterFactory().getParamValue(req, type, name); + return customization.beanParameterFactory().getParamValue(req, type, name, req.data()); } catch (Exception e) { throw U.rte(e); } diff --git a/rapidoid-integration-tests/src/test/java/org/rapidoid/http/CustomizationTest.java b/rapidoid-integration-tests/src/test/java/org/rapidoid/http/CustomizationTest.java index e68a70be32..4e3de68d10 100644 --- a/rapidoid-integration-tests/src/test/java/org/rapidoid/http/CustomizationTest.java +++ b/rapidoid-integration-tests/src/test/java/org/rapidoid/http/CustomizationTest.java @@ -72,7 +72,7 @@ Object aa(Num num) { // customization ObjectMapper mapper = new ObjectMapper(); - On.custom().beanParameterFactory((req, type, name) -> mapper.convertValue(req.posted(), type)); + On.custom().beanParameterFactory((req, type, name, props) -> mapper.convertValue(req.posted(), type)); // after customization onlyPost("/aa?id=3", U.map("the-name", "three"));