wenjianzhang

2006年2月24日

可恶 hibernate插件联接不上
http://www.binamics.com/hibernatesync 
连接不上

有没有新的地址 , 或是其他办法请高手指教!!!
posted @ 2006-02-24 11:18 不老的传说 阅读(355) | 评论 (1) | 编辑 收藏
 

2006年2月23日

在Middlegen-Hibernate中设置oracle.xml实例

   <!-- =================================================================== -->
   <!-- ant properties/targets for oracle 8/9                               -->
   <!-- note: this is not a proper xml file (there is no root element)      -->
   <!--       it is intended to be imported from a *real* xml file          -->
   <!-- =================================================================== -->

   <!-- please set your Oracle-SID according to your needs -->

   <property environment="env"/>

   <property name="database.script.file"           value="${src.dir}/sql/${name}-oracle.sql"/>
   <!--property name="database.driver.file"           value="${env.ORACLE_HOME}/jdbc/lib/classes12.jar"/-->
   <property name="database.driver.file"           value="${lib.dir}/classes12.jar"/>
   <property name="database.driver.classpath"      value="${database.driver.file}"/>
   <property name="database.driver"                value="oracle.jdbc.driver.OracleDriver"/>
   <property name="database.url"                   value="jdbc:oracle:thin:@localhost:1521:oracle"/>
   <property name="database.userid"                value="scott"/>
   <property name="database.password"              value="tiger"/>
   <property name="database.schema"                value="scott"/>
   <property name="database.catalog"               value=""/>

   <!--property name="jboss.datasource.mapping"       value="Oracle7"/-->
   <!--property name="jboss.datasource.mapping"       value="Oracle8"/-->
   <property name="jboss.datasource.mapping"       value="Oracle9i"/>
1. 注意一定要设置SCHEMA
2. 用了默认的driver.file设置,在执行ant时出错,我就把oracle_home/jdbc/lib下的jar文件拷贝到 lib 目录下了,再修改driver.file属性即可

posted @ 2006-02-23 11:29 不老的传说 阅读(953) | 评论 (0) | 编辑 收藏
 
使用MiddleGen 产生hibernate的数据库表映射文件

 1:下载Middlegen-Hibernate-r5
地址:URL http://voxel.dl.sourceforge.net/sourceforge/hibernate/Middlegen-Hibernate-r5.zip
2:解压缩
将下载的解压缩,如 D:\Middlegen-Hibernate-r5
3:配置数据库文件
进入D:\Middlegen-Hibernate-r5 目录下的\config\database 子目录,选择你要得数据库文件,我使用的是mysql.
将原来的
<property name="database.driver.file"           value="${lib.dir}/mysql-connector-java-3.0.0-beta-bin.jar"/>
改成
<property name="database.driver.file"           value="${lib.dir}/mysql-connector-java-3.0.15-ga-bin.jar"/> 
同时指定数据库与用户名。我的配置如下(红色部分是要修改的部分)
   <property name="database.script.file"           value="${src.dir}/sql/${name}-mysql.sql"/>
   <!--property name="database.driver.file"           value="${lib.dir}/mysql-connector-java-3.0.0-beta-bin.jar"/-->
   <property name="database.driver.file"           value="${lib.dir}/mysql-connector-java-3.0.15-ga-bin.jar"/> 
   <property name="database.driver.classpath"      value="${database.driver.file}"/>
   <property name="database.driver"                value="org.gjt.mm.mysql.Driver"/>
   <property name="database.url"                   value="jdbc:mysql://localhost/hibernate"/>
   <property name="database.userid"                value="root"/>
   <property name="database.password"              value=""/>
   <property name="database.schema"                value=""/>
   <property name="database.catalog"               value=""/>
   <property name="jboss.datasource.mapping"       value="mySQL"/>

将mysql的驱动程序mysql-connector-java-3.0.15-ga-bin.jar copy 到D:\Middlegen-Hibernate-r5\lib下

4:修改Build.xml
修改D:\Middlegen-Hibernate-r5目录下的build.xml 文件,此文件是Middlegen-Hibernate 的Ant
构建配置。Middlegen-Hibernate将根据build.xml 文件中的具体参数生成数据库表映射
文件

1)第24行 修改数据库连接
将hsqldb.xml 改成mysql.xml
<!ENTITY database SYSTEM "file:./config/database/mysql.xml">
2)第52行 修改输出目录
将${build.dir}/gen-src 改成你要的目录
   <property name="build.gen-src.dir"              value="D:/Middlegen-Hibernate-r5/sample"/>
3)第184行 对应代码的Package name
hibernate 节点package 属性的默认设置实际上是由前面的
Application Name (${name})和“.hibernate”组合而成,根据我们的需要,
将其改为
         <hibernate
            destination="${build.gen-src.dir}"
            package="org.hibernate.sample"
            genXDocletTags="true"
            genIntergratedCompositeKeys="false"
            javaTypeMapper="middlegen.plugins.hibernate.HibernateJavaTypeMapper"
         />
这里还有一个属性genXDocletTags,如果设置为true,则生成的代码将包含
xdoclet tag。
4)第33行 修改应用名
将原来的
   <property name="name" value="airline"/>
改成
   <property name="name" value="HibernateSample"/>

5:切换到D:\Middlegen-Hibernate-r5目录,运行ant


posted @ 2006-02-23 10:54 不老的传说 阅读(582) | 评论 (1) | 编辑 收藏
 
eclipse 的JDK设置问题
eclipse没有办法使用,提示:Required Java version:1.4.1. Available: 1.3.1_01.
我机器上装的是JDK1.5
后来发现是安装了Oracle9i自带的是jdk1.3.1,安装Oracle时自己给装上去了,把path中jdk1.3.1的bin路径给去掉,检测一下JAVA_HOME是不是指向机器上的jdk1.5.0,然后启动eclipse,就OK了
posted @ 2006-02-23 10:14 不老的传说 阅读(6945) | 评论 (1) | 编辑 收藏
 

2006年2月14日

转:利用JSF应对应用程序开发的未来

JavaServer Face为Java应用程序的开发提速。

JavaServer Faces(JSF)是一项使用Java技术来快速构建Web应用程序的新技术。JSF通过提供以下特性来加速开发进程:标准和可扩展的用户界面组件;极易配置的页面导航;用于输入验证的组件;自动化的Bean管理;事件处理;轻松的错误处理,以及内置的对国际化的支持。

本文介绍如何使用JSF来构建在线比萨(pizza)订购系统。

项目描述

该应用程序被称之为PizzaRia,是一个在线商店,允许用户选择比萨饼并递交选定的比萨饼。PizzaRia与其他在线商店类似,用户可以浏览菜单,向购物车中添加所选产品并进行结账。

该应用程序的用户界面由5个JSP文件组成,它们是index.jsp, details.jsp, shoppingCart.jsp, checkOut.jsp以及order.jsp 。每个用户界面的页面包括3个其它页面:header.jsp, menu.jsp和 footer.jsp 。

Figure 1

Figure 2

Figure 3

Figure 4

Figure 5

数据库

该程序的数据存储在3张表中:products(产品)、orders(定单)和OrderDetails(订单详细项目)。Products表存储产品信息,具有4列:ProductId(产品标识), Name(名称), Description(说明)和 Price(价格)。

Orders表中的每一行存储一个单独的订单,其中的信息包括联系人姓名、送货地址以及信用卡细目。Orders表有6列:OrderId(定单标识), ContactName(联系人姓名), DeliveryAddress(送货地址), CCName(信用卡所属人姓名), CCNumber(信用卡号码)和 CCExpiryDate(信用卡有效期限)。

每个订单的详细项目被存储在OrderDetails表中。OrderDetails表有4列:OrderId(定单标识), ProductId(产品标识), Quantity(数量)和 Price(价格)。Orders与OrderDetails表通过OrderID列有一对多的对应关系。请注意,OrderDetails表在用户下订单的时候就保存相关的价格信息。该价格可能与当前产品价格不同,后者存储在Products表的Price列中。

用于在一个Oracle数据库中创建所需的表的脚本文件pizzaria-oracle.sql存放在pizzaria.zip文件中。

业务对象

以下是在该应用程序中使用的业务对象:

ProductBean用于封装一个产品信息。它具有如下属性:id(标识)、name(名称)、description(说明)和price(价格)。每次details.asp页被访问的时候,JSF实现(implementation)就会自动创建一个ProductBean实例。该JSF实现调用ProductBean的无参数构造器,从数据库中获取相关的数据,并且将其填入相应的字列中。

ProductSummary。ProductSummary(产品概要)用于表示产品的概要。该类包含2个属性:id(标识)和name(名称)。

ShoppingItemBean。ShoppingItemBean用于表示购物项目。该类包含4个属性:productId(产品标识), productName(产品名称), price(价格)以及 quantity(数量)。

ShoppingCartBean。ShoppingCartBean用于表示一个存储在对话(session)对象中的购物车。该类允许用户添加购物项目(使用addShopping方法),获取包含所有购物项目的列表(使用getShoppingItems方法),获得所购货物的总价值(使用getTotal方法)。

OrderBean。OrderBean表示一个订单。该类具有如下5个属性:contactName, deliveryAddress, creditCardName, creditCardNumber以及 creditCardExpiryDate。

MenuBean。MenuBean使用getMenu方法显示可供产品的目录。该方法返回一个包含到产品细节的链接的HTML表。

DatabaseUtil。DatabaseUtil提供了以下3种方法以便访问和操作数据:

  • GetProductSummaries:该方法返回一个包含了产品表中所有产品概要的列表。一个产品概要通过ProductSummary类来表示。

  • GetProductDetails:该方法返回一个ProductBean对象,该对象封装具有特定标识符的产品细节。

  • InsertOrder:该方法向Orders表和OrderDetails表插入客户订单。

应用程序上下文监听器

应用程序上下文监听器(AppContextListener类)从web.xml文件读出用于访问数据库的初始参数,然后将其写入ServletContext对象。用到的初始参数如下:jdbcDriver, dbUrl, dbUserName和 dbPassword。在你的web.xml文件中编辑这些值,以便反应你数据库的真实值。

JSF应用程序配置

JSF允许编程人员仅仅通过应用程序配置文件就可以轻松配置应用程序。该文件如果存在的话,则它应该被命名为faces-config.xml,并且应该位于你应用程序下的WEB-INF 目录。

可以在faces-config.xmlz文件中对该应用程序的多个方面进行配置,包括bean管理、页面导航、定制UI(用户界面)组件、定制验证程序和消息资源。在 PizzaRia 应用程序中,我将该faces-config.xml用于bean管理和页面导航的配置。

JavaBean管理。对于JavaBean管理,可以使用应用程序配置文件faces-config.xml中的managed-bean元件。每个managed-bean元件都会注册一个JavaBean--JSF会将该JavaBean在特定的作用域内实例化和进行储存。managed-bean元件定义如下:

<!ELEMENT managed-bean (description*, display-name*, icon*, managed-bean
name, managed-bean-class, managed-bean-scope, (managed-property* | map-entries |
list-entries))>

每个managed-bean元件都必须包含一个managed-bean-name元件,一个managed-bean-class元件,以及一个managed-bean-scope元件,并且可选择性地包含一些描述、显示名、图标和managed-property/map-entries/list-entries元件。

managed-bean-name指定了被用来在整个应用程序中引用该JavaBean的名称。managed-bean-class元件包含该JavaBean的完全限度的类名。managed-bean-scope元件定义该JavaBean的作用域。该元件可能的值是:application、session、request或者none。如果managed-bean-scope元件是none以外的其他值,那么,所创建的该JavaBean元件将会被存储在相应的对象中。比如说,如果值是"session",那么,该JavaBean就会被存储在一个给定用户的session对象中。

在PizzaRia应用程序中,我注册了如代码清单1所示的4个JavaBeans。

页面导航:页面导航决定了Web应用程序的控制流。本节演示如何在JSF中创立一个页面导航。

JSF使用navigation-rule元件来为页面导航定义规则。其定义如下:

<!ELEMENT navigation-rule 
  (description*, display-name*, icon*, from-view-id?, navigation-case*)>

from-view-id元件是首页(起始页)的标识符。为了说明被称之为index.jsp的JSP页面的导航规则,下面给出子元件from-view-id的值:

<from-view-id>/index.jsp</from-view-id>

navigation-case元件表示一个可能的目标页面。navigation-rule一个元件可以有零个或者数个navigation-case子元件。

每个navigation-case元件都指定from-view-id的特定处理结果的目标页面。结果可以来自from-view-id元件中 UICommand组件的行动(action)属性。

navigation-case元件由如下所示的代码描述:

<!ELEMENT navigation-case 
(description*, display-name*, icon*, from-action?, from-outcome?, 
to-view-id, redirect?)>

to-view-id元件指定目标页面。from-outcome值是处理from-view-id的结果。该值来自于在from-view-id中触发了ActionEvent的 UICommand组件的行动属性。

from-action元件也表示处理from-view-id的结果。但其值来自于引发了ActionEvent的UICommand组件的行动属性的运算值。

代码清单2展示了在PizzaRia应用程序中使用的navigation-rule元件。

在JSP页面中使用UI组件

JSF提供两个定制标记库来帮助用户快速编写Web应用程序:HTML和Core。HTML定制标记库定义了用来表示UI组件的标记。Core定制标记库使用具有组件的验证器(validators)定义了注册事件处理器的核心行动,以及其他一些行动。你可以在自己的JSF应用程序的JSP页面中使用这两个库的标记。

为了在JSP页面中使用HTML和Core定制标记库,必须在页面中包含如下所示的taglib指令:

<%@ taglib uri="http://java.sun.com
/jsf/html/" prefix="h" %>
<%@ taglib uri="http://java.sun.com/
jsf/core/" prefix="f" %>

Prefix的属性值可以是任意值。但是,根据惯例,最好是使用"h"和"f"。

在JSF应用程序中编写JSP页面是每一个页面制作者的责任。除了布置组件之外,他们的责任还包括把组件绑定到模型对象数据并且把Core标记(诸如事件监听器和验证器)添加到组件标记中。

在HTML定制标记库中有25个标记。每个组件都呈现为一个HTML元件,而多个标记被呈现为同一个HTML元件。表1列出了HTML定制标记库中的标记。

标记 说明
Column 在UIData组件内表示一个数据列。
command_button 表示一个向服务器提交表单的按钮。
command_link 表示一个指向另一页面或者本页面内其他位置的超链接。
data_table 表示一个支持将数据绑定到一个数据对象的集合上的表。
Form 表示一个表单。
graphic_image 显示一张图片。
input_hidden 表示一个隐藏的元件。
input_secret 表示一个密码输入框。
input_text 表示一个可接受单个字符串的文本输入框。
input_textarea 表示一个可接受多个字符串的文本输入区。
Message 显示给定组件的信息。
Messages 表示一个从FacesContext中获取消息并且将其显示给用户的组件。
output_label 显示文本。
output_link 显示一个超链接。
output_message 显示给定组件的信息。
output_text 显示一行文本。
panel_grid 显示一张表。
panel_group 将一个组件集合分组。
selectboolean_checkbox 表示一个单选文本框。
selectmany_checkboxlist 显示一套复选框,用户从中可以选择多个值。
selectmany_listbox 表示一个多选下拉选择框,用户从中可以选择多个项目。
selectmany_menu 表示一个多选项目列表,用户从中可以选择多个项目。
selectone_listbox 表示一个单选下拉选择框,用户从中只能选择一个项目。
selectone_menu 表示单选项目列表,用户从中只能选择一个项目。
selectone_radio 表示一套单选按钮。

表1. HTML定制标记库

使用验证器

验证器使得输入确认简单化并且可以节省开发人员的大量编程时间。JSF提供一套验证器类用于确认输入到输入组件中的值。另外一种方法就是,如果现有的标准验证器不符合需要,那么开发人员还可以编写自己的验证器。

验证器是一个实现类(implementation class),它可以验证输入值,如果是非法输入,就会发出一个错误信息。可以通过将一个验证器嵌入一个其输入需要验证的输入组件中来使用它。如果该验证器判断出用户的输入是非法的,那么JSF servlet就会重新显示刚才提交了表单的那个JSP页面,而不会将本地值复制给绑定到该输入组件上的JavaBean实例。

JSF实现为通用的验证任务提供了3个标准验证器,包括检查必填的域内已填入内容、输入的内容符合长度和范围要求。表2列举了标准的验证器。

验证器类 标记 说明
LengthValidator validate_length 确保组件的本地值的长度在规定的范围之内。该值必须是字符串型。
LongRangeValidator validate_longrange 确保组件的本地值在规定的范围之内。该值必须能够被转换成长型。
DoubleRangeValidator validate_doublerange 确保组件的本地值在规定的范围内。该值必须能够被转换成浮点型。

表2.标准验证器

另外,HTML定制标记库中的input_text和input_textarea标记有必填的属性。如果将该属性标赋值为真,那么用户在继续进行操作之前,就必须对文本输入框元件或者文本输入区域进行填写。

在PizzaRia应用程序中,checkOut.jsp页面使用该必填的属性以便保证没有一个域是空的。


事件处理

JSP应用程序是事件驱动型的程序。在JSF中处理事件令人惊奇的简单。以下是处理步骤:

  1. 编写事件监听器。
  2. 在程序目录下的WEB-INF/classes or WEB-INF/lib目录中部署事件监听器。
  3. 在表示组件(其事件被捕获)的标记中,使用Core定制标记库中定义的action_listener或者 valuechange_listener标记。

在JSF中的事件对象。JSF中的所有事件对象必须提供javax.faces .event.FacesEvent类,以便这些事件被请求处理生命周期支持。FacesEvent类是java.util.EventObject的子类,并添加了getComponent方法,该方法返回引发该事件的UIComponent组件。

FacesEvent类有两个子类:ActionEvent和 ValueChangeEvent。ActionEvent类激活诸如UICommand组件之类的UI组件。

ValueChangeEvent类会发出一个通知,告知本地UIInput组件的值被修改了。然而,如果新值没有被成功地验证为合法的,则不会发出ValueChangeEvent通知。被加入到该类中的两个重要方法是getOldValue 和 getNewValue。getOldValue方法返回引发该事件的组件的旧值。getNewValue方法返回相应的新值。这两种方法的返回值类型都是java .lang.Object。
第三,JSF中的事件监听器。

为捕获一个JSF事件,需要使用一个事件监听器。JSF程序中的所有监听器都必须实现javax.faces.event.FacesListener接口。该接口提供java.util.EventListener接口,后者是必须由所有Java事件监听器实现的接口。

Faces Listener接口有两个子接口:ActionListener 和 ValueChangeListener。ActionListener接口是为了捕获ActionEvent而必须被实现的接口。该接口添加了一个新的方法--processAction--该方法请求处理生命周期来调用。当为之注册了ActionListener 的ActionEvent发生事件时,就会调用processAction。processAction方法的代码如下:

public void processAction(ActionEvent 
  event) 
 throws AbortProcessingException

ValueChangeListener接口是为了捕获ValueChangeEvent而实现的接口。该接口添加了一个方法:processValueChange。当ValueChangeEvent动作被其监听者监听到时,就会调用processValueChange方法。processValueChange方法的代码如下:

public void processValueChange(ValueChangeEvent
  event) 
throws AbortProcessingException

下一步

下载
JavaServer Faces (JSF)

PizzaRia应用程序

阅读
关于JavaServer Faces的更多信息
java.sun.com/j2ee/javaserverfaces/download.html
java.sun.com/webservices/downloads/webservicespack.html

在PizzaRia应用程序中,开发人员需要一个名为AppAction Listener 的ActionListener。其processAction方法从ActionEvent对象的getLocalValue方法获取传递给该方法的本地值。如果本地值为"Buy(购买)",则processAction获取与用户相关的ShoppingCartBean对象,并且将shoppingItem加入到bean中去。如果本地值为"pay(付款)",那么processAction就从session(会话)对象获取OrderBean对象和ShoppingCartBean对象,并调用DatabaseUtil对象的insertOrder方法。代码清单3描述了processAction方法。

AppActionListener类使用两个非常有用的方法:getValueBinding 和getDatabaseUtil。getValueBinding接受指定对象名的字符串,并返回一个可以向下转换类型为对象类型的ValueBinding对象。比如说,为获得用户的在应用程序配置文件中被注册成shoppingCartBean 的ShoppingCartBean实例,开发人员需要通过传递"shoppingCartBean"来调用getValueBinding。

ShoppingCartBean cart = (ShoppingCartBean) 
getValueBinding("#{shoppingCartBean}").getValue(facesContext);

getValueBinding方法如下:

private ValueBinding getValueBinding(String valueRef) {
  ApplicationFactory factory =
  (ApplicationFactory)FactoryFinder
.getFactory(FactoryFinder
.APPLICATION_FACTORY);
  Application application = factory.getApplication();
return
  application.createValueBinding
(valueRef);
  }

getDatabaseUtil方法返回一个对ServletContext中的DatabaseUtil实例的引用:

private DatabaseUtil getDatabaseUtil() {
FacesContext facesContext = FacesContext.getCurrentInstance();
ServletContext servletContext = (ServletContext)
facesContext.getExternalContext()
.getContext();
return (DatabaseUtil) servletContext
.getAttribute("DATABASE_UTIL");
  }

运行该应用程序

该PizzaRia JSF应用程序用JSF参考实现(JavaServer Faces [JSF] Beta 1.0)已做过测试。请参看该应用程序的zip文件(pizzaria.zip)中的readme.txt文件,以便获得有关部署PizzaRia应用程序的更详细信息。

posted @ 2006-02-14 13:49 不老的传说 阅读(473) | 评论 (0) | 编辑 收藏
 
转:JSF开发实战(二)

JSF开发实战(二)

bromon原创 请尊重版权

    JSF开发实战的第一篇(jsf开发实战一)演示了如何建立一个最简单的JSF应用,从那个例子中我们可以观察到JSF的页面组件是如何与后台的javabean绑定的,也看到了JSF标签的最基本使用。在本文中我们会演示一个更加复杂的应用,它包含了更丰富的JSF标签。

    要开发的例子是一个用户管理程序,管理员输入帐号与密码登陆,然后它可以看到所有用户的列表,并且可以修改或者删除其中的一些数据。利用myeclipse所带的jsf-config.xml设计器,页面流程如下:

 

    可以看出,这个应用设计到的业务逻辑有:

用户登陆、修改用户信息、增加新用户、删除用户

    我们在后台的数据库操作中使用hibernate框架来辅助开发,相关的技术细节请自行查阅文档。

    首先建立pojo文件:User.java,它包含几个基本属性:

private int id;
private String name;
private String password;
private int power;

请自行完成set/get方法,并且编写对应的hbm.xml文件。

我们的主要工作之一,是要建立好供jsf页面组件使用的javabean,把它命名为UMDelegater.java。它会调用UserManager来完成业务逻辑,这里是一个代理模式。UserManager的内容只是简单的增/删/查/改的操作,这里不再具体列出。UMDelegater的内容是:
package org.bromon.jsf.control;

import java.util.List;

import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;

import org.bromon.jsf.model.UserManager;//自行建立的工具类,负责所有的hibernate操作
import org.bromon.jsf.model.pojo.User;//pojo对象

public class UMDeletager {
    private UserManager um=new UserManager();//所有具体的方法都由它来实现
    private User user=new User();
        private DataModel allUsers=new ListDataModel();//JSF的内置对象,用来封装html中table的数据

        //----------set/get方法---------------------
    public DataModel getAllUsers() {
        return allUsers;
    }

    public void setAllUsers(List list) {
        allUsers.setWrappedData(list);
    }
    public UserManager getUm() {
        return um;
    }
    public void setUm(UserManager um) {
        this.um = um;
    }
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    
    //-----功能方法---------
    public String login()
    {
        String s=um.login(this.getUser());
        if(s.equals("ok"))
        {
            this.setAllUsers(um.loadAll());//如果登陆成功,就取出所有的用户信息
            return "login:ok";
        }else
        {
            swapper.setLoginFailInfo(s);
            return "login:fail";
        }
    }
    
    public String edit()
    {
        this.user=(User)allUsers.getRowData();//页面中的table自动返回含有id的user对象
        this.user=um.loadById(user.getId());
        if(user!=null)
        {
            return "edit";
        }else
        {
            return "error";
        }
    }
    
    public String update()
    {
        um.update(this.getUser());
        this.setAllUsers(um.loadAll());//重新取一次数据,目的是更新缓存
        return "update:ok";
    }
    
    public String addNew()
    {
        this.setUser(new User());//生成一个新的user对象,不含任何数据,它会被自动映射成一个没有数据的form
        return "add";
    }
    
    public String add()
    {
        um.add(this.getUser());
        this.setAllUsers(um.loadAll());//重新取一次数据,目的是更新缓存
        return "add:ok";
    }
}

    在jsf-config.xml中声明这个bean:

<managed-bean>
        <managed-bean-name>UMDelegater</managed-bean-name>
<managed-bean-class>org.bromon.jsf.control.UMDeletager</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>

业务逻辑就设计完成了,下面可以开始编写jsf文件,首先是index.jsp:

首先引入标签库,并且声明page属性:

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

然后是构建页面:

<body>
    <f:view>
        <h:form>
            <h:panelGrid columns="3">
                <h:outputLabel for="name" value="帐号:"/>
                <h:inputText id="name" value="#{UMDelegater.user.name}" required="true"/>
                <h:message for="name"/>
                
                <h:outputLabel for="password" value="密码:"/>
                <h:inputSecret id="password" value="#{UMDelegater.user.password}" required="true" />
                <h:message for="password"/>
            </h:panelGrid>
            <h:panelGroup>
                <h:commandButton value="登陆" action="#{UMDelegater.login}"/>
            </h:panelGroup>
        </h:form>
    </f:view>
  </body>

页面中声明了两个文本框,分别映射UMDelegater对象中user对象的name属性,和UMDelegater对象中user对象的password属性。一旦这个表单被提交,这两个文本框的值就会被自动赋给user对象,我们只需要从user中取数据就行了,不用再去执行麻烦的request.getParameter(“”),更改编码,转换数据类型等操作。

我们同时还声明了一个button,它与UMDelegater对象的login方法绑定,点击该按钮,系统会执行UMDelegater.login方法,该方法从user对象中取出name和password,和数据库中的记录进行比较。如果合法,那么就取出所有的数据,放到一个DataModel对象中,具体代码是:

List userList=UserManager.getAllUser();//取得所有用户数据,放到一个List中
DataModel allUser=new ListDataModel ();//DataModel是一个接口,ListDataModel是它的一个实现

allUsers.setWrappedData(userList);//将数据填充进去备用

使用DataModel意义何在呢?JSF中,我们可以把一个html页面上的table和一个DataModel绑定起来,这些数据会自动填充到table中,我们不必再自己去写循环,生成若干的<tr>、<td>来生成一个table。在list.jsp中我们会看到如何使用DataModel。

放好数据之后,登陆成功的操作就完成了,返回一个login:ok,就可以重定向到list.jsp。如果用户登陆失败,那么会返回login:fail,重定向到error.jsp,它的内容就不叙说了。下面我们看看list.jsp里面有什么,下面是它的<body>代码:

<body>
    <f:view>
        <h:form>
            <h:dataTable id="users" value="#{UMDelegater.allUsers}" var="u" border="1" width="80%" >
                <h:column>
                    <f:facet name="header">
                        <h:outputText value="id"/>
                    </f:facet>
                    <h:outputText value="#{u.id}"/>
                </h:column>
                
                <h:column>
                    <f:facet name="header">
                        <h:outputText value="帐号"/>
                    </f:facet>
                    <h:commandLink action="#{UMDelegater.edit}">
                        <h:outputText value="#{u.name}"/>
                    </h:commandLink>
                </h:column>
                
                <h:column>
                    <f:facet name="header">
                        <h:outputText value="密码"/>
                    </f:facet>
                    <h:outputText value="#{u.password}"/>
                </h:column>
                
                <h:column>
                    <f:facet name="header">
                        <h:outputText value="权限代码"/>
                    </f:facet>
                    <h:outputText value="#{u.power}"/>
                </h:column>
            </h:dataTable>
            <p>
                <h:commandLink action="#{UMDelegater.addNew}" value="增加用户" />
            </p>
        </h:form>
    </f:view>
  </body>

我们使用了一个h:dataTable标签,它是JSF独有的东西,它会被翻译为一个html的table,通过指定h:dataTable的value="#{UMDelegater.allUsers}"属性,它就与我们刚才生成的DataModel对象关联起来,数据会被自动填充。我们只需要声明dataTable中的每一列的表头,数据来自哪个字段就可以了,如下:
<h:column>
    <f:facet name="header">
        <h:outputText value="id"/>
    </f:facet>
    <h:outputText value="#{u.id}"/>
</h:column>

表格最后还有一个“增加用户”的按钮,它与UMDelegater.addNew绑定,它会把我们重定向到add.jsp。
需要注意的是,每个用户名都是个超链接,点击之后可以重定向到edit.jsp,这个页面可以修改用户资料。这是通过如下代码实现的:

<h:commandLink action="#{UMDelegater.edit}">
    <h:outputText value="#{u.name}"/>
</h:commandLink>

可以看出,实际上系统调用了UMDelegater.edit方法,该方法的功能是根据页面传过来的用户id查询数据库,找到相关记录后返回一个User对象,然后重定向到edit.jsp,由于我们后面编写edit.jsp的时候会把form元素与User对象绑定,所以该User对象所含有的数据会自动显示到各个form元素上。

list.jsp的显示效果如下:



看到这里你也许会问,那么我如何来美化这个表格?实际上这正式JSF这类框架面临的最大问题,它大量的使用了标签库,目前流行的网页制作工具(如deamweaver)又没有提供足够的支持,所以只能依靠挖掘dataTable标签的各个属性,并且大量依赖css才能实现页面的美化。如果java世界能有一个强大的JSF IDE,能够提供vs.net一样的能力,那么JSF也许会更容易流行。

下面我们来看看edit.jsp的内容,如下:

<body>
    <f:view>
        <h:form>
            <h:inputHidden id="id" value="#{UMDelegater.user.id}"/>
            <h:panelGrid columns="3">
                <h:outputLabel for="name" value="帐号"/>
                <h:inputText id="name" value="#{UMDelegater.user.name}" required="true"/>
                <h:message for="name"/>
                
                <h:outputLabel for="power" value="权限"/>
                <h:inputText id="power" value="#{UMDelegater.user.power}" required="true"/>
                <h:message for="power"/>
            </h:panelGrid>
            <h:panelGroup>
                <h:commandButton value="保存" action="#{UMDelegater.update}"/>
            </h:panelGroup>
        </h:form>
    </f:view>
  </body>

可以看出,edit.jsp并没有什么特别需要留意的,只是一个最简单的form与bean的绑定,“保存”按钮与UMDelegater.update方法绑定,它的功能是把修改后的form数据写入数据库,然后重新取一次数据,以免缓存做怪,看不到修改的效果。

Add.jsp也和edit.jsp很类似,它的内容如下:

<body>
    <f:view>
          <h:form>
              <h:panelGrid columns="3">
                  <h:outputLabel for="name" value="帐号:" />
                  <h:inputText id="name" value="#{UMDelegater.user.name}" required="true"/>
                  <h:message for="name"/>
                  
                  <h:outputLabel for="password" value="密码:"/>
                  <h:inputText id="password" value="#{UMDelegater.user.password}" required="true"/>
                  <h:message for="password"/>
                  
                  <h:outputLabel for="power" value="权限"/>
                  <h:inputText id="power" value="#{UMDelegater.user.power}" required="true"/>
                  <h:message for="power"/>
              </h:panelGrid>
              <h:panelGroup>
                  <h:commandButton value="保存" action="#{UMDelegater.add}"/>
              </h:panelGroup>
          </h:form>
      </f:view>
  </body>
 
posted @ 2006-02-14 13:47 不老的传说 阅读(348) | 评论 (0) | 编辑 收藏
 
转:JSF开发实战(一)

JSF开发实战(一)

bromon原创 请尊重版权

    JSF将是J2EE5.0中所包含的web开发框架,这应该是第一个成为jcp标准,并且随j2eesdk一起发布的web框架,可以看出sun对它的期望很高。JSF最大的竞争对手是tapestry,是apache的产品,但是apache又弄出了个myfaces,是对jsf标准的一个实现。也许你也和我一样,在jsf和tapestry之间犹豫很久,将来从apache的态度上应该可以看出二者的走向。在tss上有一篇比较jsf 1.0与tapestry 3.0的文章,内容很扎实到位:http://www.theserverside.com/articles/article.tss?l=JSFTapestry
JSF的竞争对手不是struts/webwork之流,它们基本上已经是不同阶段上的东西了,放在一起比较意义不大。

    JSF的开发流程和asp.net中所倡导的code behind方式很相似,核心是事件驱动,组件和标签的封装程度非常高,很多典型应用已经不需要开发者去处理http。页面操作会被自动映射到对应的java bean中,后台逻辑只需要同java bean发生交互。整个过程是通过“依赖注入(DI)”来实现的,看来这是目前解偶合的最佳途径啊,spring的影响真是深远。不过正式因为jsf采用了这样的方式,导致开发工作和以前的jsp/struts等都有非常大的不同,需要一定的时间去学习。学习之前建议先对依赖注入有比较清楚的认识,可以参考我的learn Spring in spring系列的第一篇。

    本系列将以两个例子来讲解jsf的基本开发,第一个例子当然是hello world。目前可用的jsf ide不多,ibm要到06年才能放出支持jsf的wtp版本。所以我们的例子基本以手写为主,这样也能让我们有更清楚的认识,同时推荐目前最好的jsf开发工具:myeclipse 4.0 GA。后面的例子将会有jsf和hibernate的内容,它都能给予很好的支持。由于myeclipse并不免费,所以我们除了讲解在ide中如何操作外,还会叙述手动操作的具体内容,以免过于依赖开发工具。用什么服务器都可以,这里采用了jboss 4.0.2。如果你的服务器是高版本的tomcat(5.5+),那么必须要删除它自带的一些包才能很好的支持jsf,具体细节请查看它的文档。

    请自行下载jsf ri和JSTL 1.1。

废话少说,开始了。

    在myeclipse 4.0GA中新建一个web项目,命名为hello,为项目增加对JSTL的支持:


 
在JSTL的版本中选择1.1。
该操作实际上是把jstl.jar和standard.jar加到工程中。

采用类似的操作为项目添加对jsf的支持:myeclipse?add jsf capabilities
如图:
 


其中的jsf implementation是选择使用哪中JSF实现,我们采用的是sun的jsf ri
JSF config path是配置文件的位置,保持不变
URL pattern是jsf servlet的映射方式,有两种选择,具体细节后面说明。
以上操作上是为项目加入了jsf需要的jar和tld文件,并且创建了一个faces-config.xml的配置文件。涉及到的jar有:commons-beanutils.jar    commons-collections.jar        commons-digester.jar    commons-logging.jar    jsf-api.jar        jsf-impl.jar
涉及到了jsf中所有的tld文件。

当前的faces-config.xml文件的内容是:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN" "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">

<faces-config>

</faces-config>

环境已经建立好了,现在我们要建立一个程序,它的功能是让用户在表单中输入名字,提交后系统会返回一个问候。使用jsf的以后好处是,开发人员会很自然的把mvc各层分开,不会像使用strtus那样别扭,这一点在后面的开发中感觉得到。

首先开发model层,它是个很简单的bean:
package org.bromon.jsf.model.hello;

public class SayHello {
    public String say(String name)
    {
        return "你好,"+name;
    }
}

在model层中你可以随意的实现业务的数据逻辑,不需要与web层有任何的关系。

下面开发控制层,它负责存取web层的数据,并且调用model层的逻辑:
/**
 * jsf的控制层方法
 * @author bromon
 */
package org.bromon.jsf.control.hello;

import org.bromon.jsf.model.hello.*;

public class HelloDelegater {
    
    //------属性---------
    private String name;//表单中的文本框数据会传到这里
    private String result;//web页会从这里取得运行结果
    private SayHello sayHello;//model层的对象,并不事例化,由系统注入
    
    //-----set/get--------
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public SayHello getSayHello() {
        return sayHello;
    }
    public void setSayHello(SayHello sayHello) {
        this.sayHello = sayHello;
    }
    public String getResult() {
        return result;
    }
    public void setResult(String result) {
        this.result = result;
    }
    
    //-----逻辑方法---------
    public String say()
    {
        this.setResult(sayHello.say(this.getName()));
        return "ok";
    }
}

需要注意的是,属性的名字、set/get方法的名字必须严格按照java bean规范编写,因为它们要被注入依赖时使用。sayHello对象并没有被实例化,它会在运行时由系统注入。

这两个bean当然要在系统中申明,否则无法实现DI。在faces-config.xml文件中添加内容:
<managed-bean>
        <managed-bean-name>SayHello</managed-bean-name>
        <managed-bean-class>
            org.bromon.jsf.model.hello.SayHello
        </managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>
    </managed-bean>
    <managed-bean>
        <managed-bean-name>HelloDelegater</managed-bean-name>
        <managed-bean-class>
            org.bromon.jsf.control.hello.HelloDelegater
        </managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>
        <managed-property>
            <property-name>sayHello</property-name>
            <value>#{SayHello}</value>
        </managed-property>
    </managed-bean>

    在后一个bean中,它的sayHello属性被指定要在运行时注入一个org.bromon.jsf.model.hello.SayHello的实例。

下面要编写表示层的页面,只有一个index.jsp:
需要引入两个标签库:

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
下面是构造jsf标签:

<body>
    <f:view>
        <h:form>
            <h:panelGrid columns="3">
                <h:outputLabel for="name" value="姓名:"/>
                <h:inputText id="name" value="#{HelloDelegater.name}" required="true"/>
                <h:message for="name"/>
                
                <h:outputLabel value="#{HelloDelegater.result}"/>
            </h:panelGrid>
            <h:panelGroup>
                <h:commandButton action="#{HelloDelegater.say}" value="提交"/>
            </h:panelGroup>
        </h:form>
    </f:view>
  </body>

页面中包含了一个文本框和一个label,他们分别被绑定到了HelloDelegater类的两个属性上,具体的绑定工作有系统通过翻转控制的方式调用对应的set/get方式实现。提交按钮被绑定到了HelloDelegater.say方法,该方法会把计算结果赋给result属性,它会在页面中显示出来。

因为我们在url pattern中选择了*.faces,所以我们应该访问如下地址来查看程序:
http://localhost:8080/hello/index.faces
相应的,如果你选择了/faces/*,那么就应该是:
http://localhost:8080/hello/faces/index.jsp

程序执行结果如下:


 

    下一篇文章中,将介绍一个更加复杂的用户管理程序,可以更清楚的看到jsf的特征,还会涉及到jsf的model对象一些组件的使用。
posted @ 2006-02-14 13:46 不老的传说 阅读(216) | 评论 (0) | 编辑 收藏
 
仅列出标题  
 
<2025年6月>
日一二三四五六
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

 导航

  • BlogJava
  • 首页
  • 发新随笔
  • 发新文章
  • 联系
  • 聚合
  • 管理

 统计

  • 随笔: 7
  • 文章: 0
  • 评论: 3
  • 引用: 0

常用链接

  • 我的随笔
  • 我的评论
  • 我的参与
  • 最新评论

留言簿(1)

  • 给我留言
  • 查看公开留言
  • 查看私人留言

随笔档案

  • 2006年2月 (7)

搜索

  •  

最新评论

  • 1. re: 使用MiddleGen 产生hibernate的数据库表映射文件[未登录]
  • 调通了没 ?
    求助……
    我的qq:963152558
  • --漫步者
  • 2. re: eclipse 的JDK设置问题
  • 评论内容较长,点击标题查看
  • --111
  • 3. re: 可恶 hibernate插件联接不上
  • 怎么没人能解决吗?
  • --不老的传说

阅读排行榜

  • 1. eclipse 的JDK设置问题(6945)
  • 2. 在Middlegen-Hibernate中设置oracle.xml实例(953)
  • 3. 使用MiddleGen 产生hibernate的数据库表映射文件(582)
  • 4. 转:利用JSF应对应用程序开发的未来(473)
  • 5. 可恶 hibernate插件联接不上(355)

评论排行榜

  • 1. 使用MiddleGen 产生hibernate的数据库表映射文件(1)
  • 2. eclipse 的JDK设置问题(1)
  • 3. 可恶 hibernate插件联接不上(1)
  • 4. 在Middlegen-Hibernate中设置oracle.xml实例(0)
  • 5. 转:利用JSF应对应用程序开发的未来(0)

Powered by: 博客园
模板提供:沪江博客
Copyright ©2025 不老的传说