后续:
1. 拦截器 uk.ltd.getahead.dwr.DWRServlet
该类拦截所有指向dwr目录下的请求,并调用Processor的handler方法进行处理,在uk.ltd.getahead.dwr.impl.DefaultProcessor下,我们可以看到详细的处理过程。
if (pathInfo.length() == 0 ||pathInfo.equals(HtmlConstants.PATH_ROOT) ||
pathInfo.equals(req.getContextPath())) {
resp.sendRedirect(req.getContextPath() + servletPath + HtmlConstants.FILE_INDEX);
} else if (pathInfo.startsWith(HtmlConstants.FILE_INDEX)) {
index.handle(req, resp);
} else if (pathInfo.startsWith(HtmlConstants.PATH_TEST)) {
test.handle(req, resp);
} else if (pathInfo.startsWith(HtmlConstants.PATH_INTERFACE)){
iface.handle(req, resp);
}else if (pathInfo.startsWith(HtmlConstants.PATH_EXEC)){
exec.handle(req, resp);
} else if (pathInfo.equalsIgnoreCase(HtmlConstants.FILE_ENGINE)) {
file.doFile(req, resp, HtmlConstants.FILE_ENGINE, HtmlConstants.MIME_JS);
}else if (pathInfo.equalsIgnoreCase(HtmlConstants.FILE_UTIL)){
file.doFile(req, resp, HtmlConstants.FILE_UTIL, HtmlConstants.MIME_JS);
} else if (pathInfo.equalsIgnoreCase(HtmlConstants.FILE_DEPRECATED)) {
file.doFile(req, resp, HtmlConstants.FILE_DEPRECATED, HtmlConstants.MIME_JS);
} Else {
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
}
通过判断request请求的servlet路径,进行处理,大家可以自己去参看,这里不详细讨论。
2. bean转换器,<convert converter="bean" match="test.User"/>
将dwr.jar解压缩,在路径ukltdgetaheaddwr下可以看到dwr.xml,这里配置了系统默认的一些转换器,
<converter id="bean" class="uk.ltd.getahead.dwr.convert.BeanConverter"/>即是刚才用到User类的转换器,进入代码我们来看看它是如何在javascript和java间进行转换的。打开BeanConverter代码,定位到函数
public Object convertInbound(Class paramType, InboundVariable iv, InboundContext inctx)
throws ConversionException
即是将javascript对象转换成java对象的,其中paramType即Class类型,在上面的例子中是test.User,InboundVariable iv,是传入的值,通过iv.getValue可以得到传入的javascript值串InboundContext inctx,是入口参数上下文,用于保存转换的后java对象。因为前台传入的是一个javascript的map类型,而map肯定是以{开始和以}结束的,于是在这个函数一开始进行了判断
if (!value.startsWith(ConversionConstants.INBOUND_MAP_START)) {
throw new IllegalArgumentException(
Messages.getString("BeanConverter.MissingOpener", ConversionConstants.INBOUND_MAP_START));
}
if (!value.endsWith(ConversionConstants.INBOUND_MAP_END)) {
throw new IllegalArgumentException(Messages.getString("BeanConverter.MissingCloser", ConversionConstants.INBOUND_MAP_START)); //$NON-NLS-1$
}
javascript中,map里各个项是用逗号连接的,如var userMap = {id:'admin',password:'123456',name:'chenbug',email:'chenbug@zj.com'};而每个项的键值对是用冒号连接的,
在convertInbound函数的接下来的处理中,即是通过分析map字串,通过paramType构造java实例(即User类),然后通过反射,将这些键值对设置到java实例中,并返回。
这样就完成了javascript到java的转换。
另一个函数
public String convertOutbound(Object data, String varname, OutboundContext outctx) throws ConversionException
即是将java对象转换为javascript对象(其实是声明和赋值语句)。
Object data ,是待转换的java对象
String varname,是javascript中的该对象的变量名
OutboundContext outctx,传出参数上下文,用于保存转换后的javascript值
StringBuffer buffer = new StringBuffer();
buffer.append("var "); //$NON-NLS-1$
buffer.append(varname);
buffer.append("={};"); //$NON-NLS-1$
这里声明了map类型的变量。
即下来来的代码即是通过反射进行变量赋值,如下
buffer.append(varname);
buffer.append('.');
buffer.append(name);
buffer.append('=');
buffer.append(nested.getAssignCode());
buffer.append(';');
大家可以自己去参看更多的代码。
3.dwr本身提供了一个测试环境,大家在配置完后,可以在IE中输入地址http://localhost/testApp/dwr/index.html,看到配置的各DWR组件,并进行相关测试。