|
From: Steven D. <ste...@gm...> - 2004-12-30 16:13:14
|
Hi Aliaksandr,
Looks nice. Does this framework have a name or shall I just refer to
it as YAWF? :-)
Can we download a distribution somewhere?
Steven
On Thu, 30 Dec 2004 16:11:00 +0200, Aliaksandr Radzivanovich
<ara...@gm...> wrote:
> Hello everybody, you got it right - Yet Another Web Framework ;)
> Everybody loves writing web frameworks, so I do ;)))
> My idea is to annotate POJOs, their methods and arguments with metadata
> to make them web request handlers. I've never heart of this approach
> before, correct me if I'm wrong. Let me explain it in details, let's
> start from example. Take a look at the following snippets of code, pay
> your attention to the javadocs:
>
> Here is declaration of a POJO whose methods will handle web requests:
>
> /**
> * Simple action handler, defines default view name for the action
> * methods that don't specify their own ones.
> *
> * @@web.extensions.ActionSet(defaultViewName="default")
> */
> public class Simple {
> ...
>
> Here is the method which would handle requests to "/welcome.htm":
>
> /**
> * The simplest method ever, it does not take any parameters nor
> * does it return anything. Returned view name is taken from class
> * annotation.
> *
> * @@web.extensions.ActionHandler("/welcome")
> */
> public void welcome() {
> // custom code goes here
> }
>
> Here is the method whose arguments are taken from request values.
>
> /**
> * A more advanced example. Method's arguments are taken from the
> * corresponding request's values. Here the <em>userId</em>
> * argument is taken from the <em>uid</em> request's parameter
> * converted to integer. If none is specified then default value is
> * choosen. The <em>username</em> and <em>password</em> arguments
> * are mandatory.
> *
> * @@web.extensions.ActionHandler("/simple/dummylogin")
> * @@.userId web.extensions.ActionParam("uid", defaultValue=0)
> * @@.email web.extensions.ActionParam("eml", required=true)
> * @@.password web.extensions.ActionParam("pwd", required=true)
> */
> public ModelAndView dummylogin(int userId, String email, String password) {
> // login code goes here
> Map model = new HashMap();
> model.put("message", "Login successful");
> return new ModelAndView("default", "model", model);
> }
>
> And fragment of the configuration code:
>
> <!--
> - This bean is an explicit URL mapper that is used by the dispatcher
> - servlet.
> - It is used instead of the default BeanNameUrlHandlerMapping.
> -->
> <bean id="urlMapping"
> class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
> <property name="mappings">
> <props>
> <prop key="/**/*.htm">controller</prop>
> </props>
> </property>
> </bean>
>
> <!--
> - A POJO whose methods will handle web requests.
> -->
> <bean id="simple" class="web.extensions.simple.Simple">
>
> </bean>
>
> <!--
> - A Controller dispatching web requests to a POJO.
> -->
> <bean id="controller" class="web.extensions.ActionSetController">
> <property name="actionSet">
> <ref local="simple"/>
> </property>
> </bean>
>
> From my experience complex web applications always have large number of
> methods processing web requests. The methods have to deal with web
> request parameters, but they don't have to handle user form submissions
> and don't require data validation. For example, a server script would
> generate an URL which clicked by user would change web application state
> somehow. Building separate Command objects for every controller method
> would be overkill, dealing with servlet's parameter maps is annoyance.
> This is where metadata comes to help. I believe the example code above
> is a small piece of what can be done with attributes, they can solve
> wider range of problems of web applications.
>
> I've written initial working demo, which is in alpha state now. As
> youmay guess it is Spring's AbstractController implementation. I used
> Apache commons-attributes, because of their compatibility with JDK1.4,
> but JDK1.5 annotations are also possible.
>
> I'd like to ask the community, what do you think about the idea? Do you
> lake it? Does it have any future? Is so, may be it isthe time to
> implement it in some framework? I would appreciate any feedback from you.
>
> Thanks, Alex.
>
> PS
> Happy New 2005 Year!!!
>
>
>
> package web.extensions.simple;
>
> import org.springframework.web.servlet.ModelAndView;
>
> import java.util.HashMap;
> import java.util.Map;
>
> /**
> * Simple action handler, defines default view name for the action
> * methods that don't specify their own ones.
> *
> * @@web.extensions.ActionSet(defaultActionHandler="welcome",
> * defaultViewName="default")
> */
> public class Simple {
>
> /**
> * The simplest method ever, it does not take any parameters nor
> * does it return anything. Returned view name is taken from class
> * annotation.
> *
> * @@web.extensions.ActionHandler("/welcome")
> */
> public void welcome() {
> // custom code goes here
> }
>
> /**
> * Simple method, implicitly specifies returned view name in its
> * annotation.
> *
> * @@web.extensions.ActionHandler("/simple/simple1",
> * defaultViewName="view1")
> */
> public void simple1() {
> // custom code goes here
> }
>
> /**
> * Simple method, exclicitly scpecifies returned view name in the
> * returning string.
> *
> * @@web.extensions.ActionHandler("/simple/simple2")
> */
> public String simple2() {
> // custom code goes here
> return "view2";
> }
>
> /**
> * A more complicated method, which returns <em>ModelAndView</em>.
> *
> * @@web.extensions.ActionHandler("/simple/simple3")
> */
> public ModelAndView simple3() {
> // custom code goes here
> Map model = new HashMap();
> model.put("message", "Hello World (executing simple3)");
> return new ModelAndView("view3", "model", model);
> }
>
> /**
> * This action would be invoked when <em>"/simple/action"</em>
> * path is requested and no <em>switch</em> parameter is specified
> * in the request's values.
> *
> * @@web.extensions.ActionHandler("/simple/action")
> * @see #actionSwitchAbc()
> * @see #actionSwitchXyz()
> */
> public ModelAndView actionDefault() throws Exception {
> Map model = new HashMap();
> model.put("message",
> "invoking <em>action</em>, the switch parameter is not specified");
> return new ModelAndView("default", "model", model);
> }
>
> /**
> * An example of a method which would only be invoked if a certain
> * request's parameter has the specified value. This action would
> * be invoked when <em>"/simple/action"</em> path is requested and
> * the <em>switch</em> parameter is <em>abc</em>.
> *
> * @@web.extensions.ActionHandler("/simple/action?switch=abc")
> * @see #actionDefault()
> * @see #actionSwitchXyz()
> */
> public ModelAndView actionSwitchAbc() throws Exception {
> Map model = new HashMap();
> model.put("message",
> "invoking <em>action</em>, the switch parameter is 'abc'");
> return new ModelAndView("default", "model", model);
> }
>
> /**
> * An example of a method which would only be invoked if a certain
> * request's parameter has the specified value. This action would
> * be invoked when <em>"/simple/action"</em> path is requested and
> * the <em>switch</em> parameter is <em>xyz</em>.
> *
> * @@web.extensions.ActionHandler("/simple/action?switch=xyz")
> * @see #actionDefault()
> * @see #actionSwitchAbc()
> */
> public ModelAndView actionSwitchXyz() throws Exception {
> Map model = new HashMap();
> model.put("message",
> "invoking <em>action</em>, the switch parameter is 'xyz'");
> return new ModelAndView("default", "model", model);
> }
>
> /**
> * A more advanced example. Method's arguments are taken from the
> * corresponding request's values. Here the <em>userId</em>
> * argument is taken from the <em>uid</em> request's parameter
> * converted to integer. If none is specified then default one is
> * choosen. The <em>username</em> and <em>password</em> arguments
> * are mandatory.
> *
> * @@web.extensions.ActionHandler("/simple/dummylogin")
> * @@.userId web.extensions.ActionParam("uid", defaultValue=0)
> * @@.email web.extensions.ActionParam("eml", required=true)
> * @@.password web.extensions.ActionParam("pwd", required=true)
> */
> public ModelAndView dummylogin(int userId, String email, String password) {
> // login code goes here
> Map model = new HashMap();
> model.put("message", "Login successful");
> return new ModelAndView("default", "model", model);
> }
>
> /**
> * A counterpart of the {@link Simple#dummylogin(int, String,
> * String) dummylogin} method.
> *
> * @@web.extensions.ActionHandler("/simple/dummylogout")
> */
> public void dummylogout() {
> // perform logout and redirect to the login view.
> }
>
> }
>
>
>
|