Jsp/Java代码分离.实现页面真正的代码分离 实现框架代码:BasePage,TextBox,BasePageFilter

BasePage代码如下

package  JXDO.WebUI;

import  java.io. * ;
import  javax.servlet. * ;
import  javax.servlet.http. * ;
import  javax.servlet.jsp. * ;
import  java.lang.reflect. * ;

public   class  BasePage
{
    
protected PageContext pageContext;
    
protected HttpServletRequest request;
    
protected HttpServletResponse response;
    
protected HttpSession session;
    
protected ServletContext application;
    
protected ServletConfig config;
    
protected JspWriter out;

    
public BasePage(){}
    
    
    
final void writeContextToBasePage(PageContext pageContext) throws Exception
    
{
        
this.pageContext = pageContext;
        
this.request = (HttpServletRequest)(this.pageContext.getRequest());
        
this.response = (HttpServletResponse)(this.pageContext.getResponse());
        
this.session = this.pageContext.getSession();
        
this.application = this.pageContext.getServletContext();
        
this.config = this.pageContext.getServletConfig();
        
this.out = this.pageContext.getOut();
    
        
//注意:此处非真正的isPostBack=true,只是判断如果是POST方法,而设置,所以必须注意FORM的METHOD为POST
        String sRequestMethod = this.request.getMethod();
        
if(sRequestMethod!=null && sRequestMethod.compareToIgnoreCase("POST")==0)this.isPostBack = true;
        
        
//现实过程的调用
        this.handlerProcess();
        
    }

    
    
protected boolean isPostBack = false;
    
    
protected void Page_Load()throws Exception{}
    
    
protected void Page_Unload()throws Exception{}
    
    
synchronized void doInit()throws Exception
    
{
        
//得到后台代码中定义的标签库,对应ASPX中的控件
        Field[] fldAry = this.getClass().getDeclaredFields();
        
for(Field fld : fldAry)
        
{            
            
if(fld.getType().getSuperclass()!= javax.servlet.jsp.tagext.TagSupport.class)
            
{
                
continue;
            }

            
            fld.setAccessible(
true);
            Object obj 
= fld.getType().newInstance();    //变量的类型就是标签库中的标签,比如:TextBox
            String tagLibName = fld.getName();            //变量名,就是标签 ID
            
            
//如果存在值,则Filter已经将值放入对应的Atribute中了
            Object objPostVal = this.request.getAttribute(tagLibName);
            
if(objPostVal != null)
            
{                
                
try
                
{
                    
//回调以后给标签赋值,[setPostValue]方法为以后其他标签考虑,统一方法名,可以采用反射进行赋值
                    Method m = obj.getClass().getDeclaredMethod("setPostValue",new Class[]{String.class});
                    m.invoke(obj, objPostVal.toString());
                }
catch(Exception ex){}
            }

            fld.set(
this, obj);
            
            
//添加到属性中,在对应的标签中将根据名称进行输出值[没有采用ViwState方式]
            this.pageContext.setAttribute("jxdo.webui.ocxs." + tagLibName, obj);
            fld.setAccessible(
false);
        }

    }

    
    
synchronized void doRelease()throws Exception
    
{
        
//后台的代码运行完毕,则将后台代码中的标签释放
        Field[] fldAry = this.getClass().getDeclaredFields();
        
for(Field fld : fldAry)
        
{            
            
if(fld.getType().getSuperclass()!= javax.servlet.jsp.tagext.TagSupport.class)
            
{
                
continue;
            }

            fld.setAccessible(
true);
            Object tagLibObj 
= fld.get(this);
            
if(tagLibObj != null)
            
{
                Method mRrelease 
= tagLibObj.getClass().getMethod("release"null);
                mRrelease.invoke(tagLibObj, 
null);
            }

            fld.setAccessible(
false);
        }

    }

    
    
final synchronized void handlerProcess()throws Exception
    
{        
        
this.doInit();        //实例化标签库
        this.Page_Load();    //继承类覆盖
        this.invokeEventHandler();
        
this.Page_Unload();    //继承类覆盖
        this.doRelease();    //释放标签库
    }
    
    
    
final void invokeEventHandler()throws Exception
    
{
        String sSenderName
= this.request.getParameter("__JXDO__EVENTTARGET");
        
if(sSenderName==null)return;
        
else if(sSenderName.length()==0)return;
        
        String sSenderEvent
= this.request.getParameter("__JXDO__EVENTARGUMENT");
        
if(sSenderEvent==null)return;
        
else if(sSenderEvent.length()==0)return;
        
        
//查找客户端提交事件触发数据,然后反射调用
        
//客户端的提交[οnclick="__doPostBack(this.name,'onclick');"]
        
//可以将按钮写成标签,直接对应标签中的事件,而现在后台代码没有引入真正的标签事件
        Method method = this.getClass().getMethod(sSenderName + "_" + sSenderEvent, null);
        method.invoke(
thisnull);
    }


}


解释:
writeContextToBasePage方法,在标签<jxui:page>的doStartTag中被调用,就进入整个后台绑定代码的执行了
该方法中先设置WEB的一些必要参数项,然后判断是否为提交,设置isPostBack的值

doInit方法
通过反射得到后台的绑定代码中,定义的标签库,然后实例化该标签
如果是提交的数据,则通过Filter,已经对应标签名称的属性中 this.request.getAttribute(tagLibName)

invokeEventHandler方法
得到客户端提交的数据,根据两个HIDDEN域的值,构造出后台代码中的方法名称,然后反射调用

doRelease方法
对于在doInit方法中被实例化后的标签,进行释放

注意:后台代码中申明的标签,在实例化后,被添加到pageContext的Attribute中,当后台程序运行完成,后台程序中的标签被释放,在pageContext中的标签不会释放
而定义的TEXTBOX,标签在 doStartTag时,必须判断, 对应的标签是否存在,如果存在则取值并输出,然后释放该pageContext中的标签
TextBox标签代码如下

package  JXDO.WebUI;

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

public   class  TextBox  extends  TagSupport
{
    
//public TextBox(){super();}
    
    
private String text;
    
public String getText(){return this.text;}
    
public void setText(String text){this.text = text;}
    
    
protected void setPostValue(String sPostValue)
    
{
        
this.text = sPostValue;
    }

    
    
public int doStartTag() throws JspException
    
{
        
try
        
{
            Object me 
= this.pageContext.getAttribute("jxdo.webui.ocxs." + this.id);
            
if(me!=null)
            
{
                TextBox tBox 
= (TextBox)me;
                
this.text = tBox.getText();
                tBox.release();
                
this.pageContext.removeAttribute("jxdo.webui.ocxs." + this.id);
            }

            
this.pageContext.getOut().println("<input type="text" name=""+this.id+"" value=""+this.text+"">");
        }

        
catch(Exception ex){}
        
return EVAL_BODY_INCLUDE;
    }

    
    
public int doEndTag() throws JspException
    
{        
        
return EVAL_PAGE;
    }

}


过滤器没啥花头,就是分析数据将其添加到request的Attribute中
BasePageFilter过滤器代码如下

package  JXDO.WebUI;

import  java.io.IOException;
import  java.util.Enumeration;

import  javax.servlet. * ;
import  javax.servlet.http. * ;

public   class  BasePageFilter  implements  Filter
{
    
private FilterConfig fconfig = null;
    
public void init(FilterConfig fconfig)throws ServletException
    
{
        
this.fconfig = fconfig;
    }

    
    
public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)throws IOException,ServletException
    
{
        HttpServletRequest req 
= (HttpServletRequest)request;
        String type 
= req.getHeader("Content-Type");
        
        Enumeration  paramNames 
= request.getParameterNames();
        
while(paramNames.hasMoreElements())
        
{              
            String paramName 
= (String)paramNames.nextElement();
            String paramVale 
= request.getParameter(paramName);
            request.setAttribute(paramName,paramVale);
        }

        
        chain.doFilter(request, response);

    }

    
    
public void destroy()
    
{
        
this.fconfig = null;
    }

}


整个框架就算完成,配置对应的WEB.XML就可以协同工作了

开始我们的配置与测试程序

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值