Java Web Application开发日志之一--自己设计简易framework

Java Web Application开发日志之一
--自己设计简易framework

    前段时间,实验室接了学校研究生院的MIS系统。

      采用DelphiCSJ2EEBS结合的构架方式。数据库用的是师兄最熟悉的Oracle。说道Oracle,对我来说,基本使用没有问题了,只是数据建模我还没有主导设计过,心里还是没有底。

      按照分配,我还是主导BS的设计,更具体的说就是完成一个Java Web Application,再具体一点就是搞搞jspservlettagjsbeans。呵呵,技术很简单,以前也做过了。

      但是,由于这回小组的Leader是自己,我的自由度更大了一些。能发挥什么呢,第一个灵感还是“模式”二字。那就用用吧。但肯定是需求是第一位的,没有需要而乱用或硬用会制造无端的复杂度,让产品远离需求。所以,一定要根据实际需要来用模式。

      除了我们实验室外,由于这个项目的特殊性,必须要联合别的老师的4个小组一起做。我们导师是大Leader,所以,BSCS的设计规范都是我们定,一定要保证大框架的可集成性,公共资源的单一性。

      说到Java Web Application的开发,以下这本书(Art of Java Web Development)不得不说。反正无论对错,它是我的教科书。

          
        
    
    
   想了解这本书详细的信息,请点击
这里

       它从演化(evolution)的角度,一步一步的告诉你,Java Web Application是怎么一步一步演变过来的。说实话,我也就看了这书的前半部分。也就是主要的演变史,而后半部分的设计模式的高阶应用的例子没有“所谓的时间”看了。呵呵。

       谈到Java Web Application的开发,最基本的一个模式(跟“设计模式”的“模式”有一定的区别)就是MVC模式,而MVC最开始就是为了规范Desktop UI Application的开发而提出的。如果要跟Web Application结合的更紧一些。它就有另外一个形式,应此便有了Model 2的由来。

       因此,下面我们经常说的Model 2的全称应该是MVC Model 2


       







    
    这就是所谓的Model 2的说明图。可以说,一切就这个图完美的表示了,毕竟也不是什么难以理解的东西。详细解释,我没书上说的好,也懒得说,就copy过来。

Designers looked at MVC and modified it to work within this new development paradigm. This work led to what is now popularly called “Model 2” (to distinguish it from the desktop-centric MVC). Model 2 doesn’t change the definition of MVC; it just casts it in terms of web development. In Model 2 for Java web applications, JavaBeans represent the model. Notice that this may include simple JavaBeans, Enterprise JavaBeans (EJBs), or JavaBeans that act as proxies for EJBs. The view is rendered with JSP, which makes sense because JSP is closely tied to HTML. The controller is a servlet, well suited to executing Java code. This plays to the strengths of servlets, utilizing the services of the servlet container for lifecycle and invocation without forcing servlets to generate mixed Java code and HTML.

 

The typical Model 2 scenario is shown in figure 1.2. The user invokes a controller servlet (more about this design later). The servlet instantiates one or more JavaBeans that perform work. The servlet then adds the bean(s) to one of the JSP collections and forwards control to a JSP. The JSP extracts the JavaBeans and displays the results.

 

        Model 2可以说是以下Nframework的原型。很多framework都是紧密基于这个model 2模式而建立的。

        许多开发小组,在开发Java Web Application的时候,都是直接选择在各种framework的基础上进行开发的。下面列出一些常用的frameworks

 

Framework

Download from

Description

Struts

http://jakarta.apache.org/struts

A lightweight, open–source framework primarily designed for building Model 2 applications.

Velocity

http://jakarta.apache.org/velocity

A Java-based template engine. Velocity permits anyone to use the simple yet powerful template language to reference objects defined in Java code.

Tapestry

http://jakarta.apache.org/tapestry

A framework that is positioned primarily as an alternative to JavaServer Pages. It replaces the scripting and code generation of JSPs with a full-fledged component object model.

WebWork

http://sourceforge.net/projects/opensymphony

A community project conducted using the open-source process, aimed at providing tools and a framework for building complex web sites in a short amount of time that are easy to understand and maintain.

Turbine

http://jakarta.apache.org/turbine

A large, open-source, services-based framework for building extensive web applications such as e-commerce sites.

 

        而最最常用的framework就是大名鼎鼎的,也是我唯一用过的,当然就是struts啦。它的特点有:

n         A controller servlet that dispatches requests to appropriate action classes provided by the application developer

n         JSP custom tag libraries and associated support in the controller servlet that assists developers in creating interactive form-based applications

n         Utility classes that support XML parsing, automatic population of JavaBeans properties based on the Java reflection APIs, and internationalization of prompts and messages

 

        呵呵,最后我们项目没有使用这里任何的一个framework,一是觉得成本高,5个小组都没有什么接触过的人,要搞懂一个framework再开发,对于学校的同学来说,是不现实的。二是实用性也不强,struts中的很多功能,我们这里并不需要。

        结论是,咱自己设计了另一个基于model 2framework,当然,称为framework真不好意思。但是,想来想去,自己这套东西,真的有可以重用的东西,的确可以实现一些“genetic”的功能。暂且就认为是一种幼稚的framework吧。由于是给研究生院(graduate school)做的,就叫gs框架吧。虽然功能简陋,但也有它弱智的能力,其由以下一些类和支持元素组成:

1.         一个基类servletGSServlet。类图如下:



         



         
         
         gs
框架下的servlet都要继承于它。

                  a)         子类要override以下的方法:

    n         validate,控制此servlet能被谁访问的代码。其实内容就是初始化属性validator

    n         process,此servlet逻辑业务代码,以前写在doPostdoGet中的代码。

                  b)         子类可以使用的方法:

    n         forwardErr,出错跳转方法,当然根据不同的出错参数,有不同的出错显示。

    n         forward,跳转下一个页面的方法。

    n         forwardSuccess,有了forward,此方法舍弃了。

    n         forwardWithObject,带着对象跳转页面的方法。













2.        
一个对用户验证的框架(如下图),每个
servlet都会用此验证框架来指定可访问用户的身份。


        这个框架可重用的部分为接口 Validator 抽象类 Role 两个关系类 OrRelation AndRelation
    而继承于
Role的各个具体角色则要根据不同的项目的实际情况自行定义,gs项目中暂时只有三种角色:游客,学生,教师。对于这个的使用,后面会说到的。明眼人一看就可以知道这里用了装饰模式,我自豪啊。

3.         JSTL,这里使用了JSTL作为页面的标准标记。

       在页面中的条件判断和迭代,就都靠它了。相对于自定义标记,使用JSTL作为jsp标记,我个人认为是性价比非常好的一种选择,毕竟学习自定义标记的开发要一定的时间,而且一但使用,量一定很大。

4.         tipErr.jsp,显示出错信息页面。

       出错提示对于一个framework肯定是必要的,既然GSServlet中有通用的跳转出错页面的方法,那也就把这个显示出错信息页面当作框架的一部分吧,不妥之处请见谅。


      
由上面的四点构成了本项目的一个简易framework

    下面是基于这种framework开发的一个servlet例子。其功能是为教师和学生提供成绩查询。类图如下:

框架代码:


首先,必须
Override
父类的process方法,可见,本servlet的业务逻辑都在这里。

 1 protected   void  process(HttpServletRequest req, HttpServletResponse resp)
 2          throws  ServletException, IOException  {
 3
 4        req.setCharacterEncoding("GB2312");
 5
 6        String function = req.getParameter("function");
 7
 8        if (function.equals("getQueryType_Stu")) {
 9            this.queryNullQueryScoreStu(req, resp);
10        }
 else if (function.equals("getQueryType_Tch")) {
11            this.queryNullQueryScoreTch(req, resp);
12        }
 else if (function.equalsIgnoreCase("queryScoreStu")) {
13            this.queryScoreStu(req, resp);
14        }
 else if (function.equalsIgnoreCase("queryScoreTch")) {
15            this.queryScoreTch(req, resp);
16        }
 else {
17            this.forwardErr(req, resp, "页面没传参数进来");
18        }

19    }

20

      
接着,必须Override父类的validate方法,实现对本servlet的访问控制。

1 protected   void  validate(HttpServletRequest req)  {
2        //教师和学生都可以。
3        validator = new Or_Teacher(new Or_Student(new OrRelation(req)));
4    }

5

再者,有多少子逻辑功能,就写多少个下面的业务方法。父类GSServlet的一些跳转方法这里就可以用了。

 1    /**
 2     * 学生查询成绩
 3     * @param req
 4     * @param resp
 5     */

 6      private   void  queryScoreStu(
 7         HttpServletRequest req,
 8         HttpServletResponse resp)
 9          throws  ServletException, IOException  {
10
11        //1:获得用户ID
12        HttpSession session = req.getSession(false);
13        Ent_BaseUser user = (Ent_BaseUser) session.getAttribute("USER");
14        String stuID = user.getId();
15
16        //2:获得查询类型
17        String queryType = req.getParameter("queryType");
18
19        //3:准备存放查出成绩对象的集合
20        ArrayList scores = null;
21
22        //4:准备要使用的工厂对象
23        Bean_Score bs = new Bean_Score();
24
25        //5:判断查询类型(单课头,全部课头)
26        if (queryType.equals("0")) //0--查单课头
27            //获得查询课头ID
28            String lessonHeadID = req.getParameter("lessonHeadID");
29            //得到结果
30            try {
31                scores = bs.findByStuIDLessonHeadID(stuID, lessonHeadID);
32            }
 catch (Exception e) {
33                e.printStackTrace();
34                this.forwardErr(req, resp, DB_ERROR);
35            }

36        }
 else //1--查全部课头
37            try {
38                scores = bs.findAllScoreByStuID(stuID);
39            }
 catch (Exception e) {
40                e.printStackTrace();
41                this.forwardErr(req, resp, DB_ERROR);
42            }

43        }

44        //6:搞定就forward给页面去显示!
45        this.forwardWithObject(
46            req,
47            resp,
48            "../gs.train/stu/score/scoreStu.jsp",
49            "scoreResults",
50            scores);
51        //this.forward(req,resp,"../common/viewNotice.jsp");
52
53    }

54
55      /** 
56     * 老师查询成绩
57     * @param req
58     * @param resp
59     */

60      private   void  queryScoreTch(
61         HttpServletRequest req,
62         HttpServletResponse resp)
63          throws  ServletException, IOException  {
64        //省略……………………
65    }

66     
67      // 省略……………………
68

        显示的 jsp 页面就用 JSTL forward 过来的东西显示出来,一个业务过程就完成了。

        这个简单的framework在本项目中基本符合使用要求,特别是别的小组的同学不需要花太多的时间就能很好的使用,希望以后实验室能够考虑重用这个东西,呵呵。

                                                      MARCO ZHANG 2006年2月10日5:10:08

你可能感兴趣的:(Java Web Application开发日志之一--自己设计简易framework)