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;
//查找客户端提交事件触发数据,然后反射调用
//客户端的提交[onclick="__doPostBack(this.name,'onclick');"]
//可以将按钮写成标签,直接对应标签中的事件,而现在后台代码没有引入真正的标签事件
Method method = this.getClass().getMethod(sSenderName + "_" + sSenderEvent, null);
method.invoke(this, null);
}
}
解释:
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就可以协同工作了
开始我们的配置与测试程序