网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > Java
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
本月文章推荐
.非常不错的SCJP真题回忆.
.JavaBeans和关系数据库的镜像.
.Java Application启动画面的制作.
.JSF 中使用自定义 Nav.
.使用SOAP开发Java Web服务详解.
.《java与模式》读书笔记 ----模式.
.优化 Java 垃圾收集器改进系统性.
.Java程序的编码规范.
.Apache Geronimo 1.0 M3 Released.
.JBuilder 编辑器常规设置及优化(.
.Apusic 应用服务器简介.
.构建WAP应用程序开发环境.
.关于Servlet.
.设计模式在EJB中的应用(上).
.探索 CORBA 技术的应用领域.
.2005年度Java十大新技术和新产品.
.教您如何用Zeus实现XML-Java的数.
.使用JMX监控应用程序内、外部的状.
.pnews.template模板.
.Springframwork中集成Velocity的.

开源技术——体验Struts

发表日期:2008-1-5


用户登陆的实现

看到题目,您一定觉得很土,Struts早已风靡,而关于Stuts的文章也早已遍地都是,假如你觉得土那你就别看了,我只是把我这段时间学到的一些比较肤浅知识在这里记录一下,假如您真在这些连载文章中获得了您想要的知识,那么我就会很欣慰了。
        这不快毕业了吗?我选的题目就和Struts有关,做一个关于学校的毕业设计选题系统,就是B/S结构,访问数据库的一些俗套的东西,为了巩固我这段时间学习Struts,我把这个系统竟往难里做,这样对我这个动手能力差的人,实际工作经验少的人来说,会有点帮助吧?
        当初就是这样想的,所以就开始了我的Struts之旅。
        那我就从我的第一页讲起吧,当然第一页一般都是登陆,至于怎么配置Struts,您还是参考一些别人的文章吧,我觉得写这些就够土的了,写怎么配置,怎么实现就更土!

        <%@ page contentType="text/Html; charset=gb2312"%>
        <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
       <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
       这句是生成验证登陆表单所需要的js代码
      
            用户名:
            密码:   
                           
                                                               onclick="window.location='ajax.do?method=register'" value="注册"/>
                           
       


       把控制格式的HTML删除掉,应该剩下这些就是主干了,对于这个毕业设计选题系统,有三种角色,治理员(Admin),教师(Teacher),学生(Student)而我把他们的登陆都做到了一起,在后台这三种角色也是都放在了一个表中,对于他们这三种对象,都是继续于Person的类,所以在登陆时可以忽视他们的具体角色,用多态来实现登陆。        


    action="/ajax.do?method=login" :将一些关于登陆啊,注册的一些乱七八糟的操作我都放到了一个DispatchAction,之后可以用method的不同来分别调用不同的功能。
   onsubmit="return validateLoginForm(this)":这个是用来实现Struts自带的validate验证
    :是用来显示在登陆时的错误信息

    在这里需要的Struts相关配置会有如下的几个方面:
      首先是要对配置文件进行配置我们登陆时需要的FormBean和Action
       (1)struts-config.XML:
            
           
                     对于登陆失败,我们预备返回到这里
           
     (2)validation.xml:
            
                  user
                  ^[0-9a-zA-Z]*$
               这里是常量配置,因为我们还会需要到用户名的验证,所以把他设置为了常量
           

          下面是对这个bean的具体严整手段了,按字段field分别来写他们所依靠depaends的检验手段,常用的有必须填required,正则表达式验证mask,最大maxlength和最小minlength
            

                                 从application.properties里读取input.user.mask           
                    从application.properties里读取input.user
                  
                  
                  以上三部分构成了js的一条错误提示,以下是具体的严整规则了

               
                    mask
                    ${user}
                

                
                    minlength
                    1
                

                
                    maxlength
                    16
                

         

       depends="required,mask,minlength,maxlength">
    
         resource="false" />
         resource="false" />
    
     mask
     ${password}
    

    
     minlength
     1
    

    
     maxlength
     16
    

   

  

 对于我们需要的FormBean是这样写的:
package com.boya.subject.view;

import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.*;

public class LoginForm extends ActionForm
{
    private static final long serialVersionUID = 1L;
    private String user = null;
    private String password = null;

    public String getPassword()

    {
        return password;
    }

    public void setPassword( String password )
    {
        this.password = password;
    }

    public String getUser()
    {
        return user;
    }

    public void setUser( String user )
    {
        this.user = user;
    }
   
    public void reset(ActionMapping mapping,HttpServletRequest request)
    {
        this.password = null;这里很重要,当用户输入有错时,需要返回登陆界面给用户,为了用户填写方便我们可以设置返回给用户的哪部分信息设置为空
    }
}

我用来实现登陆的DispatchAction代码如下:
      public ActionForward login( ActionMapping mapping, ActionForm form,
            HttpServletRequest req, HttpServletResponse res ) throws Exception
    {
         Service service = getService();调用业务逻辑
        LoginForm loginForm = (LoginForm) form;获取formbean
        String user = loginForm.getUser();提取用户名
        Person person = service.getUser( user );从业务逻辑中查找用户
        ActionMessages messages = new ActionMessages();
        ActionMessage am;
        if ( person == null )假如用户不存在,我们就返回
        {
            am = new ActionMessage( "index.jsp.fail.user", user );参数的意义:第一个是主串,而后面的作为arg数组
            messages.add( "user", am );把错误信息放到errors 属性为user那里去显示
            saveErrors( req, messages );
            form.reset( mapping, req );假如出现错误,调用formbean的重置功能
            return mapping.findForward( ID.FAIL );
        }
        if ( !person.getPassword().equals( loginForm.getPassword() ) )假如密码不一致
        {
            am = new ActionMessage( "index.jsp.fail.password", user );
            messages.add( "password", am );

            saveErrors( req, messages );
            form.reset( mapping, req );
            return mapping.findForward( ID.FAIL );
        }
       
        setSessionObject( req, person.getType(), person );把用户放到session里
        return new ActionForward( person.getType() + ".do", true );我在每个类型用户的类中加入了一个getType来在这里调用,之后动态的去对应的admin.do,student.do,teacher.do的主页面,并且这里实现的不是请求转发,而是请求从定向
   }


 

整体结构

为了让大家更方便的了解我这个设计,我先把我的一些整体的规划都说出来吧,由于我是初学,难免会参照本书籍来看,我买的是那本孙某女的书《精通:*****》,看了看她前面的介绍,我一看了不得,能出书,写的还都不错,这女的可不得了,渐渐迷惑的地方非常多,比如例子里面注释都拽上了英语,搞不懂,而当我从网上下到电子盗版jakarta struts(我已安下栽说明要求的那样在24小时后删除了)这本书的时候我才恍然大悟,原来是抄袭啊?至于是谁抄的谁,口说无凭,不能乱诽谤,不过大家心里都该有杆称!

下面就是代码了:
package com.boya.subject.model;
public interface Person
{
    public Long getId();
    public void setId( Long id );
    public String getName();
    public void setName( String name );
    public String getPassword();
    public void setPassword( String password );
    public String getTelphone();
    public void setTelphone( String telphone );
    public String getUser();
    public void setUser( String user );
    public String getType();
}

package com.boya.subject.model;
public abstract class User implements Person
{
    private Long id;数据库id
    private String user;用户名
    private String password;密码
    private String name;姓名
    private String telphone;电话

    public Long getId()
    {
        return id;
    }

    public void setId( Long id )
    {
        this.id = id;
    }

    public String getName()
    {
        return name;
    }

    public void setName( String name )
    {
        this.name = name;
    }

    public String getPassword()
    {

        return password;
    }

    public void setPassword( String password )
    {
        this.password = password;
    }

    public String getTelphone()
    {
        return telphone;
    }

    public void setTelphone( String telphone )
    {
        this.telphone = telphone;
    }

    public String getUser()
    {
        return user;
    }

    public void setUser( String user )
    {
        this.user = user;
    }
}

package com.boya.subject.model;
public class Admin extends User
{
    private String grade = null; 治理员权限

    public String getGrade()
    {
        return grade;
    }

    public void setGrade( String grade )
    {
        this.grade = grade;
    }

    public String getType()
    {
        return "admin";
    }
}

package com.boya.subject.model;
public class Teacher extends User
{
    private String level; 教师职称

    public String getLevel()
    {
        return level;
    }

    public void setLevel( String level )
    {
        this.level = level;
    }

    public String getType()
    {
        return "teacher";
    }
}

package com.boya.subject.model;

public class Student extends User
{
    private String sn;学生学号
    private SchoolClass schoolClass; 班级

    public SchoolClass getSchoolClass()
    {
        return schoolClass;
    }

    public void setSchoolClass( SchoolClass schoolClass )

    {
        this.schoolClass = schoolClass;
    }

    public String getSn()
    {
        return sn;
    }

    public void setSn( String sn )
    {
        this.sn = sn;
    }

    public String getType()
    {
        return "student";
    }
}

而对于Action我分别做了一个抽象类,之后别的从这里继续
先是Action的
package com.boya.subject.controller;

import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import com.boya.subject.frame.ID;
import com.boya.subject.frame.ServiceFactory;
import com.boya.subject.model.Person;
import com.boya.subject.service.Service;
import com.boya.subject.util.HtmlUtil;

public abstract class BaseAction extends Action
{
    /**
     * 由服务工厂方法创建服务
     * @return 数据库操作的服务
     * 2006-5-16 18:10:04
     */
    public Service getService()
    {
        ServiceFactory factory = (ServiceFactory) getAppObject( ID.SF );
        Service service = null;
        try
        {
            service = factory.createService();
        }
        catch ( Exception e )
        {
        }
        return service;
    }

    /**
     * 判定用户是否合法登陆
     * @param req
     * @return 用户是否登陆
     * 2006-5-16 18:11:26
     */
    public boolean isLogin( HttpServletRequest req )
    {
        if ( getPerson( req ) != null ) return true;
        else
            return false;

    }

   
    /**
     * 抽象方法,子类实现
     * @param mapping
     * @param form
     * @param req
     * @param res
     * @return
     * @throws Exception
     * 2006-5-16 18:12:54
     */
    protected abstract ActionForward executeAction( ActionMapping mapping,
            ActionForm form, HttpServletRequest req, HttpServletResponse res )
            throws Exception;

    /**
     * 获取session范围的用户
     * @param req
     * @return 当前用户
     * 2006-5-16 18:13:35
     */
    public abstract Person getPerson( HttpServletRequest req );

    /**
     * 父类的执行Action
     * @see org.apache.struts.action.Action#execute(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    public ActionForward execute( ActionMapping mapping, ActionForm form,
            HttpServletRequest req, HttpServletResponse res ) throws Exception
    {
        if ( !isLogin( req ) )
        {
            HtmlUtil.callParentGo( res.getWriter(), ID.M_UNLOGIN, ID.P_INDEX );
            return null;
        }
        return executeAction( mapping, form, req, res );
    }

    /**
     * 删除session中属性为attribute的对象
     * @param req
     * @param attribute 对象属性
     * 2006-5-16 18:16:59
     */
    public void removeSessionObject( HttpServletRequest req, String attribute )
    {
        HttpSession session = req.getSession();
        session.removeAttribute( attribute );
    }

    /**
     * 设置session中属性为attribute的对象
     * @param req

     * @param attribute 设置属性
     * @param o 设置对象
     * 2006-5-16 18:17:50
     */
    public void setSessionObject( HttpServletRequest req, String attribute,
            Object o )
    {
        req.getSession().setAttribute( attribute, o );
    }

    /**
     * 设置application中属性为attribute的对象
     * @param req
     * @param attribute 设置属性
     * @param o 设置对象
     * 2006-5-16 18:17:50
     */
    public void setAppObject( String attribute, Object o )
    {
        servlet.getServletContext().setAttribute( attribute, o );
    }

    public Object getSessionObject( HttpServletRequest req, String attribute )
    {
        Object obj = null;
        HttpSession session = req.getSession( false );
        if ( session != null ) obj = session.getAttribute( attribute );
        return obj;
    }

    public Object getAppObject( String attribute )
    {
        return servlet.getServletContext().getAttribute( attribute );
    }

    public void callParentGo( HttpServletResponse res, String msg, String url )
            throws IOException
    {
        HtmlUtil.callParentGo( res.getWriter(), msg, url );
    }

    public void callMeGo( HttpServletResponse res, String msg, String url )
            throws IOException
    {
        HtmlUtil.callMeGo( res.getWriter(), msg, url );
    }

    public void callBack( HttpServletResponse res, String msg )
            throws IOException
    {
        HtmlUtil.callBack( res.getWriter(), msg );
    }

    public void callMeConfirm( HttpServletResponse res, String msg, String ok,

            String no ) throws IOException
    {
        HtmlUtil.callMeConfirm( res.getWriter(), msg, ok, no );
    }
}
再是DispatchAction的
package com.boya.subject.controller;

import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import com.boya.subject.frame.ID;
import com.boya.subject.frame.ServiceFactory;
import com.boya.subject.model.Person;
import com.boya.subject.service.Service;
import com.boya.subject.util.HtmlUtil;

public abstract class BaseDispatchAction extends DispatchAction
{
    /**
     * 由服务工厂方法创建服务
     * @return 数据库操作的服务
     * 2006-5-16 18:10:04
     */
    public Service getService()
    {
        ServiceFactory factory = (ServiceFactory) getAppObject( ID.SF );
        Service service = null;
        try
        {
            service = factory.createService();
        }
        catch ( Exception e )
        {
        }
        return service;
    }

    /**
     * 判定用户是否合法登陆
     * @param req
     * @return 用户是否登陆
     * 2006-5-16 18:11:26
     */
    public boolean isLogin( HttpServletRequest req )
    {
        if ( getPerson( req ) != null ) return true;
        else
            return false;
    }

    /**
     * 获取session范围的用户
     * @param req
     * @return 当前用户
     * 2006-5-16 18:13:35
     */
    public abstract Person getPerson( HttpServletRequest req );

    /**

     * 父类的执行DispatchAction
     * @see org.apache.struts.action.Action#execute(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    public ActionForward execute( ActionMapping mapping, ActionForm form,
            HttpServletRequest req, HttpServletResponse res ) throws Exception
    {
        try
        {
            if ( !isLogin( req ) )
            {
                callParentGo( res, ID.M_UNLOGIN, ID.P_INDEX );
                return null;
            }
            return super.execute( mapping, form, req, res );
        }
        catch ( NoSUChMethodException e )
        {
            callBack( res, ID.M_NOMETHOD );
            return null;
        }
    }

    /**
     * 删除session中属性为attribute的对象
     * @param req
     * @param attribute 对象属性
     * 2006-5-16 18:16:59
     */
    public void removeSessionObject( HttpServletRequest req, String attribute )
    {
        HttpSession session = req.getSession();
        session.removeAttribute( attribute );
    }

    /**
     * 设置session中属性为attribute的对象
     * @param req
     * @param attribute 设置属性
     * @param o 设置对象
     * 2006-5-16 18:17:50
     */
    public void setSessionObject( HttpServletRequest req, String attribute,
            Object o )
    {
        req.getSession().setAttribute( attribute, o );

    }

    /**
     * 设置application中属性为attribute的对象
     * @param req
     * @param attribute 设置属性
     * @param o 设置对象
     * 2006-5-16 18:17:50
     */
    public void setAppObject( String attribute, Object o )
    {
        servlet.getServletContext().setAttribute( attribute, o );
    }

    public Object getSessionObject( HttpServletRequest req, String attribute )
    {
        Object obj = null;
        HttpSession session = req.getSession( false );
        if ( session != null ) obj = session.getAttribute( attribute );
        return obj;
    }

    public Object getAppObject( String attribute )
    {
        return servlet.getServletContext().getAttribute( attribute );
    }

    public void callParentGo( HttpServletResponse res, String msg, String url )
            throws IOException
    {
        HtmlUtil.callParentGo( res.getWriter(), msg, url );
    }

    public void callMeGo( HttpServletResponse res, String msg, String url )
            throws IOException
    {
        HtmlUtil.callMeGo( res.getWriter(), msg, url );
    }

    public void callBack( HttpServletResponse res, String msg )
            throws IOException
    {
        HtmlUtil.callBack( res.getWriter(), msg );
    }

    public void callMeConfirm( HttpServletResponse res, String msg, String ok,
            String no ) throws IOException
    {
        HtmlUtil.callMeConfirm( res.getWriter(), msg, ok, no );
    }
}
对于程序中的一些提示信息,我比较喜欢用JS来写,所以我把这些都放到了一个类中
import java.io.IOException;
import java.io.Writer;

public class HtmlUtil
{
    public static void callParentGo( Writer out, String msg, String url )

            throws IOException
    {
        out.write( " " );
    }

    public static void callMeGo( Writer out, String msg, String url )
            throws IOException
    {
        out.write( " " );
    }

    public static void callMeConfirm( Writer out, String msg ,String ok, String no )
            throws IOException
    {
        out.write( " " );
    }

    public static void callBack( Writer out, String msg ) throws IOException
    {
        out.write( " " );
    }
}


 
加上点ajax

你问我什么叫ajax,我也不太了解,我了解的是那支培养了无数荷兰足球精华的Ajax,谁知道怎么有人用几个单词的头字母也能凑出这个单词来,不过感觉用它来做东西,应该会挺有意思的
比如当用户在注册的时候,用户点一个按纽不用刷新界面就可以获得一句提示,是有这人还是没有这人啊?这次我尝试了用ajax技术来做一个三级要害的下拉列表,而这是我要讲的要害。
其实现在一般的ajax都是向Servlet发出请求,之后服务器响应,再偷摸的把结果传给它,之后显示出来,而换到Struts,有人会发甍,也一样,Action是Servlet,DispatchAction也是,只要把代码往这里写,让它往.do那里请求就行了。
在接下来我就向大家介绍我是怎样实现上述功能的
因为大学里面的结构是这里的
学院-专业-班级-学生
在学生注册的时候他是依靠于上述对象的,所以用户注册就需要一个三级的下拉选择
而ajax就能象变魔术一样,从服务器那里偷摸弄来您需要的列表
下面我先给大家展示一下第一个功能是怎么实现的吧?
当用户在注册的时候,点一个按纽,之后会弹出一个alert来告诉你这个用户是否有人用了,下面就让我们来看看这个功能是怎么实现的吧?


这里定义了按纽,用来测试老师是否已经存在了
大体的ajax的JS代码都上面这四部分,
先是创建XMLHttpRequest,
var xmlHttp;
function createXMLHttpRequest()
{
 if (window.XMLHttpRequest)
 {
  xmlHttp = new XMLHttpRequest();
 }
 else if (window.ActiveXObject)
 {
  xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
}
之后是客户响应部分的代码
function teacherCheck()
{
 var f = document.TeacherRegisterForm 从表单里读字段
 var user = f.user.value
 if(user=="")
 {
   window.alert("用户名不能为空!")
  f.user.focus()
   return false
   }
 else
 {
  createXMLHttpRequest()        这里都是精华了
  var url = "ajax.do?method=checkUserIsExist&user="+user   定义响应地址
  xmlHttp.open("GET",url, true)    发出响应
  xmlHttp.onreadystatechange = checkUser  把从服务器得到的响应再传给另个函数

  xmlHttp.send(null)
   }
}

function checkUser()
{
 if (xmlHttp.readyState == 4)
 {
  if (xmlHttp.status == 200)
  {
   alert(xmlHttp.responseText)        这里是对响应结果的操作,在这里我们是滩出对话框,并把服务器发来的信息显示出来
  }
 }
}

我把所有乱七八糟的操作都放到了一个DispatchAction里,所以它也不例外的在这个DA中了
public ActionForward checkUserIsExist( ActionMapping mapping,
            ActionForm form, HttpServletRequest req, HttpServletResponse res )
            throws Exception
    {
        Service service = getService();
        res.getWriter().write(service.checkUserIsExistForAjax( req.getParameter( "user" ) ) );
        return null;
    }
它仅仅是把业务逻辑部分的结果发送回去,而真正的判定是在业务逻辑那里实现的,
public String checkUserIsExistForAjax( String user )把结果弄成String的形式传回去
    {
        Connection connection = null;
        PreparedStatement pstmt1 = null;
        ResultSet rs = null;
        try
        {
            connection = getConnection();
            pstmt1 = connection
                    .prepareStatement( "select * from user where user=?" );
            pstmt1.setString( 1, user );
            rs = pstmt1.executeQuery();
            rs.last();
            if ( rs.getRow() > 0 )
            {
                return ID.M_EXIST; 用户存在
            }
        }
        catch ( Exception e )
        {
            e.printStackTrace();
        }
        finally
        {
            close( rs );
            close( pstmt1 );

            close( connection );
        }
        return ID.M_NOEXIST;用户不存在
    }


 
用ajax实现三级下拉列表

接着上次的话题,下面的就是学生注册时需要的学院,专业,班级,三层列表,
学院:

     
    

专业:

班级:


学院是上来就应该有的,我们把他放到了LabelValueBean里
public Vector getInstitutes()
    {
        Connection connection = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try
        {
            connection = getConnection();
            pstmt = connection.prepareStatement( "select * from institute" );
            rs = pstmt.executeQuery();
            Vector institutes = new Vector();
            institutes.add( new LabelValueBean( "请选择所在学院", "" ) );
            while ( rs.next() )
            {
                institutes.add( new LabelValueBean(
                        rs.getString( "institute" ), rs.getString( "id" ) ) );
            }
            return institutes;
        }
        catch ( Exception e )
        {
            e.printStackTrace();
        }
        finally
        {

            close( rs );
            close( pstmt );
            close( connection );
        }
        return null;
    }
而当它选择了一个学院后,相应的getDepartments(this.value)的js脚本就该工作了,还是四步
var xmlHttp;
function createXMLHttpRequest()
{
 if (window.XMLHttpRequest)
 {
  xmlHttp = new XMLHttpRequest();
 }
 else if (window.ActiveXObject)
 {
  xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
}
发出请求
function getDepartments(institute)
{
 createXMLHttpRequest()
 var url = "ajax.do?institute="+institute+"&method=getDepartments"
 xmlHttp.open("GET",url, true)
 xmlHttp.onreadystatechange = departments
 xmlHttp.send(null)
}
处理响应
function departments()
{
 if (xmlHttp.readyState == 4)
 {
  if (xmlHttp.status == 200)
  {
   resText = xmlHttp.responseText
   each = resText.split("")
   buildSelect( each, document.getElementById("departmentId"), "请选择所在专业");
  }
 }
}
function buildSelect(str,sel,label)
{
 sel.options.length=0;
 sel.options[sel.options.length]=new Option(label,"")
 for(var i=0;i {
  each=str[i].split(",")
  sel.options[sel.options.length]=new Option(each[0],each[1])
 }
}
我把从数据库中得到的各个专业进行了编码,之后再这里再回归回去,下面的是编码过程
public StringBuffer getDepartmentsByInstituteIdForAjax( Long instituteId )
    {
        Connection connection = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try
        {
            connection = getConnection();
            pstmt = connection
                    .prepareStatement( "select * from department where instituteID=?" );
            pstmt.setLong( 1, instituteId );
            rs = pstmt.executeQuery();
            StringBuffer sb = new StringBuffer();
            while ( rs.next() )
            {

                sb.append( rs.getString( "department" ) + ","
                        + rs.getLong( "id" ) );
                if ( !rs.isLast() ) sb.append( "" );
            }
            return sb;
        }
        catch ( Exception e )
        {
            e.printStackTrace();
        }
        finally
        {
            close( rs );
            close( pstmt );
            close( connection );
        }
        return null;
    }
当然这些都是由
public ActionForward getDepartments( ActionMapping mapping,
            ActionForm form, HttpServletRequest req, HttpServletResponse res )
            throws Exception
    {
        Service service = getService();
        res.getWriter().write(
                service.getDepartmentsByInstituteIdForAjax(
                        Long.parseLong( req.getParameter( "institute" ) ) )
                        .toString() );
        return null;
    }
来控制

===========班级的再这里
public ActionForward getClasses( ActionMapping mapping, ActionForm form,
            HttpServletRequest req, HttpServletResponse res ) throws Exception
    {
        Service service = getService();
        res.getWriter().write(
                service.getClassesByDepartmentIdForAjax(
                        Long.parseLong( req.getParameter( "department" ) ) )

                        .toString() );
        return null;
    }


public StringBuffer getClassesByDepartmentIdForAjax( Long departmentId )
    {
        Connection connection = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try
        {
            connection = getConnection();
            pstmt = connection
                    .prepareStatement( "select * from class where departmentID=?" );
            pstmt.setLong( 1, departmentId );
            rs = pstmt.executeQuery();
            StringBuffer sb = new StringBuffer();
            while ( rs.next() )
            {
                sb.append( rs.getString( "class" ) + "," + rs.getLong( "id" ) );
                if ( !rs.isLast() ) sb.append( "" );
            }
            return sb;
        }
        catch ( Exception e )
        {
            e.printStackTrace();
        }
        finally
        {
            close( rs );
            close( pstmt );
            close( connection );
        }
        return null;
    }

function getClasses(department)
{
 createXMLHttpRequest()
 var url = "ajax.do?department="+department+"&method=getClasses"
 xmlHttp.open("GET",url, true)
 xmlHttp.onreadystatechange = classes
 xmlHttp.send(null)

}

function classes()
{
 if (xmlHttp.readyState == 4)
 {
  if (xmlHttp.status == 200)
  {
   resText = xmlHttp.responseText
   each = resText.split("")
   buildSelect( each, document.getElementById("classid"), "请选择所在班级");
  }
 }
}


从分页体会MVC

大家都知道Struts是一种基于MVC的结构,而这个MVC又怎么样理解呢?书上阐述的一般都很具体,而我的理解很直白,我们可以把业务逻辑放到每个JSP页面中,当你访问一个JSP页面的时候,就可以看到业务逻辑得到的结果,而把这些业务逻辑与HTML代码夹杂到了一起,一定会造成一些不必要的麻烦,可以不可以不让我们的业务逻辑和那些HTML代码夹杂到一起呢?多少得搀杂一些,那干脆,尽量少的吧,于是我们可以尝试着把业务逻辑的运算过程放到一个Action里,我们访问这个Action,之后Action执行业务逻辑,最后把业务逻辑的结果放到request中,并将页面请求转发给一个用于显示结果的jsp页面,这样,这个页面就可以少去很多的业务逻辑,而只是单纯的去显示一些业务逻辑计算结果的页面而已。这时的Action称为控制器,JSP页可以叫做视图了,而控制器操作的业务对象,无非就应该叫模型了!

从上面的话,我们来分析一下当我们要做一个分页时所需要的部分,而在这之前,我们先看看他们的执行过程吧,首先我们第一次请求访问一个页面,它会把所有记录的前N条显示给我们,之后计算是否有下一页,等类似的信息,当我们点下一页的时候,就获取下一页的信息,我们还可以添加一个搜索,比如我们用于显示学生的,可以安学生姓名查找,学号查找,班级查找。而对于显示的对象,我们一般也都会封装为javabean,所以用于放置查询结果的容器是不定的,而这时,我们就需要用泛型来提升我们的代码效率!

首先我们写一个用于分页显示的javabean:

package com.boya.subject.model;

import java.util.Vector;

public class Page
{
    private int current = 1;        //当前页
    private int total = 0;         //总记录数
    private int pages = 0;    //总页数
    private int each = 5;         //每页显示
    private int start = 0;      //每页显示的开始记录数
    private int end = 0;       //每页显示的结束记录数
    private boolean next = false;        //是否有下一页
    private boolean previous = false;  //是否有上一页
    private Vector v = null;    //存放查询结果的容器

    public Page( Vector v ,int per)
    {
        this.v = v;
        each = per;
        total = v.size();   //容器的大小就是总的记录数
        if ( total % each == 0 )
            pages = total / each;       //计算总页数
        else
            pages = total / each + 1;
        if ( current >= pages )
        {
            next = false;

        }
        else
        {
            next = true;
        }
        if ( total < each )
        {
            start = 0;
            end = total;
        }
        else
        {
            start = 0;
            end = each;
        }
    }
   
    public int getCurrent()
    {
        return current;
    }

    public void setCurrent( int current )
    {
        this.current = current;
    }

    public int getEach()
    {
        return each;
    }

    public void setEach( int each )
    {
        this.each = each;
    }

    public boolean isNext()
    {
        return next;
    }

    public void setNext( boolean next )
    {
        this.next = next;
    }

    public boolean isPrevious()
    {
        return previous;
    }

    public void setPrevious( boolean previous )
    {
        this.previous = previous;
    }

    public int getEnd()
    {
        return end;
    }

    public int getPages()
    {
        return pages;
    }

    public int getStart()
    {
        return start;

    }

    public int getTotal()
    {
        return total;
    }

 //获取下一页的对象们  

public Vector getNextPage()
    {
        current = current + 1;
        if ( (current - 1) > 0 )
        {
            previous = true;
        }
        else
        {
            previous = false;
        }
        if ( current >= pages )
        {
            next = false;
        }
        else
        {
            next = true;
        }
        Vector os = gets();
        return os;
    }

 //获取上一页

    public Vector getPreviouspage()
    {
        current = current - 1;
        if ( current == 0 )
        {
            current = 1;
        }
        if ( current >= pages )
        {
            next = false;
        }
        else
        {
            next = true;
        }
        if ( (current - 1) > 0 )
        {
            previous = true;
        }
        else
        {
            previous = false;
        }
        Vector os = gets();

        return os;
    }

 //一开始获取的

    public Vector gets()
    {
        if ( current * each < total )
        {
            end = current * each;
            start = end - each;
        }
        else
        {
            end = total;
            start = each * (pages - 1);
        }
        Vector gets = new Vector();
        for ( int i = start; i < end; i++ )
        {
            E o = v.get( i );
            gets.add( o );
        }
        return gets;
    }
}



 而对于按不同搜索,我们需要一个FormBean,一般的搜索,都是模糊搜索,搜索个大概,而且输入的信息中文的比重也会很大,所以,我把对中文字符的转换放到了这个BEAN里,在进行select * from * where like这样的查询时,假如是like ''这样就可以得到所有的记录了,我便用这个来对付没有输入查询要害字的情况,而like '%*%'可以匹配要害字,而%%也在这里添加上了!

package com.boya.subject.view;

import java.io.UnsupportedEncodingException;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;

public class SearchForm extends ActionForm
{
    private static final long serialVersionUID = 1L;
    private String key;
    private String from;

    public String getFrom()
    {
        return from;
    }

    public void setFrom( String from )
    {
        this.from = from;
    }

      public void reset( ActionMapping mapping, HttpServletRequest req )
    {
        this.key = null;
    }

    public String getKey()
    {
        return key;
    }

    public void setKey( String key )

    {
        try
        {
            key = new String( key.getBytes( "iso-8859-1" ), "gb2312" );
        }
        catch ( UnsupportedEncodingException e )
        {
            e.printStackTrace();
        }
        this.key = "%" + key + "%";
    }
   
    public String getAny(){
        return "%%";
    }
}
前期都做好了,我现在就要开始访问这个Action了,可是这个控制器还没写呢!这里是代码

public class AdminUserAction extends AdminAction
{
    private Vector ss; //用来装结果的容器
    private Page ps; //分页显示的PAGE对象

    protected ActionForward executeAction( ActionMapping mapping,
            ActionForm form, HttpServletRequest req, HttpServletResponse res )
            throws Exception
    {
        if ( !isSupper( req ) )
        {
            return notSupper( res );//假如不是超级治理员怎么办?
        }
        Service service = getService();//获取业务逻辑
        SearchForm sf = (SearchForm) form;//获取搜索FORM
        String op = req.getParameter( "op" );//获取用户对页面的操作
        String search = req.getParameter( "search" );//是否执行了搜索
        Vector temp = null; //用于存放临时反馈给用户的结果容器
                if ( op == null )//假如用户没有执行上/下一页的操作
                {
                    if ( search != null )//用户假如执行了搜索
                    {
                        if ( sf.getFrom().equalsIgnoreCase( "class" ) )//假如是按班级查找
                        {

                            ss = service.getAllStudentBySchoolClassForAdmin( sf
                                    .getKey() );//获取from的要害字
                        }
                        else if ( sf.getFrom().equalsIgnoreCase( "name" ) )//假如是按姓名查找
                        {
                            ss = service.getAllStudentByNameForAdmin( sf
                                    .getKey() );
                        }
                        else if ( sf.getFrom().equalsIgnoreCase( "user" ) )//假如是按用户名查找
                        {
                            ss = service.getAllStudentByUserForAdmin( sf
                                    .getKey() );
                        }
                        else
                        {
                            ss = service.getAllStudentBySnForAdmin( sf.getKey() );//按学号查找
                        }

                        form.reset( mapping, req );//重置搜索表单
                    }
                    else
                    {
                        ss = service.getAllStudentForAdmin( sf.getAny() ); //用户未执行查找就显示全部,
                    }
                    if ( ss != null && ss.size() != 0 )//假如查找不为空,有记录,那就创建一个分页对象
                    {
                        ps = new Page( ss, 10 );//将查询结果和每页显示记录数作为参数构件对象
                        temp = ps.gets();//并获取第一页
                    }
                }
                else//假如用户执行了操作
                {
                    if ( op.equals( "next" ) )//操作是下一页
                    {
                        temp = ps.getNextPage();
                    }
                    if ( op.equals( "previous" ) )//操作是上一页
                    {
                        temp = ps.getPreviouspage();
                    }

                }
                req.setAttribute( "search", SelectUtil.studentSearch() );//把搜索用到的表单放到request中
                req.setAttribute( "students", temp );//该页显示的学生
                req.setAttribute( "page", ps );//分页对象
                return mapping.findForward( "student" );//请求转发
    }
}


用到SelectUtil中的代码如下:
/**
     * 获取学生查找类别的select
     * @return 学生查找类别
     * 2006-5-17 9:06:12
     */
    public static Vector studentSearch()
    {
        Vector s = new Vector();
        s.add( new LabelValueBean( "按学号查找", "sn" ) );
        s.add( new LabelValueBean( "按班级查找", "class" ) );
        s.add( new LabelValueBean( "按姓名查找", "name" ) );
        s.add( new LabelValueBean( "按用户查找", "user" ) );
        return s;
    }
在看页面视图前先让我们看看Model吧,

public class Student extends User
{
    private String sn;
    private SchoolClass schoolClass; //这里的班级做为了一种对象,我们在视图显示的时候就有了一层嵌套

    public SchoolClass getSchoolClass()
    {
        return schoolClass;
    }

    public void setSchoolClass( SchoolClass schoolClass )
    {
        this.schoolClass = schoolClass;
    }

    public String getSn()
    {
        return sn;
    }

    public void setSn( String sn )
    {
        this.sn = sn;
    }

    public String getType()
    {
        return "student";
    }
}
在了解了model后,还是看看视图吧,


先放个查询表单:















由于模型中有嵌套,那么我们就将用到Nested标签,其实没有嵌套也可以使用这个标签,下面的是用于显示信息的,用迭迨器进行遍历request范围的students,你不安排范围,他会自动找到的,并把每次遍历的对象起名叫student,并作为层次的根元素,





//寻找了student的schoolClass属性对象的schoolClass嵌套

      //student的名字

删除



这里是显示分页对象的:



        //上一页是否存在
        
               
                上一页
               
   
       

        上一页   
        
       //下一页是否存在
         
         
          下一页
         
   

        下一页   
        

共有条数据



到这里不知道您看明白了多少,在我的这个JSP页里几乎没有任何的业务逻辑,这样的设计就比把HTML和JAVA搀杂在一起好了很多。


 

阻止非法的登陆方式

假如用户直接输入了地址,不也可以直接访问吗?理论上是,我们可以加入session进行跟踪,以杜绝此类型事件发生,我们是不是要把每次对session的判定依次拷到每个页里呢,之后下次需要验证的SESSION换了,我们再换?太浪费了,我的做法是做了一个自定义标签,来解决这个问题。


import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

public class CheckTag extends TagSupport
{
    private static final long serialVersionUID = 879137944441282895L;
    private String check = "";//用来验证的变量
    private String url = "index.jsp";//出现错误要去的页面
    private String msg = "";//错误的提示
    private String scope = "";//要严整变量的范围
    private String to = "go"; //假如验证失败,是将页面后退,还是定位到哪里?

    public String getTo()
    {
        return to;
    }

    public void setTo( String to )
    {
        this.to = to;
    }

    public String getMsg()
    {
        return msg;
    }

    public void setMsg( String msg )
    {
        this.msg = msg;
    }

    public String getScope()
    {
        return scope;
    }

    public void setScope( String scope )
    {
        this.scope = scope;
    }

    public String getCheck()
    {
        return check;
    }

    public void setCheck( String check )
    {
        this.check = check;
    }

    public String getUrl()
    {
        return url;
    }

    public void setUrl( String url )
    {
        this.url = url;
    }

    public int doStsrtTag() throws JspException
    {
        return SKIP_BODY;
    }

    public int doEndTag() throws JspException
    {
        boolean valid = false;//先设为不可用
        if ( scope.equalsIgnoreCase( "request" ) )//假如要检查request范围
        {

            valid = CheckUtil.checkRequestAttribute( pageContext.getRequest(),
                    check );
        }
        else if ( scope.equalsIgnoreCase( "session" ) )
        {
            valid = CheckUtil.checkSession( pageContext.getSession(), check );
        }
        else if ( scope.equalsIgnoreCase( "parameter" ) )
        {
            valid = CheckUtil.checkParameter( pageContext.getRequest(), check );
        }
        else if ( scope.equalsIgnoreCase( "application" ) )
        {
            valid = CheckUtil.checkApp( pageContext.getServletContext(), check );
        }
        if ( valid ) return EVAL_PAGE;//假如可用就继续执行此页的其余部分
        else
        {//否则,哈哈
            try
            {
                if ( to.equalsIgnoreCase( "go" ) ) //现在失败了,就看怎么回到你该到的地方
                    HtmlUtil.callParentGo(
                        pageContext.getOut(), msg, url );//将浏览器定位到URL 
                else
                    HtmlUtil.callBack( pageContext.getOut(), msg );//后退一下页面来阻止
                return SKIP_PAGE;//跳过页面的其余部分,不执行
            }
            catch ( Exception e )
            {
                throw new JspException( e.toString() );

            }
        }
    }

    public void release()
    {
        super.release();
        check = "";
        url = "";
        msg = "";
        scope = "";
    }
}


下面是用到的htmlUtil部分:

public static void callParentGo( Writer out, String msg, String url )
            throws IOException
    {
        out.write( " " );
    }
public static void callBack( Writer out, String msg ) throws IOException
    {
        out.write( " " );
    }


写个check.tld部署吧,



 1.0
 1.1
 
  check
  com.boya.subject.util.CheckTag
  
   check
   true
  
  
   url
   false
  
  
   msg
   true
  
  
   scope
   true
  
  
   to
   false
  
 




你 只要在每个页面里写下这个就可以判定用户是否登陆了

<%@ taglib prefix="boya" uri="/WEB-INF/check.tld" %>


假如没有登陆那么,会自动提示到首页登陆,不错,很完美吧?


上一篇:JavaBean与Java的Class的关系 人气:1282
下一篇:用Java事件处理机制实现录制回放功能 人气:714
浏览全部Java的内容 Dreamweaver插件下载 网页广告代码 祝你圣诞节快乐 2009年新年快乐