`

如何缓存DWR生成的JS文件

阅读更多

DWR provides a convenient mechanism to execute server side java classes from javascript running in the browser. We use it extensively while developing Dekoh applications. Recently I noticed that when we use DWR, there are many requests to java-script files from the browser. It appeared that some DWR scripts are not being cached by the browser. I fired up  firefox live http headers   and noticed that inded some scripts were being downloaded with every page. We use DWR version 1.1.4. The headers for the repeat downloads looked like:

GET /dekohportal/dwr/interface/locationchooser.js HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en,as;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cache-Control: max-age=0  

HTTP/1.x 200 OK
Server: Pramati Server/5.0SP3 [Servlet/2.4 JSP/2.0]
Date: Tue, 24 Jul 2007 05:29:20 GMT
Transfer-Encoding: chunked
Connection: Keep-Alive

Notice that in the response headers, there is no Last-Modified header. This is the reason why the browser is reloading the script on every page load. This script is a DWR interface script. When you expose java methods using DWR (through a create tag in the dwr-*.xml), DWR creates an interface javascript. This file implements javascript methods which invoke the remote java methods (using DWREngine._execute). The interface script does not change unless the methods exposed in the dwr-*.xml are changed and the application is restarted. Hence the script should have been cacheable. These scripts are generated by DefaultInterfaceProcessor in DWR. To enable caching, we need to change the InterfaceProcessor to add the Last-Modified header in the response and read the If-Modified-Since header in the request. DWR provides a nice mechanism to plugin custom implementation of processors. So instead of chaging the DefaultInterfaceProcessor (which is shipped with DWR), I subclassed the default implementation to support these new headers and plugged it in to our runtime. The code for custom interface processor looks like:

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import uk.ltd.getahead.dwr.impl.DefaultInterfaceProcessor;
import uk.ltd.getahead.dwr.impl.HtmlConstants;  

/**
 * This class is the InterfaceProcessor for DWRHandler which
 * will add the functionality to add las modified header and
 * check if modified since header.
 * @author <a href="mailto:venkat@pramati.com" mce_href="mailto:venkat@pramati.com">Venkat Gunnu</a>
 * @since Jul 19, 2007
 */  

public class HttpCachingInterfaceProcessor
        extends DefaultInterfaceProcessor  

{
	//Store the application startup time. This will be the time we will set
	//as the Last-Modified time for all the interface scripts
	private final long lastUpdatedTime = (System.currentTimeMillis() / 1000) * 1000;  

	public void handle(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
	{
		long ifModifiedSince = req.getDateHeader(HtmlConstants.HEADER_IF_MODIFIED);
		if (ifModifiedSince < lastUpdatedTime) {
			//If the browser does not have the script in the cache or the cached copy is stale
			//set the Last-Modified date header and send the new script file
			//Note: If the browser does not have the script in its cache ifModifiedSince will be -1  

			resp.setDateHeader(HtmlConstants.HEADER_LAST_MODIFIED, lastUpdatedTime);
			super.handle(req, resp);
		} else {
			//If the browser has current version of the file, dont send the script. Just say it has not changed
			resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
		}
	}
}

To plugin this new Interface Processor, we need to add init parameter for DWRServlet in web.xml. The snippet from web.xml would look like:

<servlet><servlet-name>dwr-invoker</servlet-name>
<servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
<init-param>
<param-name>interface</param-name>
<param-value>util.dwr.HttpCachingInterfaceProcessor</param-value>
</init-param>
...
</servlet>

After adding the custom inerface processor following are the headers for the dwr interface request.

GET /dekohportal/dwr/interface/locationchooser.js HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en,as;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-aliveHTTP/1.x 200 OK
Server: Pramati Server/5.0SP3 [Servlet/2.4 JSP/2.0]
Date: Tue, 24 Jul 2007 05:49:43 GMT  

Last-Modified: Tue, 24 Jul 2007 05:49:33 GMT


Transfer-Encoding: chunked
Connection: Keep-Alive

Notice that now for the first request, DWR is sending the Last-Modfied header. When we make the second request, the browser sends an “If-Modified-Since” header and DWR now sends a 304 NOT_MODIFIED response.

GET /dekohportal/dwr/interface/locationchooser.js HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en,as;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
If-Modified-Since: Tue, 24 Jul 2007 05:49:33 GMT

  

HTTP/1.x 304 NOT_MODIFIED


Server: Pramati Server/5.0SP3 [Servlet/2.4 JSP/2.0]
Date: Tue, 24 Jul 2007 05:50:42 GMT
Content-Length: 0


Connection: Keep-Alive

Thus, by plugging in a custom interface processor, we can enable caching of interface java-scripts in DWR.

 

原文:http://blogs.dekoh.com/dev/2007/07/24/caching-dwr-interface-java-script-files/

分享到:
评论

相关推荐

    DWR生成目录树

    在本主题中,我们将深入探讨如何使用DWR生成目录树,这在构建动态的、交互性强的Web应用时尤其有用。 目录树是一种数据结构,通常用于表示文件系统或组织层次结构。在Web应用中,用户可能需要浏览多级目录结构,...

    DWR相关文件

    5. **在HTML/JavaScript中使用DWR**:在客户端页面中引入DWR生成的JavaScript文件,并在JavaScript代码中调用对应的方法。 6. **测试和调试**:使用浏览器和开发工具测试DWR调用是否正常工作,如果遇到问题,查看...

    dwr的包文件jar

    5. **前端集成**:在HTML页面中引入DWR生成的JavaScript文件,并使用这些接口进行AJAX通信。 总的来说,DWR是一个强大的工具,简化了AJAX应用的开发,通过其丰富的特性,可以构建出交互性强、用户体验良好的Web应用...

    dwr实例,从后台取数据显示

    - **在JavaScript中调用**:在HTML或JavaScript文件中引入生成的JavaScript接口,即可像调用本地函数一样调用服务器端的方法。 4. **安全性**:DWR提供了一些安全特性,如IP白名单、方法签名验证等,以防止未授权...

    dwr教程+dwr.jar+util.js+engine.js

    `util.js` 和 `engine.js` 是DWR的核心JavaScript库。`util.js` 提供了一系列实用工具函数,用于辅助JavaScript编程,例如类型检查、对象遍历等。`engine.js` 是DWR引擎的核心,负责处理与服务器的通信,包括请求的...

    DWR js框架 javascript框架 web与java交互 Direct Web Remoting Ajax开源框架

    - **生成JavaScript接口**:DWR自动生成对应的JavaScript接口,使得客户端可以直接调用。 - **客户端使用**:在HTML页面中引入DWR的JavaScript库,并使用生成的接口进行Ajax调用。 3. **DWR的安全性** - **白...

    ajax 框架 dwr java

    4. **编写JavaScript代码**:在HTML或JS文件中,引入DWR生成的JavaScript库,并调用服务器端的方法。 5. **测试与运行**:启动服务器,通过浏览器访问应用,测试DWR功能是否正常工作。 ### 4. DWR的主要特性 - **...

    dwr入门简单实现示例

    5. **编写前端代码**:在HTML或JS文件中,引入DWR生成的JavaScript库,然后调用对应的接口方法。 6. **测试运行**:运行HTML页面,查看DWR是否能正确地与服务器通信。 **四、DWR示例** 在`dwrTest`这个示例中,...

    java dwr 框架源码

    - **在HTML/JavaScript中使用**:在客户端的JavaScript代码中引入DWR生成的JavaScript文件,然后就可以直接调用服务器端的方法。 4. **安全性与优化**:DWR提供了多种安全机制,如白名单、IP过滤等,以防止未授权...

    dwr 包的 使用入门

    - 在HTML页面中,引入DWR生成的JavaScript文件,例如`dwr.engine.js`和相关的接口文件。 - 使用DWR的API,如`DWRUtil`或`RemoteObject`,来调用服务器端的方法。 7. **安全性和权限控制**: - DWR提供了安全机制...

    dwr所需要的jar包

    例如,如果你有一个名为`MyService`的Java类,其中有一个`sayHello()`方法,DWR会自动生成一个`myService`对象,你可以直接在JavaScript中调用`myService.sayHello()`。 **4. 示例** 假设你已经有了一个`MyService...

    Ajax框架:简单的dwr实例

    5. **编写HTML与JavaScript**:在HTML页面中引入DWR生成的JavaScript文件,并使用生成的接口进行AJAX调用。 6. **测试与调试**:通过浏览器运行HTML页面,检查JavaScript日志或使用开发者工具查看网络请求,确保DWR...

    dwr 实例(MyEclipse开发,包括dwr所用jar包)

    - **JavaScript调用**:在HTML页面中,引入DWR生成的JavaScript文件,然后就可以像调用本地函数一样调用服务器端的方法。 - **事件处理**:可以将DWR方法绑定到DOM元素的事件,实现异步更新。 - **安全考虑**:...

    初学dwr时做的一个项目实例(代码全)

    - `*.js`: 生成的JavaScript文件,包含了调用Java方法的代码。 6. **学习与实践** 对于初学者,这个项目实例提供了很好的学习素材。通过阅读源代码,可以理解DWR如何将Java方法暴露给JavaScript,以及如何处理...

    dwr推送及js访问java代码

    2. **JavaScript接口**:在客户端,DWR会自动生成对应的JavaScript接口。例如,如果服务器有`executeTask`方法,那么在JavaScript中可以直接调用`MyService.executeTask(param1, param2)`。 3. **DWR推送(Push)**...

    DWR让Ajax如此简单

    3. **生成JavaScript接口**: DWR自动生成JavaScript接口,开发者只需调用这些接口即可执行服务器端的方法。 4. **调用服务器方法**: 在JavaScript代码中,像调用本地函数一样调用这些接口。 5. **处理回调**: ...

    dwr实现的分页功能

    这包括在`web.xml`中添加DWR的Servlet配置,以及创建一个`dwr-engine.js`和`dwr-config.xml`文件来定义可暴露给JavaScript的Java类和方法。 3. **DWR的使用** - **创建Java Bean**:在服务器端,我们需要创建一个...

    dwr3api+DWR文档.pdf

    3. **使用DWR生成的JavaScript API**:DWR自动生成JavaScript接口,使得前端可以直接调用服务器端的方法。文档会介绍如何使用这些接口,以及如何定义和调用远程Java类和方法。 4. **安全与权限控制**:DWR提供了...

    DWR小代码小例子

    5. **实例化与调用**:在HTML页面中,你需要引入DWR生成的JavaScript文件,并实例化相应的对象来调用Java方法。例如,`&lt;script src="/dwr/interface/YourJavaClass.js"&gt;&lt;/script&gt;`,然后就可以通过`YourJavaClass....

    dwr原理深入透彻讲解

    3. **资源传输**:DWR引擎通过Servlet响应客户端请求,将`engine.js`、`util.js`等必需的JavaScript文件发送到客户端。如果客户端已经有这些文件的缓存,并且文件内容没有改变,DWR会避免重复发送,以优化性能。 4....

Global site tag (gtag.js) - Google Analytics