where the amazing happens

一个WEB框架功能的分析:用编码规定代替配置文件

Ruby on Rails有个设计思想是:用编码规定代替繁琐的配置文件。jvm平台已经有一些类似ror的实现,比如
grails:http://docs.codehaus.org/display/GRAILS/2006/03/29/Groovy+on+Rails+(Grails)+0.1+Released

虽然由于java自身的局限,它很难做出像ruby或者groovy那样动态语言那样随心所欲的动作,但是利用它的运行时反射、动态代理等特性来尽可能体现“用编码规定代替繁琐的配置文件”这一思想。下面就转入正题。

ServletAPI对HTTP协议进行了封装,通过配置Web.xml来把不同的请求转发给不同的servlet来处理。Web框架则用一个ActionServlet,根据自己的对Action的定义来转发请求。
抛开那些繁琐的配置文件,设想一下这样一种方法:

1.Web动作的处理和响应

假设这样一个POST请求:

< form  action ="logic/group/NewTopic"  method ="post" >

Web动作实现Bean:

org.qqsns.web.logic.group.NewTopic

注意后面的logic/group/NewTopiclogic.group.NewTopic, 动作类和Web动作是通过请求路径和包名相互关联。
这样,对Web动作的响应就依赖于编译期的代码的组织结构而不是执行期的配置文件。这样的好处是避免了维护繁琐的配置文件,特别是在没有IDE支持的情况下。

org.qqsns.web.logic.group.NewTopic类是一个实现net.wff.servlet.WebAction接口的POJO,下面是NewTopic中execute的方法片段:   

// Only method must be implemented for interface net.wff.servlet.WebAction
  public  String execute(HttpServletRequest request, HttpServletResponse response)
 
throws  ServletException, IOException {
  
  
// return "redirect /success.html";   // 请求重定向
   return   " /success.jsp " ;               // 请求转发
}

 execute方法的返回值手动指定了一个转发或重定向的路径。

2.输入验证

普通的Web框架都带数据输入验证功能,一般复杂程度和功能强大与否成正比。
这里简单地要求从setter方法里抛出一个包含验证信息的异常,以此来实现输入异常处理。
      
普通setter方法

public   void  setName(String name)
  
this .name  =  name;
}

添加输入验证后的setter方法

public   void  setName(String name)  throws  InputException {    
 
if (name.length() < 3 )
    
throw   new  InputException( " Topic name must has a length greater than 3 " ); 
  
this .name  =  name;
}


WaterFallServlet是如何处理验证信息的:

WebAction wa  =  
    (WebAction)Class.forName(classPath).newInstance();
          
// procces forwarding
           try   {
    ActionHelper.setProperties(request,wa);
   }
  catch  (InputException e)  {
    
// return to input view
    
// header:referer
    String rtn  =  request.getHeader( " referer " );
    
// clear old errors
     if (rtn.indexOf( " ? " ) != 1 ) {
     rtn 
=  rtn.substring( 0 ,rtn.indexOf( " ? " ));
    }

    rtn
= rtn + " ?error= " + URLEncoder.encode(e.getMessage(), " UTF-8 " );
    response.sendRedirect(rtn);
    
return ;
   }

这样验证信息通过请求参数传回到输入页面.

3.数据绑定

假设有这样的html输入: 

< input  type ="text"  name ="name" />
< input  type ="text"  name ="number" />
< input  type ="text"  name ="price" />

 下面是NewTopic中execute的方法全部:   

public  String execute(HttpServletRequest request, HttpServletResponse response)
 
throws  ServletException, IOException {
  System.out.println(getName());
  System.out.println(getNumber());
  System.out.println(getPrice());
  System.out.println(getLength());
  
return   " /success.html " ;
}

自动从request注入parameter,这也许是很多人喜欢Struts DynamicActionForm的原因之一。
不过这里实现更类似多了类型转换的<jsp:setProperty name="bean" property="*"/>
因为Name的类型是String,Number的类型是Integer,Price的类型是float,length的类型是double.至于其他复杂的类型,也许jsf的转换器是个更好的主意。
这样就初步解决了数据的输入绑定和验证。余下的就是业务逻辑的问题。WaterfallWebFramework源代码:
http://www.blogjava.net/Files/zqc/WaterfallWebFramework.rar (只有一个配置文件,其中只有1行配置信息!)

以上就是框架的主要功能。用编码规定代替配置文件,也许这会是一种更加高效率的开发方式。

posted on 2006-05-17 13:12 where the amazing happens 阅读(2095) 评论(3)  编辑  收藏 所属分类: 自制土器

评论

# re: 一个WEB框架功能的分析:用编码规定代替配置文件 2006-05-17 18:28 原创专栏 开源学习

http://forum.javaeye.com/viewtopic.php?t=10894

可以看看这个讨论。
大规模的项目这种方法还是不行滴。

  回复  更多评论   

# re: 一个WEB框架功能的分析:用编码规定代替配置文件 2006-05-17 19:44 鸟不生蛋蛋的地方

去看仔细了下,觉得比较重要的是下面几个问题:
1.url mapping pattern的问题,就对一些特殊url的处理
2.action对象重用的问题.
3.页面rendering的问题
还没使用jsp以外的脚本,所以不知道第3点怎么样.
1和2应该算是url->class映射的副作用,传统的通过mapping文件的定义可以使action对象从请求过程中脱离出来,达到可重用性.这一点url->class映射也许就做不到.毕竟依赖的都是编译期的代码,如果抽出来,那就又是配置文件了.

对,没错.大型项目上百个action,比起结构整洁或者配上IDE支持的配置文件,这样的方法确实不好管理.虽然它方便了开发者.  回复  更多评论   

# re: 一个WEB框架功能的分析:用编码规定代替配置文件 2006-05-17 20:43 mixteluoyi

对于维护和扩展开发不利。
前两批的开发人员走后,这种很多靠默认行为固定的逻辑谁明白。
做软件最重要的是维护性好,换过几批人以后,仍然结构清晰,后来的人能快速上手  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 

公告

点击这里给我发消息

导航

<2006年5月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

统计

常用链接

留言簿(3)

随笔分类(18)

随笔档案(17)

文章分类

相册

其他我的blog

技术Blog

最新随笔

搜索

最新评论

阅读排行榜

评论排行榜