HTC:HTML Component

前些天公司做了个内部培训,主要是有几位同事要加入到一个B/S的项目中去,由有B/S开发经验的同事给他们做个培训,大致介绍一下公司目前做表示层使用的框架和技术。我由于刚进公司,比较闲,于是被拉去旁听,第一次听说了这个HTC。

其实HTC也不是什么新的东西,只不过是一个封装,由微软免费提供,当然也仅仅支持IE,而且没有文档和任何技术支持。但是HTC说起来也挺简单的,就是把最常用的表单验证、动态表单生成等封装起来,使用到的基本技术也就是CSS和JS,而我们公司在使用JSP做View的时候,还结合了一点JST,使页面代码更清晰一点。

HTC的优势就在于它提供了一种适合程序员思路的写网页的方式。本来如做客户端验证之类的问题之所以成为一个问题,就是因为这里面有一定的业务逻辑,但是放在服务器端的确没有必要,放在客户端,那就是一个老问题了??逻辑与表示混合在一起。

HTC的具体技术实现可以到网上查一下,或者到微软的网站上下一份源码看看,很简单的,就是将逻辑用js写到htc文件里,然后通过css分布给各个表单控件,这里特别要提到的是,是通过控件css的behavior属性,或者是onBehavior方法发布到各个控件的。

下载地址

http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/samples/internet/behaviors/library/webservice/default.asp

微软的refrence

http://msdn.microsoft.com/library/default.asp?url=/workshop/components/htc/reference/htcref.asp

the hibernate data access test posted by "lian"

"lian" has posted an article about hibernate data access.

for convenience,I take all these six parts together as below:

目标标题 Eclipse开发环境下Hibernate持久层数据库存取测试(1)  作者: lian  创建时间: 2005-08-12 22:01:37  最近更新: 2005-08-12 22:01:37  我要评论  订阅邮件 

内容

日期:2005年7月29日

作者:binglian

联系方式:binglianrushui@sohu.com

          QQ:284508610

开发环境配置:Eclipse3.0.2, Hibernate2.0, MYSQL数据库。

              打开MYSQL Command Line Client(MYSQL 服务器的客户端交互程序),

              输入ROOT用户登录密码。即你在安装MYSQL服务器时,为ROOT用户设置

              的密码。显示登录成功。创建数据库,此处命名为:learndiary. 输入

              use learndiary,起用此数据库; 注意以分号结尾。创建表:temp.

              表中包括的字段为:

              id bigint, name char(15), value char(30), description text.

              将hibernate.jar, hibernate-tools.jar包考贝到你所要测试的项目的lib

              目录下。如果你想为你的测试程序加入日志追踪,将common-logging.jar

              也考入lib目录下。 

目标标题 Eclipse开发环境Hibernate持久层数据库存取测试(2)  作者: lian  创建时间: 2005-08-12 22:04:49  最近更新: 2005-08-12 22:04:49  我要评论  订阅邮件 

内容

配置MYSQL驱动程序:将MYSQL驱动的jar包考贝到你所要测试的项目的lib

              目录下,并将其路径设置为系统的环境变量,即设置CLASSPATH值,包含此

              驱动程序的路径,本例中设置如下:

               CLASSPATH值 G:\Eclipse3.1Workspace\LearnDiaryV1.0\web\WEB-INF\lib

              如果你拥有一套JBuilder开发工具,打开它,测试你的MYSQL在开发环境中

              是否可以正确连接。点击JBuilder->tool->DataBase pilot,在窗口中新建

              一个到数据库learndiary的连接。设置驱动程序名和MYSQL服务器链接地址:

              driver name:com.mysql.jdbc.Driver ;

              database url:dbc:mysql://localhost:3306/learndiary

              如果你的MYSQL数据库位于同一域中的另一台机器上,将localhost替换为

              另一台机器的地址,如192.168.1.12, 3306为默认的访问MYSQL服务的端口

              号。接下来设置user name:root, 选中extended properties复选框,点击

              properties栏,在出现的对话框内选择add new , 点击左侧的name,value,

              依次输入:password, 1234, 双击required.保存退出。在DataBase pielot

              对话框内左侧点击MYSQL的+号,出现数据库连接中的动画。稍后数据库连接

              成功,右击MYSQL连接,选择CLOSE,关闭刚才的连接。退出JBuilder. 

目标标题 Eclipse开发环境Hibernate持久层数据库存取测试(3)  作者: lian  创建时间: 2005-08-12 22:05:48  最近更新: 2005-08-12 22:05:48  我要评论  订阅邮件 

内容

以上设置为开发前的预配置。下面为Eclipse开发过程中的类及文件的创建和配置。

首先创建一个新的项目。如果是新建了一个WEB Project, 可以SRC下,设置你所要的包名。此处简化为mypackage.

在这个包名下,创建一个你用以施行持久层测试的测试类,我们把它命名为:ORMService.java ,在此之前,你可

以先创建基于数据库中temp 表的Temp.java类。 Temp.java的代码如下:

/*

 * Created on 2005-7-27

 *本类用以对MYSQL数据库的测试

 *持久层组件为Hibernate

 */

package com.learndiary.website.module.beans;

import java.io.Serializable;

/**

 * @author binglian

 *本类的hbm映射文件为:Temp.hbm

 */

public class Temp implements Serializable{

private Long id;

private String name;

private String value;

private String description;

public Temp(){

}

public Temp( String Vname, String Vvalue, String Vdescription){

this.name = Vname;

this.value =Vvalue;

this.description = Vdescription;

}

/**

* @return Returns the description.

*/

public String getDescription() {

return description;

}

/**

* @param description The description to set.

*/

public void setDescription(String description) {

this.description = description;

}

/**

* @return Returns the id.

*/

public Long getId() {

return id;

}

/**

* @param id The id to set.

*/

public void setId(Long id) {

this.id = id;

}

/**

* @return Returns the name.

*/

public String getName() {

return name;

}

/**

* @param name The name to set.

*/

public void setName(String name) {

this.name = name;

}

/**

* @return Returns the value.

*/

public String getValue() {

return value;

}

/**

* @param value The value to set.

*/

public void setValue(String value) {

this.value = value;

}



目标标题 Eclipse开发环境Hibernate持久层数据库存取测试(4)  作者: lian  创建时间: 2005-08-12 22:06:58  最近更新: 2005-08-12 22:06:58  我要评论  订阅邮件 

内容

再为Temp.java到数据库中的temp表做映射,映射文件名为Temp.hbm.xml,请注意书写正确的映射文件名,

Temp.hbm.xml如下:

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping

PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>

  <class name="com.learndiary.website.module.beans.Temp" table="TEMP" >

    <cache usage="read-write"/>

    <id name="id" type="long" column="ID">

      <generator class="increment" />

    </id>

    <property name="name" type="string" >

      <column name="NAME" length="15"/>

    </property>

    <property name="value" type="string" >

      <column name="VALUE" length="30" />

    </property>

    <property name="description" type="string" >

      <column name="DESCRIPTION" />

    </property>

  </class>

</hibernate-mapping>

   其中:<id name="id" type="long" column="ID">

      <generator class="increment" />

    </id>

   这一段中的 <generator class="increment" />指定temp表的 id的设置,不由应用程序设置,由MYSQL数据库

   中的内置序列号增长器控制生成序列号。即数据库将根据每次插入的记录,自动为其生成序列号。我们在执行

   Hibernate的持久层操作,对新建的Temp类对象进行持久化保存时,也不要为这个新的对象设置其id 值。 

目标标题 Eclipse开发环境Hibernate持久层数据库存取测试(5)  作者: lian  创建时间: 2005-08-12 22:07:50  最近更新: 2005-08-12 22:07:50  我要评论  订阅邮件 

内容

回到我们刚才提到的ORMService类,我们将在这个类中调用Hibernate的持久化操作,将一个新的Temp类对象

存入数据库中。这一切都是由Hibernate经由我们为temp配置的映射文件,调用其session.save(temp)操作,

在后台执行的数据库插入动作,并不由我们费力的创建显示的connection链接并书写insert语名。

ORMService类的代码如下:

package com.learndiary.website.services;

import javax.servlet.ServletContext;

import net.sf.hibernate.*;

import net.sf.hibernate.cfg.Configuration;

import net.sf.hibernate.SessionFactory;

import net.sf.hibernate.Session;

import net.sf.hibernate.Transaction;

import java.sql.Connection;

import java.io.File;

public class ORMService {

ServletContext context = null;

private static SessionFactory sessionFactory =null;

//用以测试MYSQL数据库连接的方法

public void initSessionFactory(){

try{

File file = new File("g:\\Eclipse3.1Workspace\\LearnDiaryV1.0\\web\\WEB-INF\\src\\hibernate.cfg.xml");

Configuration cfg = new Configuration().configure(file);

SessionFactory factory = cfg.buildSessionFactory();

sessionFactory = factory;

if(sessionFactory ==null){

System.out.println("sessionFactory is null!");

}

}catch(Exception ex){

ex.printStackTrace();

}

}

public boolean saveTempData(){

boolean success = false;

String name = "binglian";

String value = "coding girl";

String description ="programer";

Session session =null;

Transaction tr =null;

try{

Temp temp = new Temp(name, value, description);

if(sessionFactory !=null){

session = sessionFactory.openSession();

tr = session.beginTransaction();

Connection con = session.connection();

if(con !=null){

session.save(temp);

session.flush();

}else{

System.out.println("the connection is null!");

}

tr.commit();

success = true;

}else{

System.out.println("the sessionFactory is null");

}

}catch(Exception eg){

try{

if(tr !=null) {tr.rollback();}

}catch(Exception eh){

eh.printStackTrace();

}

eg.printStackTrace();

System.out.println("session save failed!");

}finally{

try{

session.close();

}catch(Exception em){

em.printStackTrace();

}

}

return success;

}

        public static void main(String args[]){

ORMService ser = new ORMService();

ser.initSessionFactory();

boolean saved = ser.saveTempData();

System.out.println("data has " + saved + " saved!");

}

           

目标标题 Eclipse开发环境Hibernate持久层数据库存取测试(6)  作者: lian  创建时间: 2005-08-12 22:08:33  最近更新: 2005-08-12 22:08:33  我要评论  订阅邮件 

内容

当你看过这一段代码后,我们再回过头来讲解一下:

  File file = new File("g:\\Eclipse3.1Workspace\\LearnDiaryV1.0\\web\\WEB-INF\\src\\hibernate.cfg.xml");

  Configuration cfg = new Configuration().configure(file);

Configuration类负责管理Hibernate的配置信息,当调用new Configuration().configure()时,默认的Hibernate会在

当前的CLASSPATH中搜寻hibernate.cfg.xml并将其加载至内存中,作为后继操作的基础配置。我们也可以替换使用

hibernate.properties这个文件,但此文件在配置条目上,不及hibernate.cfg.xml丰富灵活,此处我们选用hibernate.cfg.xml

作为配置文件。在LearnDiaryV1.0\web\WEB-INF\src目录下创建这个hibernate.cfg.xml文件,当然你也可以把它放在mypackage包

下或其它你想要找到它的地方,重要的是你要把它的绝对路径放在上面所示的FILE类下:

    new File("g:\\Eclipse3.1Workspace\\LearnDiaryV1.0\\web\\WEB-INF\\src\\hibernate.cfg.xml");

请注意正确的路径书写样式,采用"\\"表示下一级路径。

调试运行你的程序,选中窗口内的ORMService,点击工具栏中的运行图标,以Java application程序运行,注意下方的

Consle控制台输入信息,显示:

  Hibernate: insert into TEMP (NAME, VALUE, DESCRIPTION, ID) values (?, ?, ?, ?)

data has true saved!

以上英文信息很粗劣,你可以添加更正为你的正确的输出信息。本例省略了log日志创建代码。

关于Hibernate的持久化组件实现细节的解释,请详见Learndiary开发方案及相关的Hibernate教程。

初你的工作顺利,成功!

                                    冰莲如水。 

a difficut:struts module

For my viewpoint,struts module should be a useful technique.It offer a framework to resolve a important aspect of OOP.

So,I think we can import this technique in our future Learndiary Version for extension goal.And,I have tried to use this in fileSharing trial system(there are problem in this using for my inapprehension on this technique.)

But,from some resource of learning it,I found there are many restricts on this-all of a module:include action,jsp,messageresource,datasource...,are added the module prefix automatically!e.g.,a path of jsp is:/WEB-INF/amodule/test.jsp,it will be /amodule/WEB-INF/amodule/test.jsp.And,the action is so too.

I feel the struts module is a bit complex.

很久没来了

换了一个工作,忙着做交接。主要是原来的工作太轻闲了,实在对自己的发展不利。新的工作与原来的类似,但是公司规模更大一些,也更正规一些。目前也在使用Hibernate+Struts的框架,我现在正在学习,平时零散的学习笔记会写在自己的blog上,以后会整理后贴到这里的。

我觉得使用开源软件对于学习的最大的好处就是可以去看源码,看看牛人们是怎么写程序的,而且可以从中理解框架的原理和思想。譬如DAO、譬如MVC、由譬如DI和AOP,为什么要实现这些模式,又是怎么实现这些模式的。今天看到csdn的java emag上采访Adams,JDO成员组的专家,他说,JDO不是凭空出现的,早在java诞生前,他们就用c做过一个O/R Mapping概念的组件了。实际上Hibernate、Struts、Spring这些眼下很红火的东东,其中的思想也是很早就有了,它们都是多年来经验的总结。

另外,看源码的另一个好处就是知道了很多很实用但一直不被多数了解的东西,即框架背后默默无闻的那些工具包,比如负责事务处理的jta,有比如jakarta commons下面的许多包,像Digester和BeanUtils,还有像Antlr。另外也包括像maven这样的工具,还有docbook,原来大牛们都用啊......

看源码最后一个好处就是遇到后来新出的东西也不会害怕了,即使是不同的思想,但是框架的原理是一样的,或者目的是一样的,只是实现方式不同,就算不一样,也可以有个参照么。像我们这些整体闲着的,或者是学生,没太多实践的机会,如果看通源码,那出去和人侃,照样能把人侃晕啊,hiahia~~

need "j2ee.jar" added to classpath when hibernate

Today,I am trying Hibernate and use Hibernatesynch for eclipse2.1 plugin got some classes.

When I run this program on Tomcat5.0,the page always reports:

HTTP Status 500 -

--------------------------------------------------------------------------------

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

javax.servlet.ServletException: Servlet execution threw an exception

root cause

java.lang.NoClassDefFoundError: javax/transaction/Synchronization

net.sf.hibernate.impl.SessionFactoryImpl.openSession(SessionFactoryImpl.java:314)

net.sf.hibernate.impl.SessionFactoryImpl.openSession(SessionFactoryImpl.java:327)

net.sf.hibernate.impl.SessionFactoryImpl.openSession(SessionFactoryImpl.java:335)

com.asprise.business._BaseRootDAO.createSession(_BaseRootDAO.java:116)

com.asprise.business._BaseRootDAO.createSession(_BaseRootDAO.java:107)

com.asprise.business._BaseRootDAO.getSession(_BaseRootDAO.java:99)

com.asprise.business._BaseRootDAO.find(_BaseRootDAO.java:162)

com.asprise.business.UserBean.findUsers(UserBean.java:23)

com.asprise.struts.action.OwnerAction.performViewUsers(OwnerAction.java:61)

com.asprise.struts.action.OwnerAction.execute(OwnerAction.java:51)

org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:448)

org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:263)

org.apache.struts.action.ActionServlet.process(ActionServlet.java:1176)

org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:454)

javax.servlet.http.HttpServlet.service(HttpServlet.java:697)

javax.servlet.http.HttpServlet.service(HttpServlet.java:810)

note The full stack trace of the root cause is available in the Apache Tomcat/5.0.25 logs.

--------------------------------------------------------------------------------

Apache Tomcat/5.0.25

I found there are two ways to resolve this problem:

1.add j2ee.jar to program's "/web-inf/lib" folder or javax.transaction.Synchronization.class to it's "/web-inf/classes" folder;

2.add the file to tomcat's "/common/lib" or "/common/classes" as above.

I don't know why this happened,I have configed the classpath environment "d:\j2ee1.3\lib\j2ee.jar",and configed the "J2EE_HOME" is "d:\j2ee1.3".

Is there anyone can answer me this question,by any chance please?

Struts开发技巧

/*看到这篇文章不错,害怕后来被删除了,于是把它保存在这里。*/

  Struts开发技巧

Struts配置文件

事件对应的类主要有Action、ActionForm

struts开发中一些的规范

Struts开发技巧

谢?

在经历了《中国电信大客户贴心服务》项目的开发以及目前正在开发中的《中国电信经营分析》项目,已累计了一些对于Struts1.1和Tiles开发的一些技术和技巧,特写出来,方便以后的开发,同时也相信能给读者在开发Struts方面提供一些帮助。

在经历了《中国电信大客户贴心服务》项目的开发以及目前正在开发中的《中国电信经营分析》项目,已累计了一些对于Struts1.1和Tiles开发的一些技术和技巧,特写出来,方便以后的开发,同时也相信能给读者在开发Struts方面提供一些帮助。

模块配置

1.     Struts配置文件定义

   对于系统中的某个模块,需要在开发前定义该模块的配置,该struts的配置文件命名为:

struts-config-xxx.xml

xxx为模块的小写英文名或缩写,如:struts-config-sysman.xml

注意:中间为"-",而不是"_"连接符

统一保存在"WEB-INF\xml"文件夹下,并需要在web.xml中添加相应的配置文件

地址,具体如下例:

       ...

  <init-param>

      <param-name>config</param-name>

      <param-value>/WEB-INF/struts-config.xml, /WEB-INF/xml/struts-config-pages.xml,/WEB-INF/xml/struts-config-sysman.xml</param-value>

       </init-param>

...

注意:需要用","连接符隔开各个配置文件名

另外,所有的静态jsp需要通过配置文件定义其".do"形式的访问,保存在

struts-config-pages.xml文件中,内容如下例:

  ...

  <!--主页转向-->

  <action path="/main" type="org.apache.struts.actions.ForwardAction" parameter="/main.jsp"/>

  ...

2.         Tiles配置文件定义

系统的框架配置文件为tiles-defs_zh_CN.xml(通过.properties属性文件支持国际化应用,默认是tiles-defs.xml),模块的框架结构需要定义在里面,如下例:

...

<!-- 定义默认首页 -->

    <definition name="default.frame" path="/layouts/defaultLayout.jsp">

        <put name="title"  value="欢迎进入电信经营分析系统" />

        <put name="header" value="/top.jsp" />

        <put name="body"   value="default.body" />

        <put name="footer" value="/buttom.jsp" />

    </definition>

<!-- 定义默认首页的body -->  

    <definition name="default.body" path="/layouts/main.jsp" >

  <put name="logon"   value="/logon.jsp" />

  <put name="date" value="/layouts/date.jsp" />

       <put name="linkSite"   value="/layouts/link.html" />

    </definition>

...

框架命名规范按"系统(子系统).功能模块.页面模块",如上面的"default.frame"

在struts-config-pages.xml文件中的设置的页面action可以这样写:

<action path="/main" type="org.apache.struts.actions.ForwardAction" parameter=" default.frame "/>

这样就不必单独写一个tiles:insert的页面,如下:

<tiles:insert definition="vip.warn.day" flush="true" />

3.         模块中的注释

不但需要在程序中添加必要的注释,在定义配置文件的时候也必须需要添加相应注释,主要是在struts-config-xxx.xml和tiles- defs_zh_CN.xml这些文件中添加注释,要把action或配置模块的功能解释清楚,放在配置项的前面,参见上面的配置文件

4.         对于配置文件的编辑

不能使用Jbuilder里面的xml编辑功能,因为JB会自动地改变xml里面的编码和内容,因此,对xml配置文件的编辑,要使用编辑软件,如UE等

事件定义

事件对应的类主要有Action、ActionForm,还有jsp中提交的".do"定义,以及页面动作的提交,以login登录为例:

1.  类的命名定义(首字母需大写)

形式为"动作名+Action/Form"

如:LoginAction.class、LoginForm.class

2.  页面地址定义(首字母需小写)

如果有两个单词以上,第二个单词首字母大写,依此类推

形式为"动作名"

如:login.do或loginSys.do

jsp文件命名也按此规范

3.  页面动作定义

因为jsp页面中的Form对应ActionForm,其本身有action这个属性,所以页面动作如果定义也为action,会引起不必要的麻烦,所以,把页面动作统一定义为"act",

如需要编辑某条记录,地址如下:

"/editRecord.do?act= Edit"

如需要删除,地址如下:

"/editRecord.do?act=Delete"

4.  对于菜单和操作事件触发的控制机制

由于系统中的菜单和操作都是由".do"形式向服务端发请求的,因此需要一套机制来控制哪些是对菜单的事件请求,哪些是对操作的事件请求;

我们在系统中引入了Filter过滤器,对所有请求进行控制,以及判断用户是否登录和是否有对资源(菜单等)访问权限等;

约定:

jsp页面上对于系统中菜单的请求都是"GET"方法,对于操作的Action都是"POST"方法;

有了这样的约定,在Filter中先判断request的请求方法,如果是"GET"方法,则认为是对菜单的请求,所以去"菜单表"根据请求地址读取相应的记录,并读取用户的权限表,判断用户的菜单权限;

如果是"POST"的方法,则认为是对操作的请求,并提取request中的"act"动作,进行对用户的权限点的判定。

 

参数信息获取

1.         公共参数信息通过Plugin方式在Web服务启动时将变量放入application中,使得在任何需要该变量的jsp中都可以调用;

方式如下:

public void setServletContext(ActionServlet actionServlet) {

try {

        ServletContext sc = actionServlet.getServletContext();

        //SysInitPwd

   sc.setAttribute(Constants.SYS_INIT_PWD,SelectLists.getSysConfig("PWDINIT"));

...

在action等程序中的调用方式:

getServlet().getServletContext().getAttribute("...");

 

2.         对于页面上需要展示的数据尽量存放在request这个范围里,可以减轻服务器端内存负载,方式如下:

//调用员工处理类

StaffDeal sd=new StaffDeal();

//根据员工状态查询员工

ArrayList al=sd.qryStaff(strState);

//放入request

    request.setAttribute("staffInfo",al);

3.         私有的或需要根据用户的属性来获取参数信息的,可以在tiles的定义中使用"controlClass=xxx"这个方式获取,配置如下例:

<definition name="vip.welcome" path="/vip/welcome.jsp" controllerClass="viptx.logic.vip.welcomeAction" />

需implements Controller中的perform方法,代码如下例:

public void perform(ComponentContext componentContext,

                      HttpServletRequest request,

                      HttpServletResponse response,

                      ServletContext servletContext) throws IOException,ServletException  {

    HttpSession session = request.getSession();

    // Get current session.

    User user = (User) session.getAttribute(Constants.USER_KEY);

    if (user == null) {

      return null;

    }

    String uid = user.getUserid();

    String sql = "select userid,content from ti_salutatory where userid='"+uid+"'";

    try {

      ...

    }

    catch (Exception ex) {

      throw new ServletException(ex.getMessage());

    }

}

4.         对于后台出错信息在前台页面显示的技巧

首先在properties配置"message.common={0}"

然后在Action类中使用ActionErrors或ActionMessages时,方法如下:

...

ActionMessages ams = new ActionMessages(); //例外处理

Try{

...

}

catch (Exception ex) {

    ex.printStackTrace();

    ams.add(ActionMessages.GLOBAL_MESSAGE,

                 new ActionMessage("message.common", ex.getMessage()));

}

                finally {

if (!ams.isEmpty()) {

        saveMessages(request, ams);

     }

}

...

        在jsp页面中使用方法如下:

        <html:messages id="msg" message="true">

               <font color="red"><bean:write name="msg"/></font>

        </html:messages>

        如果有后台的messages产生,前台页面就可以出现报错信息

5.         系统配置文件

系统参数如数据库连接等在sysConfi.xml文件中配置,存放在"WEB-INF/xml"文件夹下,请参见该文件。

开发规范和公用方法

关于java的开发规范参见《Java 编程规范.doc》,这里仅给出用struts开发中一些的规范:

1.         java文件存放按业务逻辑划分,并用模块作为包名的形式,如:telecombi.logic.sysman.security

包名都为小写形式

所有的Action和ActionForm都存放在同一包下,便于管理,不要跨包调用

2.         所有ActionForm中的属性均为"首单词小写+第二个单词首字母大写+..."的形式,如:staffId、staffName,不允许使用"_"为单词连接符

3.         需要验证的页面,均需要客户端和服务端两次验证(即对jsp中的Form进行javascript验证和Action中的excute方法中进行验证),不能只采用其中一种方法,防止客户绕过js直接提交;

在验证登录提交的form时,必须使用staticJavascript="false",否则就会把javascript写到页面里,如:

<html:javascript formName="logonForm"

        dynamicJavascript="true"

         staticJavascript="false"/>

<script language="Javascript1.1" src="staticJavascript.jsp"></script>

验证的formName必须和validation.xml中的Form的名字对应起来,否则验证无效

4.         ActionForm是代表html中的Form的,其中的变量需要和Form中的属性对应起来,如:要在jsp中使用<form:text property="userName"/>,则使用的ActionForm中就必须有userName这个变量

5.         对于Action中的逻辑,如果处理方法在一个以上,需要另外新建一个处理类,负责对Action中的逻辑集中处理,命名为xxxDeal,如:LoginDeal;

Action通过调用该处理类的方法,实现业务逻辑处理

6.         对数据库的操作使用DBManager这个类,对其中的一些方法,具体介绍如下:

n         查询结果对象化的Select操作,使用Select(String sql,String className)方法

StringBuffer sql = new StringBuffer(

        "select staff_id staffId from ts_m_staff ")

        .append("where staff_id='").append(uid).append("'");

    try {

/**

*       User是一个用户对象类,其中有staffId这个属性,以及对应的get/set方法,通过

*        DBManager的Select方法获得一个User的ArrayList集合

*/

ArrayList rs = DBManager.Select(sql.toString(), User.class.getName());

/**

*   如果确定返回的只有一个对象,则可以使用

*

*/

User user=(User)rs.get(0);

    }

    catch (Exception ex) {

      throw new ServletException(ex.getMessage());

}

取出来的数据可以存放在session或page等里,供jsp页面调用,方法为session.setAttribute("user",user1)

...

n         Insert或Update等操作

使用DBManager里面的executeSql(String sql)方法,如果是批量处理,使用executeBatchSql(String[] sqls)方法,返回成功标志为Constants.OPERATE_SUCCESS

失败标志为Constants.OPERATE_FAILED

暂无其它信息返回

n         ResultSet对象向Hashtable集合对象的转化,使用select(String sql)方法:

除了可以使用DBManager的Select把查询结果转为对象以外,还可以使用以前的直接使用ResultSet对象的方式,不过这里返回的数据集对象为Hashtable;

Hashtable存放的数据结构为:

columnName1 ? ArrayList1(该字段的结果集)

columnName2 ? ArrayList2(该字段的结果集)

...

        系统中使用该方法的比较多的是用在生成下拉框数据,从select方法返回的Hashtable取到字段值,并生成LabelValueBean,具体方法如下:

        /**公用函数 Hashtable 转换成 ArrayList (LabelValueBean)*/

   private static ArrayList hashToLVB(Hashtable ht, String id, String name,boolean hasBlank) {

      if (ht!=null){

         ArrayList al = new ArrayList();

         ArrayList alId = (ArrayList) ht.get(id.toUpperCase());

         ArrayList alName = (ArrayList) ht.get(name.toUpperCase());

         int iLen = alId.size();

         if (hasBlank)

            al.add(new LabelValueBean("未知", "-1"));

         for (int i = 0; i < iLen; i++) {

            al.add(new LabelValueBean( (String) alName.get(i),

                                      (String) alId.get(i)));

         }

         return al;

      }

      else{

         return null;

      }

   }

n         AutoSetForm(String sql, Object frm)方法介绍:

a)         该方法可以返回一个查询数据库后已对其中的属性赋值的对象,使用方法如下:

User user=DBManager. AutoSetForm(sql,new User());

sql为查询语句

b)        该方法还可以对页面操作后的Form进行赋值,比如在页面上提交一个对某条记录进行编辑的操作,当Action得到该条记录的Id号并查询数据库成功后,需要把各个详细信息set到ActionForm的属性变量中去,这个时候就可以使用该方法,方法如下:

form= DBManager. AutoSetForm(sql,form);

form为Action的excute方法中传入的ActionForm

 

7.         调用存储过程

使用DBManager中的execProc(String procName,ArrayList procPrts)方法

procName为存储过程名,procPrts是该存储过程的入口参数集,返回的是ProcOuts的对象,其中有Result和ExceptionInfo两个属性,表示返回的处理标记和异常信息(如果有的话)

8.         数据操作返回信息的处理

在对数据操作完成后,需要返回操作是否成功等信息,具体步骤如下:

n         使用属性文件中的"messages.comm"这个key,可以对该key添加具体返回信息

n         程序中使用"ActionMessages"这个对象,java程序如下:

ActionMessages ams = new ActionMessages();

...

//执行结果

         ProcOuts pResult=null;

//是否调用成功

         if (pResult.getResult() == -1) {

               ams.add(ActionMessages.GLOBAL_MESSAGE,

                       new ActionMessage("message.common",

                                         pResult.getExceptionInfo()));

         }

if (!ams.isEmpty()) {

            saveMessages(request, ams);

         }

Jsp中调用方法如下:

<html:messages id="msg" message="true">

  <font color="red"><bean:write name="msg"/></font>

</html:messages>

 

- 作者: 张丘 2004年12月21日, 星期二 15:26  回复(0) |  引用(0) 加入博