EasyJF 官方网站全面升级,同时EasyJF开源团队也将进行全面改组,期待您给我们提出宝贵的意见及建议!

当前位置:首页-教程-原创教程

  • EasyJWeb入门手册
    作者: 本站会员  来源:easyjf  发布时间:2007-10-12 16:04:00
  •  一 、简介

    EasyJWeb是基于java技术,应用于WEB应用程序快速开发的MVC框架,框架设计构思来源于国内众多项目实践,充分借签了当前主流的开源Web框架(Struts、JSF、Tapestry 、Webwork),吸取了其优点及精华,利用Velocity作为模板页面引擎,是一个实现了页面及代码完全分离的MVC开发框架,是一个旨在为中小型Web应用系统提供快速开发实践的简易Web框架。

    (为了能让用户快速地掌握并使用EasyJweb框架,在开发EasyJWeb的同时开发了EasyJWeb Tools。)通过EasyJWeb Tools提供的配套开发工具,可以实现基于EasyJWeb框架的Web应用项目快速开发,包括常用应用软件的代码自动生成、数据库添删改查(CRUD)代码生成、自动页面模版生成、配置文件管理等。

    框架特点:

    1、零配置文件支持。以前我们每接触一个框架,开始总被他的配置文件折腾一番。EasyJWeb实现零配置支持,可以不写一句配置文件就在框架基础上构建你的应用。(适合小型网站系统)。

    2、简易的模板页面设计支持。放弃使用jsp,使用简单Velocity脚本语言作为页面模板。

    3、页面程序完全分离。实现显示页面与程序逻辑的完全分离,克服了传统jsp页面难于维护的问题。

    4、基于页面组件的框架。灵活的页面组件配置,可以直接通过配置文件设置字段及表属性的事件等。

    5、快速开发支持。通过EasyJWeb Tools,可以自动生成应用软件模板代码,定制并管理自己的J2EE代码模板,代码生成模板扩展支持最流行的实用Java开发框架如hibernate、Spring等,实现快速开发。 

     

    EasyJWeb的MVC框架简单流程图

    二、环境需求

    三、安装配置EasyJWeb

    获取EasyJWeb SDK

    EasyJWeb是一个开源项目,你可以从EasyJF官方网站下载。下载地址:http://www.easyjf.com/easyjweb/download.htm其中,EasyJWebX_src.zip为源代码,EasyJWebX_lib.zip为编译后的jar包及运行EasyJWeb所需要的基本包。

    安装

    EasyJWeb只是一个Web应用程序MVC框架,其主要作为一般应用程序的基础框架,是以一个jar文件的形式伴随在用户的Java Web程序中执行,不需要进行专门的安装操作。只需要把easyjweb.jar文件及附属文件(lib中的所有jar文件)拷到java web应用程序类路径中即可。我们一般是放到Web应用程序目录的Web-inf\lib目录下,也可以拷到Tomcat\Common\lib目录下,这样使得所有Tomcat Web应用程序都可以使用EasyJWeb。我们推荐放到web-inf\lib 目录下,这样可以使得你不用理会具体的Web应用服务器.

    当开发EasyJWeb应用的时候,只要把EasyJWeb.jar包导入到工程中即可执行应用程序的调试及测试等工作

    配置web.xml文件

    EasyJWeb是一个Web应用程序的核心骨架,为了在浏览器中访问EasyJWeb应用程序,需要配置应用程序中的web.xml文件,使得用户的Web应用程序知道何时使用EasyJWeb应用程序处理用户请求。

    只有通过配置Web应用程序中的web.xml文件,才能使得EasyJWeb能正常的使用。EasyJWeb应用程序默认以.ejf为扩展名,在用户地址栏中输入与.ejf结尾 URL路径的时候,为了使得EasyJWeb能处理用户的请求,需要在web.xml文件中加如下的配置信息:

     <servlet>

      <servlet-name>easyjfservlet-name>

      <servlet-class>com.easyjf.web.ActionServletservlet-class>

      <load-on-startup>1load-on-startup>

     servlet>

     <servlet-mapping>

      <servlet-name>easyjfservlet-name>

      <url-pattern>*.ejfurl-pattern>

    servlet-mapping>

      

    由于Java是外国人发明的,其以unicode为默认编码,并且很多Java Web应用服务器也是泊来之品。因此我们在进行Java Web应用开发的时候经常会遇到中文字符处理的问题。比如显示在页码上的中文信息成乱码、或者保存到数据库的变成乱码等。因此,为了让Java Web应用能更好的处理中文,EasyJWeb默认情况下使用utf-8作为标准编码。这样需要通过在web.xml文件加入下面的设置,使得转码程序能正确运行,显示正确的文字字符。

     <filter>

      <filter-name>CharsetFilterfilter-name>

      <filter-class>com.easyjf.web.CharsetFilterfilter-class>

      <init-param>

       <param-name>encodingparam-name>

       <param-value>UTF-8param-value>

      init-param>

      <init-param>

       <param-name>ignoreparam-name>

       <param-value>trueparam-value>

      init-param>  

     filter>

     

     <filter-mapping>

      <filter-name>CharsetFilterfilter-name>

      <url-pattern>/*url-pattern>

    filter-mapping>

    这样,一个基于EasyJWebJava Web应用程序的web.xml文件全部内容如下:

    xml version="1.0" encoding="UTF-8"?>

    <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"

     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 

     http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

     <servlet>

      <servlet-name>easyjfservlet-name>

      <servlet-class>com.easyjf.web.ActionServletservlet-class>

      <load-on-startup>1load-on-startup>

     servlet>

     <servlet-mapping>

      <servlet-name>easyjfservlet-name>

      <url-pattern>*.ejfurl-pattern>

     servlet-mapping>

     <servlet-mapping>

      <servlet-name>easyjfservlet-name>

      <url-pattern>/ejf/*url-pattern>

     servlet-mapping>

     <filter>

      <filter-name>CharsetFilterfilter-name>

      <filter-class>com.easyjf.web.CharsetFilterfilter-class>

      <init-param>

       <param-name>encodingparam-name>

       <param-value>UTF-8param-value>

      init-param>

      <init-param>

       <param-name>ignoreparam-name>

       <param-value>trueparam-value>

      init-param>  

     filter>

     

     <filter-mapping>

      <filter-name>CharsetFilterfilter-name>

      <url-pattern>/*url-pattern>

     filter-mapping>

    web-app>

    web.xml文件配置成功,并把EasyJWeb.jar文件及相关jar文件拷到了web-inf\lib 目录下,启动Web用户服务器。在地址栏中随便输入http://localhost:8080/hello.ejf 类似以.ejf为扩展名的地址。则会得到一个如下的EasyJWeb错误反馈提示信息:

    友情提示!

    frameworkException: 没有找到处理模板的类:com.easyjweb.action.HelloAction 

    详细请查询http://www.easyjf.com 

    如下图所示:

    虽然提示框架错误,但既然有了EasyJWeb字眼,这即表示您的EasyJWeb应用程序已经配置成功,下一步就是开始激动人心的EasyJWeb应用开发了。

    若没能正确的配置Web.xml,当用户在地址栏中输入EasyJWeb应用程序扩展名的*.ejf时候,将会产生404的错误提示。如下图所示:

    四、快速入门与示例

    4.1、EasyJWeb版的 Hello World!

    下面,我们以一个老掉牙的示例"Hello World!"来开始EasyJWeb的应用程序,我们这里把"Hello World!"改成"喂,您好,EasyJWeb1.0发布了,请支持国产开源项目!",另外还将显示一个系统当前的时间。

    第一步,建立java代码程序目录:

    在您的源代码目录下,建一个如下的目录com\easyjweb\action

    第二步,写EasyJWeb Action helloAction.java:

    com\easyjweb\action目录下建一个名为helloAction.java的文件。内容如下:

    package com.easyjweb.action;

     

    import java.util.Date;

    import com.easyjf.web.IWebAction;

    import com.easyjf.web.Module;

    import com.easyjf.web.Page;

    import com.easyjf.web.WebForm;

     

    public class HelloAction implements IWebAction {

     public Page execute(WebForm form, Module module) throws Exception {  

      form.addResult("msg","喂,您好,EasyJWeb1.0发布了,请支持国产开源项目!");//设置VO对象msg的值。

      form.addResult("time",new Date());//设置VO对象time的值为当前时间

      return new Page("hello""/hello.html");

     }

    }

    写完后通过使用命令行的javac 或者编译工具编译helloAction.java。若对java的编译不熟悉,请先跳到后面的《EasyJWeb应用开发指南》章有关工具使用的介绍,或者直接执行EasyJWeb的示例程序中的helloAction.class拷到您的web-inf\classes\com\easyjweb\action目录下即可。

    第三步,建立EasyJWeb显示页面模板文件

    用记事本在/web-inf/easyjweb/建一个名为hello.html的文件,注意保存的时候请选择utf-8编码,helllo.html文件的全部内容如下:

    <html>

     <head>

      <title>我的第一个EasyJWeb程序界面title>

      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

     head>

     <body>

      $!msg<br>

      当前时间:$!time 

     body>

    html>

    把文件保存为utf-8编码的操作如下所示:

                  

    最后一步:启动Tomcat并运行Hello EasyJWeb应用程序

    重新启动Tomcat,然后在地址栏中输入http://localhost:8080/hello.ejf 即可看到如下图所示的运行结果:

    接下来我们来简单介绍一下这个简单的EasyJWeb应用。在上面这个应用中,我们可以看到,EasyJWeb应用主要包括两个部分:用Java实现的Action以及业务逻辑和一个Html模板(这里并不是使用的单纯的Html,还有Velocity脚本)。这里我们简单介绍一下Action部分,Velocity部分请参考《EasyJWeb-Velocity脚本简明教程》,你可以通过这个地址下载该教程:http://www.easyjf.com/easyjweb/EasyJWeb-Velocity.pdf

    在这个Action实现IWebAction接口,IWebAction接口只有一个方法execute。这个方法有两个参数:WebForm和Module,返回一个Page对象。WebForm负责封装用于用户端显示的数据,程序对WebForm进行处理,并根据Module封装的该模块的配置信息返回一个Page对象(本例中使用的是手动创建一个Page对象,也可以通过使用module.findPage("")方法来获取一个配置好的Page对象),告诉框架返回哪个页面。在程序中用到了WebForm的addResult方法,这个方法主要是用来添加要在客户端显示的数据。以这个程序为例,在执行了form.addResult("time",new Date());这一句之后,就可以在模板中使用$!time来调用这个Date对象。

    一个简单的例子,相信大家对EasyJWeb有了大概了解。好的,我们再稍微深入一点,将这个例子改造一下,实现稍微复杂一些的功能。我们在客户端增加一个文本框,输入用户名,提交到后台处理。我们先看看模板页:

    <html>

     <head>

      <title>我的第一个EasyJWeb程序界面title>

      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

     head>

     <body>

      <form action="/hello.ejf">

       <input name="userName" type="text" value="$!userName" /><br>

       <input type="submit" value="提交" />

      form>

      $!msg<br>

      当前时间:$!time 

     body>

    html>

    现在我们看看修改后的Action:

    public class HelloAction implements IWebAction {

     public Page execute(WebForm form, Module module) throws Exception {

      String userName = (String)form.get("userName");

      if(userName!=null&&!("".equals(userName))){

       form.addResult("msg"""+userName+",您好,EasyJWeb1.0发布了,请支持国产开源项目!");

      }else{

       form.addResult("msg""喂,您好,EasyJWeb1.0发布了,请支持国产开源项目!");

      }

      form.addResult("time"new Date());

      return new Page("hello""/hello.html");

     }

    }

    这里多了一句String userName = (String)form.get("userName");,这里的form.get("userName")用来获取客户端表单域里的userName文本框的值。现在我们来运行一下这个例子。在客户端输入http://localhost:8080/hello.ejf,界面如下:

      

    我们输入“friend”,然后提交,会出现下面的界面:

     

    到这里,相信大家应该了解了在EasyJWeb应用中如何获取客户端数据和向客户端传递数据。接下来我们再深入一点,将这个例子改为用户登录并显示用户的用户名和密码的例子,进一步的了解在EasyJWeb中是如何将对象数据传递给客户端并显示出来的。

    在这个例子中我们首先创建一个domain——User.java,代码如下:

    public class User {

     private String name;

     private String password;

    public String getName() {

      return "tianyi";

     }

     public void setName(String name) {

      this.name = name;

     }

     public String getPassword() {

      return "123";

     }

     public void setPassword(String password) {

      this.password = password;

     }

    }

    然后我们看看修改后的Action,代码如下:

    public class HelloAction implements IWebAction {

     public Page execute(WebForm form, Module module) throws Exception {

      String userName = (String)form.get("userName");

      String password = (String)form.get("passsword");

      User user = new User();

      if(userName!=null&&!(user.getName().equals(userName))&&password!=null&&user.getPassword().equals(password)){

       form.addPo(user);

       form.addResult("msg""登录成功!");

      }else{

       form.addResult("msg""登录失败!");

      }

      form.addResult("time"new Date());

      return new Page("hello""/hello.html");

     }

    }

    这里有一条语句form.addPo(user),这天语句用来将对象user的每一个属性值都传递到客户端。执行了这条语句之后在模板中可以直接使用$!name来显示user的name属性值。这里还可以这样写form.addResult("user", user),然后在模板中这样调用:$!user.name,$!user.password。具体的Velocity用法请参考EasyJF官方网站上的教程。

    最后我们修改一下模板文件,代码如下:

    <html>

     <head>

      <title>我的第一个EasyJWeb程序界面title>

      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

     head>

     <body>

      <form action="/hello.ejf">

       <input name="userName" type="text" /><br>

       <input name="password" type="text" /><br>

       <input type="submit" value="提交" />

      form>

      您的用户名为:$!name<br>

      您的密码为 :$!password<br>

      $!msg<br>

      当前时间:$!time 

     body>

    html>

    在浏览器中输入http://localhost:8080/hello.ejf访问,界面如下:

    在输入框中分别输入tianyi和123,提交,返回界面如下:

    到这里相信大家对EasyJWeb的基本使用方法已经了解了,下面我们将介绍EasyJWeb Tools的用法。

    4.2、EasyJWeb Tools

    前面我们创建了一个最简单的应用Hello World,现在我们来创建一个完整的EasyJWeb应用。在这里我们将要用到EasyJWeb Tools这个包。EasyJWeb Tools是EasyJWeb的一个重要部分。通常在Action层我们需要对客户端提交的数据做判断,进行流程控制,因此会有大量的if else语句。通过EasyJWeb Tools的业务引擎基本模型,只要编程者按照我们的模型规范进行编程,即可去除烦琐的if else语句。下面我们用一个例子来做简要说明。

    AbstractCmdAction、AbstractPageCmdAction、AbstractCrudAction这三个类是EasyJWeb Tools中最重要的三个抽象Action类,这三个类又以AbstractCmdAction为基础类。

    AbstractCmdAction对Action命令进行封装用于为提供命令式WebAction的写法用户直接调用可以减少书写繁锁的if语句。如果不使用AbstractCmdAction,那么就像struts一样每一个操作都要写一个Action,开发效率比较低。如果使用AbstractCmdAction,就可以在一个Action中执行多个操作,只需要在客户端传递一个名为easyJWebCommand的参数即可,AbstractCmdAction会根据这个参数来选择执行哪个方法。假设现在客户端传递来的参数值是save,那么将会执行doSave()方法,其它的以此类推。

    AbstractPageCmdAction类继承自AbstractCmdAction类。AbstractPageCmdAction对返回的Page对象进行了处理,用来支持更加灵活的参数调用。使用这个类可以实现零配置,并且不用显示的返回Page对象,它会根据类名、命令参数值和配置好的view路径来自动创建一个Page对象。

    AbstractCrudAction继承自AbstractPageCmdAction类,AbstractCrudAction类中对一些常用的、通用性比较强的业务逻辑方法如简单的添删改查操作进行了封装。如doEdit()方法,这个方法通常用来指向一个编辑页面,通用性很高,因此做了封装,类似的还有很多,这里不一一列举。下面我们将分别举例对这三个类的用法进行简要讲解。

    这是一个数据字典的添删改查应用,这里我们对只对字典目录进行添删改查操作。我们将分别使用这三个类来实现这个应用,比较这几个类的不同作用。现在我们来看看使用AbstractCmdAction时的Action,以下是Action的全部代码:

    public class SystemDictionaryAction extends AbstractCmdAction {

     

     private ISystemDictionaryService service;

     public void setService(ISystemDictionaryService service) {

      this.service = service;

     }

     

     public Page doList(WebForm form, Module module){

      QueryObject query = new QueryObject();

      form.toPo(query);

      IPageList pageList = service.getSystemDictionaryBy(query);

      CommUtil.saveIPageList2WebForm(pageList, form);

      return new Page("list""/news/dictionaryList.html");

     }

     

     public Page doAdd(WebForm form, Module module){

      return new Page("edit""/news/dictionaryEdit.html");

     }

     

     public Page doEdit(WebForm form, Module module){

      Long id = Long.parseLong(CommUtil.null2String(form.get("id")));

      form.addPo(this.service.getSystemDictionary(id));

      return new Page("edit""/news/dictionaryEdit.html");

     }

     

     public Page doSave(WebForm form, Module module){

      SystemDictionary dic = form.toPo(SystemDictionary.class);

      this.service.addSystemDictionary(dic);

      return this.doList(form, module);

     }

     

     public Page doDel(WebForm form, Module module){

      Long id = Long.parseLong(CommUtil.null2String(form.get("id")));

      this.service.delSystemDictionary(id);

      return this.doList(form, module);

     }

     

     public Page doUpdate(WebForm form, Module module){

      Long id = Long.parseLong(CommUtil.null2String(form.get("id")));

      SystemDictionary dic = this.service.getSystemDictionary(id);

      form.toPo(dic);

      this.service.updateSystemDictionary(id, dic);

      return this.doList(form, module);

     }

    }

    AbstractCmdAction实现了IWebAction,在它的execute方法里边根据easyJWebCommand的值来判断应该执行哪个方法。因此继承自这个类的Action就不需要再实现execute方法,只需要编写与操作相对应的doXxxx()方法。以doSave()方法为例,easyJWebCommand参数值为save时就会执行doSave()方法。在这个Action中,代码已经比较简洁了,也没有了if else语句,并且在一个Action里实现了关于SystemDictionary 这个对象的添删改查操作。但是我们的目标是要越来越简单,越来越快捷,我们并不满足于此,接下来我们看看AbstractPageCmdAction类的使用。

    下面同样是数据字典的添删改查操作,不同的是这个Action继承自AbstractPageCmdAction类,我们先看看这个Action的代码:

    public class SystemDictionaryAction extends AbstractPageCmdAction {

     private ISystemDictionaryService service;

     public void setService(ISystemDictionaryService service) {

      this.service = service;

     }

     

     public void doList(WebForm form, Module module){

      QueryObject query = new QueryObject();

      form.toPo(query);

      IPageList pageList = service.getSystemDictionaryBy(query);

      CommUtil.saveIPageList2WebForm(pageList, form);

     }

     

     public void doEdit(WebForm form, Module module){

      Long id = Long.parseLong(CommUtil.null2String(form.get("id")));

      form.addPo(this.service.getSystemDictionary(id));

     }

     

     public void doSave(WebForm form, Module module){

      SystemDictionary dic = form.toPo(SystemDictionary.class);

      this.service.addSystemDictionary(dic);

     }

     

     public void doDel(WebForm form, Module module){

      Long id = Long.parseLong(CommUtil.null2String(form.get("id")));

      this.service.delSystemDictionary(id);

     }

     

     public void doUpdate(WebForm form, Module module){

      Long id = Long.parseLong(CommUtil.null2String(form.get("id")));

      SystemDictionary dic = this.service.getSystemDictionary(id);

      form.toPo(dic);

      this.service.updateSystemDictionary(id, dic);

     }

    }

    AbstractPageCmdAction 类继承自AbstractCmdAction,这个类里边重写了execute方法,它先调用父类的execute方法,然后对父类的execute方法返回的值进行判断,如果为空并且easyJWebCommand参数值不为空,就会根据调用的Action类的名字和easyJWebCommand参数的值来创建一个Page对象返回给框架。

    这个Action与前一个Action相比,可以看出来,所有的doXxxx()方法都是void的了,不再return一个Page对象了。这就是AbstractPageCmdAction的作用,它会根据你调用的Action类的名字和客户端提交进来的命令参数的值自动创建一个Page对象,从而实现零配置,开发人员可以专注于业务逻辑,不用再关心流程控制。这样一来开发是不是又变得简单了一些、快捷了一些?但是我们的目标是不断前进的,我们不会满足现状,我们要越来越快。

    好的,激动人心的时刻到来了,前面我们讲解的两个类虽然使开发已经很方便了,但是我们可以看到,Action中还充斥着大量的form.get()、form.addResult()等方法,并且很多方法中都有着这样一些相同的代码,那么我们是否能够再封装一下呢?现在我们来看看AbstractCrudAction 类的使用。还是同样的应用:

    public class SystemDictionaryAction extends AbstractCrudAction {

     private ISystemDictionaryService service;

     public void setService(ISystemDictionaryService service) {

      this.service = service;

     }

     @SuppressWarnings("unchecked")

     protected Class entityClass() {

      return SystemDictionary.class;

     }

     protected Object findEntityObject(Serializable id) {

      return service.getSystemDictionary((Long) id);

     }

     protected IPageList queryEntity(IQueryObject queryObject) {

      return service.getSystemDictionaryBy(queryObject);

     }

     protected void removeEntity(Serializable id) {

      service.delSystemDictionary((Long) id);

     }

     protected void saveEntity(Object object) {

      service.addSystemDictionary((SystemDictionary) object);

     }

     protected void updateEntity(Object object) {

      service.updateSystemDictionary(((SystemDictionary) object).getId(),(SystemDictionary) object);

     }

    }

    我们可以看到Action的代码少了很多,业务逻辑的处理完全封装了,每个操作都只需要一条调用语句即可。现在我们来分析一下代码。首先,Action里多出了一个方法entityClass(),这个方法是AbstractCrudAction 里申明的一个抽象方法,它在没个Action里边的实现都不一样,分别返回各自要操作的类,提供给AbstractCrudAction 里实现的一些业务逻辑方法使用。

    接下来,我们会发现方法的命名也和以前不一样了,这里没有了doXxxx()方法,取而代之的是xxxxEntity()方法。这些方法都是在父类AbstractCrudAction 里申明的抽象方法,在每个不同的Action里实现,AbstractCrudAction 里的业务逻辑方法调用这些不同的实现分别执行不同的操作,巧妙的对通用性比较强的代码进行了封装,使开发变得更加简单快捷。假设命令参数值为save,在这里将不再执行doSave()方法,而是执行saveEntity()方法。这里并不是去掉了doXxxx()方法,而是将这些方法放到了AbstractCrudAction类里边,这里的saveEntyti()方法会被父类的doSave()方法调用,因此实际上还是调用了doSave()方法,只不过这个方法不需要开发人员自己来申明和实现了。

  • 评论 】 【收藏】 【 推荐给朋友 】 【字体: 】 【关闭
评论:共5条
评论人: 匿名用户    评论时间: 2007-10-21 10:59:37
评论人: 匿名用户    评论时间: 2007-10-25 07:00:48
评论人: 匿名用户    评论时间: 2007-11-06 14:07:37
代码有明显错误啊
评论人: 匿名用户    评论时间: 2007-11-09 12:14:46
不错..
评论人: 匿名用户    评论时间: 2007-11-21 22:06:14

发表评论:
评论: 
    

相关栏目

  • 如何才能得到国外最新的技术
Copyright (C) 2005 EasyJF.com 简易java框架网 渝ICP备06004507号
如有意见请与我们联系