第五部分 包拆解 4)org.directwebremoting.create包

在dwr.xml中有,<creator>标签负责公开用于Web远程的类和类的方法,实际上最后调用的就是本包下面的script创建类。
creator类型在1.1版本的时候有如下几种,现在是3.0版本了,我查了下源码,种类好像比下面要多(查XXXCreator有多少个)。
new: 用Java的new关键字创造对象。
none: 它不创建对象,看下面的原因。 (v1.1+)
scripted: 通过BSF使用脚本语言创建对象,例如BeanShell或Groovy。
spring: 通过Spring框架访问Bean。
jsf: 使用JSF的Bean。 (v1.1+)
struts: 使用Struts的FormBean。 (v1.1+)
pageflow: 访问Beehive或Weblogic的PageFlow。 (v1.1+)

creator是在什么时候调用的呢?
实际上,在Serlvet加载的时候有个doPost方法,doPost方法调用handle,handle再调用 remotor,remotor最终调用相应的creator,比如NewCreator,creator实际上是执行创建script字符串的工作。
举例来说,我们想在html中某个地方直接显示当前时间的long值,那么我们就可以调用java.util.Date类的getTime()方法。dwr.xml中写法如下:

< dwr >
< allow >
< createcreator = " new " javascript = " JDate " >
< paramname = " class " value = " java.util.Date " />
</ create >
< createcreator = " new " javascript = " Demo " >
< paramname = " class " value = " your.java.Bean " />
</ create >
</ allow >
</ dwr >

我们知道这样所有的/dwr/*所有请求都由这个servlet来处理,那么实际上,浏览器加载
<script type='text/javascript' src='dwr/interface/JDate.js'></script>时,实际上是在触发servlet,这次触发属于系统 触发,不做事的,只有执行javascript调用方法时如:

function getServerDateTime() {
JDate.getTime(handleGetTime);
}

function handleGetTime(dateTime) {
DWRUtil.setValue(
"date",dateTime);
}


才会触发下面

protected void doGet(HttpServletRequestreq,HttpServletResponseresp) throws IOException,ServletException
{
doPost(req,resp);
}


doGet会调用到doPost

protected void doPost(HttpServletRequestrequest,HttpServletResponseresponse) throws IOException,ServletException
{
try
{
webContextBuilder.set(request,response,getServletConfig(),getServletContext(),container);

UrlProcessorprocessor
=container.getBean(UrlProcessor.class);
processor.handle(request,response);
}

finally
{
webContextBuilder.unset();
}

}

在proccessor中我们看到如下代码

public void handle(HttpServletRequestrequest,HttpServletResponseresponse) throws IOException
{
try
{
StringpathInfo
=request.getPathInfo();
contextPath
=request.getContextPath();

if(pathInfo==null||pathInfo.length()==0||"/".equals(pathInfo))
{
response.sendRedirect(contextPath
+request.getServletPath()+indexHandlerUrl);
}

else
{
//LoopthroughalltheknownURLs
for(Entry<String,Object>entry:urlMapping.entrySet())
{
Stringurl
=entry.getKey();

//IfthisURLmatches,callthehandler
if(pathInfo.startsWith(url))
{
Handlerhandler
=(Handler)entry.getValue();
handler.handle(request,response);
return;
}

}


notFoundHandler.handle(request,response);
}

}

catch(Exceptionex)
{
exceptionHandler.setException(ex);
exceptionHandler.handle(request,response);
}

}

这些handle有多种
1,
/**
* A Handler that supports requests for auth.js
*/
public class AuthHandler extends JavaScriptHandler
2,
/**
* A Handler that supports requests for engine.js
* @author Joe Walker [joe at getahead dot ltd dot uk]
*/
public class EngineHandler extends JavaScriptHandler
3,
/**
* A Handler that supports requests for util.js
* @author Joe Walker [joe at getahead dot ltd dot uk]
*/
public class GiHandler extends JavaScriptHandler
4,
/**
* A handler for interface generation requests
* @author Joe Walker [joe at getahead dot ltd dot uk]
*/
public class InterfaceHandler extends JavaScriptHandler
上面三种都是系统范围的handle,对于我们自己编写的类,应该是触发InterfaceHandler 。

我们再看如下关系
public abstract class CachingFileHandler implements Handler
public abstract class TemplateHandler extends CachingFileHandler
public abstract class JavaScriptHandler extends TemplateHandler
public class InterfaceHandler extends JavaScriptHandler
逐级往上继承

InterfaceHandler,我们看到如下代码,执行顺序-4,里面调用了远程remoter

protected StringgenerateTemplate(HttpServletRequestrequest,HttpServletResponseresponse) throws IOException
{
StringscriptName
=request.getPathInfo();
scriptName
=scriptName.replace(interfaceHandlerUrl,"");

StringcontextServletPath
=request.getContextPath()+request.getServletPath();

if(scriptName.endsWith(PathConstants.EXTENSION_JS))
{
scriptName
=scriptName.replace(PathConstants.EXTENSION_JS,"");
if(!LocalUtil.isJavaIdentifier(scriptName))
{
log.debug(
"Throwingatrequestforscriptwithname:'"+scriptName+"'");
thrownewSecurityException("ScriptnamesmayonlycontainJavaIdentifiers");
}


returnremoter.generateInterfaceScript(scriptName,contextServletPath);
}

elseif(scriptName.endsWith(PathConstants.EXTENSION_SDOC))
{
scriptName
=scriptName.replace(PathConstants.EXTENSION_SDOC,"");
if(!LocalUtil.isJavaIdentifier(scriptName))
{
log.debug(
"Throwingatrequestforscriptwithname:'"+scriptName+"'");
thrownewSecurityException("ScriptnamesmayonlycontainJavaIdentifiers");
}


returnremoter.generateInterfaceSDoc(scriptName,contextServletPath);
}

else
{
log.debug(
"Throwingatrequestforscriptwithunknownextension:'"+scriptName+"'");
thrownewSecurityException("Unknownextension");
}

}

类JavaScriptHandler代码如下,调用了父类TemplateHandler的generateCachableContent方法执行顺序-2

protected StringgenerateCachableContent(HttpServletRequestrequest,HttpServletResponseresponse) throws IOException
{
Stringoutput
=super.generateCachableContent(request,response);

if(debug||compressor==null)
{
returnoutput;
}


try
{
returncompressor.compressJavaScript(output);
}

catch(Exceptionex)
{
log.warn(
"Compressionsystem("+compressor.getClass().getSimpleName()+")failedtocompressscript",ex);
returnoutput;
}

}


TemplateHandler类代码如下执行顺序-3,里面调用了generateTemplate方法

protected StringgenerateCachableContent(HttpServletRequestrequest,HttpServletResponseresponse) throws IOException
{
Stringtemplate
=generateTemplate(request,response);

Map
<String,String>replace=getSearchReplacePairs();
if(replace!=null)
{
for(Map.Entry<String,String>entry:replace.entrySet())
{
Stringsearch
=entry.getKey();
if(template.contains(search))
{
template
=template.replace(search,entry.getValue());
}

}

}


returntemplate;
}


/***/ /**
*Generateatemplatetoundergosearchandreplaceprocessingaccordingto
*thesearchandreplacepairsfrom{
@link#getSearchReplacePairs()}.
*
@paramrequestTheHTTPrequestdata
*
@paramresponseWherewewritetheHTTPresponsedata
*
@returnAtemplatestringcontaining${}sectionstobereplaced
*/

protected abstract StringgenerateTemplate(HttpServletRequestrequest,HttpServletResponseresponse) throws IOException;


CachingFileHandler类代码如下,handle方法里面调用了generateCachableContent()方法
执行顺序-1

public void handle(HttpServletRequestrequest,HttpServletResponseresponse) throws IOException
{
if(isUpToDate(request))
{
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
return;
}


Stringoutput;

synchronized(scriptCache)
{
Stringurl
=request.getPathInfo();
output
=scriptCache.get(url);
if(output==null)
{
output
=generateCachableContent(request,response);
}

scriptCache.put(url,output);
}


response.setContentType(mimeType);
response.setDateHeader(HttpConstants.HEADER_LAST_MODIFIED,CONTAINER_START_TIME);
response.setHeader(HttpConstants.HEADER_ETAG,ETAG);

PrintWriterout
=response.getWriter();
out.println(output);
}

代码有点绕
我们看到在InterfaceHandler类中
有一行代码如下:
remoter.generateInterfaceScript(scriptName, contextServletPath);
如果按例子,对于声明在dwr.xml中的JDate类,scriptName应该是JDate,contextServletPath应该是'dwr/interface/'

执行generateInterfaceScript方法生成相应的字符串,对应于JDate.js
在CachingFileHandler类中的方法handle最后一行如下,
out.println(output);
在这个地方,将返回内容输出到客户端。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值