体会真正的Struts开发

来源:互联网 发布:网络安全工程师自学 编辑:程序博客网 时间:2024/06/03 00:54

从这一期开始进入正题,以一个留言版讲解StrutsHibernate的开发。

关于留言版的页面Layout设计请参见附件的Excel文档。

 

首先我们按照惯例,写好计划表

工程卡

日期

2004-3-27 1100

工作

国际化与异常处理

执行者

杨恒贤

时间(估计)

3小时

任务列表:

l         利用UTF-8 做到国际化

l         处理JSP页面错误与StrutsJava代码错误

l         Validator验证

l         测试

备注:

任务跟踪:

日期

完成

继续

用时

备注

国际化

1200

 

0:30:00

OK

错误处理

1310

 

11000

OK

Validator验证

1400

 

050

OK

 

 

首先我们准备好制作UTF-8工具

Native2Ascii 这个文件在JDKbin目录下,利用方法如下

Native2ascii –ecoding GBK C:/GBKSource.txt C:/UTF8Source.txt

 

利用Struts资源文件达到国际化。

修改上次得Logon.jsp文件

<%@ page language="java"%>

<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%>

<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%>

<html>

    <head>

        <title><bean:message key="Logon"/></title>

    </head>

    <body>

    <html:errors property="hbm.session.error"/>

    <html:errors property="no.user"/>

    <html:errors property="hbm.session.query"/>

        <html:form action="/jsp/logon.do" focus="userName">

          <bean:message key="Logon.UserName"/> : <html:text property="userName"/><html:errors property="userName"/></br>

          <bean:message key="Logon.Password"/> : <html:text property="password"/><html:errors property="password"/></br>

            <html:submit/>

        </html:form>

    <body>

</html>

我们编写资源文件

password=<font color=red>密码格式错误</font>

userName=<font color=red>帐号格式错误</font>

hbm.session.error=建立Hibernate Session 错误。

no.user=找不到这样得用户。

hbm.session.query=Hibernate HQL 查询错误。

errors.header=</font color=red><ul>

errors.footer=</ul></font>

Logon=登陆

Logon.UserName=帐号

Logon.Password=密码

保存到C:/1.txt

然后运行

native2ascii -encoding GBK C:/1.txt C:/ApplicationResources_zh_CN.properties

将生成得C:/ApplicationResources_zh_CN.properties拷贝到src目录下,我们重新运行此登陆程序。

出现乱码,我们忘了将JSP页面编码设成UTF-8了,添加

contentType="text/html;charset=UTF-8",再次刷新

OK成功

当你在帐号框里面输入中文,但是没有通过,就会出现下图现象。

又出现乱码,这样的情况解决办法有3个:

1.  在每一个Action里面设置Response得编码,这种方法比较繁琐,每一个Action必须设置一次。

2.  利用Servlet2.3里面得过滤器,统一设置编码

3.  重载ActionServlet里面的Process函数。

 

1种方法很难通过XML配置来获得编码方式。

23可以通过Web.xml里面配置参数来解决

本文讲述时利用方式2,过滤器Filter

Tomcat里面的samples里面的Filter文件夹下有现成的编码过滤器。

拷贝来,在Eclipse利用重构,解决package不匹配问题。

下面为这个过滤器配置web.xml

<!--

        Filter

        -->

    <filter>

        <filter-name>Set Character Encoding</filter-name>

        <filter-class>com.yjsoft.filter.SetCharacterEncodingFilter</filter-class>

        <init-param>

            <param-name>encoding</param-name>

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

        </init-param>

    </filter>

    <filter-mapping>

        <filter-name>Set Character Encoding</filter-name>

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

    </filter-mapping>

    <!--

    end

    -->

再次启动Tomcat测试,OK。

下面开始处理JSP页面出错情况

添加错误页面,内容如下:

<%@ page contentType="text/html; charset=UTF-8" %>

<%@ page isErrorPage="true" %>

……其他省略,请看源文件

当要在其他页面处理Exception时,只要在头部添加

<%@ page errorPage="error.jsp" %>

测试如下:

<%@ page language="java" contentType="text/html;charset=UTF-8"%>

<%@ taglib uri="/tags/struts-bean" prefix="bean"%>

<%@ taglib uri="/tags/struts-html" prefix="html"%>

<%@ page errorPage="error.jsp" %>

 <%

    int n=0;

    int n1=10/n;

 %>

请求时转向出错页面:

下面测试Action中的Exception。

 

 

现在我们开始为Action中的异常定义处理。

先配置全局Exception

<global-exceptions>

<exception key="errors.message" path="actionerror.jsp" scope=request type="java.lang.Exception" />

</global-exceptions>

修改我们的LogonAction使其抛出一个异常。这样全局配置文件就可以进行处理了

上面的验证是通过Server端来的,我们继承了ActionForm,其实我们有一种更简单的方式,那就是利用Validator组件。

使用validator组件,既可以支持客户端的验证,同时Server端也进行同样验证。同时验证方式可以重用。

我们来认识一下Struts1.1的Validator。

1.Validators
       一个Validator就是,执行一个验证规则时Validator框架调用的一个Java类。框架根据配置文件中定义的方法签名来调用这个Validaotor类。一般情况下,每个Validator类提供一个单独的验证规则,然后这些规则可以组合成更复杂的规则集。Validator框架提供了Web应用程序需要的大多数的验证规则。你可以使用这些现有的验证规则来创建自己验证配置文件。我们也可以根据需要随意的增加更多的Validator。

 

2.配置文件

Struts1.1的Validator框架,用到这样两个配置文件,一个叫validator-rules.xml,另一个叫validation.xml;其实你也可以随意的给他们命名,甚至可以把它们合并成一个XML文件。但是,你还是最好把它们分开,因为它们各有各的用途。

Validator-rules.xml文件
 validator-rules.xml文件定义应用程序可以使用的Validator。Validator-rules.xml充当模板的作用,定义所有应用程序可能要用到的Validator。

下面我们重新设计我们的LogonForm

改为

public class LogonForm extends ValidatorForm/*ActionForm*/

我们注释掉ActionForm的Validate()函数。

我们配置Struts-config.xml文件,在文件最后增加

<plug-in className="org.apache.struts.validator.ValidatorPlugIn">

        <set-property property="pathnames" value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml" />

    </plug-in>

 

下面我们修改validation.xml文件

增加

<form name="logonForm">

            <field

                property="userName"

                depends="required">

                    <arg0 key="userName" resource="false"/>

             </field>

         <field

            property="password"

            depends="required">

            <arg0 key="password" resource="false"/>

            

         </field>

        </form>

同时在资源文件中增加

errors.required={0} is required.

 

重新启动程序,那么登陆程序服务器端验证就起作用了。

下面我们来添加Client端的Javascript验证。

 

修改Logon.jsp

<%@ page language="java" contentType="text/html;charset=UTF-8"%>

<%@ taglib uri="/tags/struts-bean" prefix="bean"%>

<%@ taglib uri="/tags/struts-html" prefix="html"%>

<%@ page errorPage="error.jsp" %>

 

<html>

    <head>

        <title><bean:message key="Logon"/></title>

    </head>

    <body>

    <html:errors property="hbm.session.error"/>

    <html:errors property="no.user"/>

    <html:errors property="hbm.session.query"/>

        <html:form action="/jsp/logon.do" focus="userName"

         onsubmit="return validateLogonForm(this)">

          <bean:message key="Logon.UserName"/> : <html:text property="userName"/><html:errors property="userName"/></br>

          <bean:message key="Logon.Password"/> : <html:text property="password"/><html:errors property="password"/></br>

            <html:submit>

                <bean:message key="Logon.Submit"/>

            </html:submit>

        </html:form>

        <html:javascript dynamicJavascript="true" staticJavascript="true" formName=logonForm/>

       

    <body>

</html>

 

OK

<name>username</name>

<value>root</value>

</parameter>

<parameter>

<name>password</name>

<value></value>

</parameter>

<parameter>

<name>driverClassName</name>

<value>com.mysql.jdbc.Driver</value>

</parameter>

<!--

   数据库地址

-->

<parameter>

<name>url</name>

<value>jdbc:mysql://localhost/test?useUnicode=true</value>

</parameter>

</ResourceParams>

</Context>

 

设置好连接池,我们对连接池进行测试

我们编写一个Servlet测试在Servlet使用连接池

代码如下

 

package com.test.web;

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

 

import javax.naming.Context;

import javax.naming.InitialContext;

import javax.naming.NamingException;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.sql.DataSource;

 

import org.apache.log4j.Logger;

/**

 * @author yanghx

* To change the template for this generated type comment go to Window -

 * Preferences - Java - Code Generation - Code and Comments

 */

public class TestServlet extends HttpServlet {

    private static Logger log = Logger.getLogger(TestServlet.class);

   

    public void init() throws ServletException {

        super.init();

        String jndiName = "java:comp/env/jdbc/mysql";

        try {

            Context ctx = new InitialContext();

            if (ctx == null) {

                log.error("找不到上下文");

                throw new Exception("找不到上下文");

            }

            DataSource ds = (DataSource) ctx.lookup(jndiName);

            Connection conn = ds.getConnection();

            PreparedStatement psmt = conn

                    .prepareStatement("select * from tbl_testhbm");

            ResultSet rs = psmt.executeQuery();

            log.info("连接池OK");

            rs.close();

        } catch (NamingException e) {

            log.error("找不到上下文" + e.getMessage());

        } catch (Exception e) {

            log.error("出现错误" + e.getMessage());

        }

    }

}

配置Web.xml使这个Servlet在启动时加载。

<servlet>

        <servlet-name>testConnectionPooler</servlet-name>

        <servlet-class>com.test.web.TestServlet</servlet-class>

        <load-on-startup>2</load-on-startup>

 </servlet>

启动Tomcat

出现信息如下

2004-3-20 org.apache.commons.modeler.Registry getRegistry

信息: Creating new Registry instance

2004-3-20 org.apache.commons.modeler.Registry getServer

信息: Creating MBeanServer

2004-3-20 org.apache.coyote.http11.Http11Protocol init

信息: Initializing Coyote HTTP/1.1 on port 80

Starting service Tomcat-Standalone

Apache Tomcat/4.1.27-LE-jdk14

2004-03-20 21:28:11,843 INFO  [main] web.TestServlet (TestServlet.java:43) - 连接池OK

2004-3-20 org.apache.struts.util.PropertyMessageResources <init>

信息: Initializing, config='org.apache.struts.util.LocalStrings', returnNull=true

2004-3-20 org.apache.struts.util.PropertyMessageResources <init>

现在我们关闭MySQL数据库服务,再重新启动Tomcat

出现信息如下

2004-3-20 org.apache.commons.modeler.Registry getRegistry

信息: Creating new Registry instance

2004-3-20 org.apache.commons.modeler.Registry getServer

信息: Creating MBeanServer

2004-3-20 org.apache.coyote.http11.Http11Protocol init

信息: Initializing Coyote HTTP/1.1 on port 80

Starting service Tomcat-Standalone

Apache Tomcat/4.1.27-LE-jdk14

2004-03-20 21:26:55,421 ERROR [main] web.TestServlet (TestServlet.java:48) - 出现错误Cannot create PoolableConnectionFactory

2004-3-20 org.apache.struts.util.PropertyMessageResources <init>

信息: Initializing, config='org.apache.struts.util.LocalStrings', returnNull=true

2004-3-20 org.apache.struts.util.PropertyMessageResources <init>

 

好了数据库连接已经成功,接下来我们重新配置Hibernate,使其支持连接池

下面我们编写生成的文件

 

首先LogonForm.java文件

public ActionErrors validate(

        ActionMapping mapping,

        HttpServletRequest request) {

        ActionErrors errors=super.validate(mapping,request);

        if(errors==null){

            errors=new ActionErrors();

        }

        if((password==null)||(password.trim().length()==0)){

            errors.add("password",new ActionError("password"));

        }

        if((userName==null)||(userName.trim().length()==0)){

            errors.add("userName",new ActionError("userName"));

        }

        return errors;

    }

修改Action类

public ActionForward execute(ActionMapping mapping, ActionForm form,

            HttpServletRequest request, HttpServletResponse response) {

        LogonForm logonForm = (LogonForm) form;

        Session s = null;

        try {

            s = YJBaseHBM.currentSession();

        } catch (HibernateException e) {

            e.printStackTrace();

            ActionErrors errors = new ActionErrors();

            errors.add("hbm.session.error",

                    new ActionError("hbm.session.error"));

            saveErrors(request, errors);

            return mapping.findForward("failure");

        }

        try {

            Query q=s.createQuery("from UserInfo  ui where ui.userName=:user and password=:password");

            q.setString("user", logonForm.getUserName());

            q.setString("password", logonForm.getPassword());

            System.out.println(q.toString());

            Iterator it = q.iterate();

            if(it.hasNext()==false){

                ActionErrors errors = new ActionErrors();

                errors.add("no.user",

                        new ActionError("no.user"));

                saveErrors(request, errors);

                return mapping.findForward("failure");

            }

            YJBaseHBM.closeSession();

        } catch (HibernateException e) {

            e.printStackTrace();

            ActionErrors errors = new ActionErrors();

            errors.add("hbm.session.query",

                    new ActionError("hbm.session.query"));

            saveErrors(request, errors);

            return mapping.findForward("failure");

        } catch (Exception e1){

            e1.printStackTrace();

            ActionErrors errors = new ActionErrors();

            errors.add("hbm.session.query",

                    new ActionError("hbm.session.query"));

            saveErrors(request, errors);

            return mapping.findForward("failure");

        }

       

        return mapping.findForward("success");

    }

logon.jsp与struts-config.xml配置修改见下载文件



原创粉丝点击