Dwr
通过用户配置文件
dwr.xml
将
java
类映射成一个
javascript
对象,从实现手法上看与
java
里的数据映射很相似。而
dwr
是将
JAVA
的对象映射到了
js
里,由客户端的
JS
提供给用户各类实现,而
java
代码完全在后台运行。
DWR 函数调用里涉及到的 JS 代码: engine.js
DWR 函数调用里涉及到的类有: AbstractDWRServlet 、 DefaultProcessor <o:p></o:p>
用户在提交 request 以后的操作步骤请参见我 blog 里的:《 dwr 源码学习(一)》, JAVA 代码生成的映射 JS 代码其实只是一个 javascript 接口,它调用了 DWREngine._execute 这个函数,而这个函数大体只是执行了一些解析的工作,在它结尾处调用了 DWREngine.endBatch() ,然后又执行了 DWREngine._sendData(batch) ,这时我们会发现有这样一句: “ batch.req.open("GET", batch.path + "/exec/" + statsInfo + "?" + query, batch.async); ”很熟悉吧。 <o:p></o:p>
下一步就到了真正的实现 js 调用 java 代码里方法的时候了,兴奋吧。其实实现也是很简单的。通过 servlet 这里实现了对各类型 request 参数的不同的匹配,还是看 AbstractDWRServlet .getPost() 这个方法:
1
protected
void
doPost(HttpServletRequest req, HttpServletResponse resp)
throws
IOException, ServletException
2
{
3
try
4
{
5
builder.set(req, resp, getServletConfig(), getServletContext(), container);
6
ServletLoggingOutput.setExecutionContext(
this
);
7
8
processor.handle(req, resp);
9
}
10
finally
11
{
12
builder.unset();
13
ServletLoggingOutput.unsetExecutionContext();
14
}
15
}
16
注意processor.handle(req, resp);
17
public
void
handle(HttpServletRequest req, HttpServletResponse resp)
throws
IOException, ServletException
18
{
19
String pathInfo
=
req.getPathInfo();
20
String servletPath
=
req.getServletPath();
21
22
if
(nullPathInfoWorkaround
&&
pathInfo
==
null
)
23
{
24
pathInfo
=
req.getServletPath();
25
servletPath
=
HtmlConstants.PATH_ROOT;
26
log.debug(
"
Default servlet suspected. pathInfo=
"
+
pathInfo
+
"
; contextPath=
"
+
req.getContextPath()
+
"
; servletPath=
"
+
servletPath);
//
$NON-NLS-1$
//
$NON-NLS-2$
//
$NON-NLS-3$
27
}
28
29
if
(pathInfo
==
null
||
30
pathInfo.length()
==
0
||
31
pathInfo.equals(HtmlConstants.PATH_ROOT))
32
{
33
resp.sendRedirect(req.getContextPath()
+
servletPath
+
HtmlConstants.FILE_INDEX);
34
}
35
else
if
(pathInfo.startsWith(HtmlConstants.FILE_INDEX))
36
{
37
index.handle(req, resp);
38
}
39
else
if
(pathInfo.startsWith(HtmlConstants.PATH_TEST))
40
{
41
test.handle(req, resp);
42
}
43
else
if
(pathInfo.startsWith(HtmlConstants.PATH_INTERFACE))
44
{
45
iface.handle(req, resp);
46
}
47
else
if
(pathInfo.startsWith(HtmlConstants.PATH_EXEC))
48
{
49
exec.handle(req, resp);
50
}
51
else
if
(pathInfo.equalsIgnoreCase(HtmlConstants.FILE_ENGINE))
52
{
53
file.doFile(req, resp, HtmlConstants.FILE_ENGINE, HtmlConstants.MIME_JS);
54
}
55
else
if
(pathInfo.equalsIgnoreCase(HtmlConstants.FILE_UTIL))
56
{
57
file.doFile(req, resp, HtmlConstants.FILE_UTIL, HtmlConstants.MIME_JS);
58
}
59
else
if
(pathInfo.equalsIgnoreCase(HtmlConstants.FILE_DEPRECATED))
60
{
61
file.doFile(req, resp, HtmlConstants.FILE_DEPRECATED, HtmlConstants.MIME_JS);
62
}
63
else
64
{
65
log.warn(
"
Page not found (
"
+
pathInfo
+
"
). In debug/test mode try viewing /[WEB-APP]/dwr/
"
);
//
$NON-NLS-1$
//
$NON-NLS-2$
66
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
67
}
68
}
69
也就只有这几种类型的请求,还记得 DWREngine._sendData 吗?里面有这么一句:“ batch.req.open("GET", batch.path + "/exec/" + statsInfo + "?" + query, batch.async); ”看到他的请求路径是 exec ,对应在 processor.handle(req, resp); 这个方法里就是 exec ,在刚才的 JAVA 代码里我们已经看到过了是括号内的代码( else if (pathInfo.startsWith(HtmlConstants. PATH_EXEC )) ),而 exec 早已在 servlet 初始化的时候就已经设置为 DefaultExecProcessor ,它的函数 hadle() 就是具体对 js 调用 java 类方法的实现了。 <o:p></o:p>
DWR
是一个小型的
AJAX
框架,它的实现思路简单,其实有很多人在开发中一定也有过类似的想法。它之所以现在才出现我想大概还是要归功于异步
javascript
消息发送这样的技术成为现实。所以我又想
AJAX
,从技术上说只能是
javascript
有了一个飞跃性的进步,而
AJAX
的最终成功却要靠软件工程。