<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>sam.ds.chen</title>
    <description></description>
    <link>http://sam-ds-chen.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>浅谈基于ExtJS的AJAX程序中i18n的实现</title>
        <author>sam.ds.chen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sam-ds-chen.javaeye.com">sam.ds.chen</a>&nbsp;
          链接：<a href="http://sam-ds-chen.javaeye.com/blog/196946" style="color:red;">http://sam-ds-chen.javaeye.com/blog/196946</a>&nbsp;
          发表时间: 2008年05月26日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>前两天在我的Gajax框架中实现了i18n<br />先来几张图</p>
<p>1. 中文界面</p>
<p><img src="../../../upload/picture/pic/15071/04352697-7823-382a-9592-e177ec21889b.jpg" alt="中文界面" /></p>
<p>2. 英文界面</p>
<p><img src="../../../upload/picture/pic/15069/787745b8-911b-312a-860d-9f64dac901ea.jpg" alt="英文界面" /></p>
<p>3. 界面语言设置窗口</p>
<p><img src="../../../upload/picture/pic/15067/047ac27e-7aeb-3aa3-9453-c85b99d10541.jpg" alt="界面语言设置窗口" /></p>
<p>实现步骤如下：</p>
<p>1. 写一个LocaleServlet</p>
<pre name="code" class="java">package org.gajaxframework.i18n;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.gajaxframework.context.GajaxContext;

/**
 * Gajax Locale Servlet
 * 
 * @author Sam Chen
 * @version 1.0 05/24/2008 11:54
 */
public class LocaleServlet extends HttpServlet {
	
	private static String DEFAULT_LANGUAGE = "EN";
	private static String localeConfigLocation = "/WEB-INF/locale";
	
	private static Map&lt;String, String&gt; LOCALES = new HashMap&lt;String, String&gt;();
	
	private static Log log = LogFactory.getLog(LocaleServlet.class);

	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
//	    String language = (String) request.getParameter("language");
	    String pathInfo = request.getPathInfo();
	    String language = null == pathInfo ? "" : pathInfo.substring(pathInfo.lastIndexOf("/") + 1);
		
	    if (null == language || "".equals(language.trim())) {
	    	// FIXME: get language setting from the user's customized settings
	    	language = "EN";
	    }
	    
	    language = (null == language ? DEFAULT_LANGUAGE : language.toUpperCase());

	    String resource = LOCALES.get(language);
	    if (null == resource) {
	    	log.warn("No locale resource found for language '" + language + "'. Defaults to '" + DEFAULT_LANGUAGE + "'");
	    	resource = LOCALES.get(DEFAULT_LANGUAGE);
	    } else {
	    	log.info("Locale resource found for language '" + language + "'.");
	    }
	    
	    printResource(response, resource);
	    
	}
	
	/**
	 * print locale resource to the client
	 * 
	 * @param response
	 */
	private void printResource(HttpServletResponse response, String resource) throws IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter writer = response.getWriter();
		writer.print(resource);
		writer.flush();
		writer.close();
	}

	// ====================== initialization ======================
	@Override
	public void init(ServletConfig config) throws ServletException {
		
		String customizedDEFAULT_LANGUAGE = config.getInitParameter("DEFAULT_LANGUAGE");
		String customizedlocaleConfigLocation = config.getInitParameter("localeConfigLocation");

		// override the default(hard-coded) configurations if there're customized configurations
		if (null != customizedDEFAULT_LANGUAGE) {
			DEFAULT_LANGUAGE = customizedDEFAULT_LANGUAGE;
		}
		if (null != customizedlocaleConfigLocation) {
			localeConfigLocation = customizedlocaleConfigLocation;
		}
		
		loadLocales(localeConfigLocation);
	}

	/**
	 * load all the locales and put 'em to the map
	 * @param localeConfigLocation
	 */
	private void loadLocales(String localeConfigLocation) {
		localeConfigLocation = GajaxContext.REAL_PATH + localeConfigLocation;
		File localeConfigFolder = new File(localeConfigLocation);
		File[] localeFiles = localeConfigFolder.listFiles();
		
		for (int i = 0, l = localeFiles.length; i &lt; l; i++) {
			File localeFile = localeFiles[i];
			String fileName = localeFile.getName();
			if (!fileName.endsWith(".properties") || fileName.endsWith(".original.properties")) {
				continue;
			}
			String language = fileName.substring(fileName.indexOf("_") + 1, fileName.indexOf(".properties"));
			
			InputStream is = null;
			try {
				is = new FileInputStream(localeFile);
				Properties properties = new Properties();
				properties.load(is);
				String json = conver2Json(properties);
				LOCALES.put(language.toUpperCase(), json);
				log.info("Locale resource for language '" + language + "' loaded:\n" + json);
			} catch (FileNotFoundException fnfe) {
				;
			} catch (IOException ioe) {
				;
			} finally {
				try {
					is.close();
				} catch (Exception x) {}
			}
		}
	

	}
	
	/**
	 * convert key-value pairs to JSON format
	 * @param properties
	 * @return
	 */
	private String conver2Json(Properties properties) {
		StringBuilder sb = new StringBuilder();
		sb.append("GajaxLocale={\n");
		sb.append("    'PROJECT_NAME':'MyDesktop',\n");
		sb.append("    'PROJECT_VERSION':'1.0 Beta',\n");
		sb.append("    'SERVLET_CONTEXT_NAME':").append("'").append(GajaxContext.SERVLET_CONTEXT_NAME).append("',\n");
		
		List&lt;String&gt; keys = new ArrayList&lt;String&gt;();
		for (Enumeration&lt;Object&gt; em = properties.keys(); em.hasMoreElements();) {
			String key = (String) em.nextElement();
			keys.add(key);
		}
		Collections.sort(keys, new Comparator&lt;String&gt;() {
			public int compare(String k1, String k2) {
				return k1.compareTo(k2);
			}
		});
		
		for (int i = 0, l = keys.size(); i &lt; l; i++) {
			String key = keys.get(i);
			String value = properties.getProperty(key);
			String suffix = i == l - 1 ? "};" : ",";
			
			if (null == value || "".equals(value.trim()) || "null".equalsIgnoreCase(value.trim())) {
				sb.append("    '").append(key).append("'").append(":").append("null").append(suffix).append("\n");
			} else {
				sb.append("    '").append(key).append("'").append(":").append("'").append(value).append("'").append(suffix).append("\n");
			}
		}
		
		return sb.toString();
	}
	
}
</pre>
<p>&nbsp;&nbsp;为了得到中文Locale资源文件对应的UTF-8编码的文件，写个bat来调用%JAVA_HOME%/bin/native2ascii.exe</p>
<div class="codeblock" style="margin: 5px 20px 20px;">
<pre>@echo off
                                         
echo ==============================================
echo Native2Ascii Utility
echo Author Sam Chen, Senior Software Engineer, GRS
echo Version 1.0 05/24/2008 11:23
echo ==============================================

set CURRENT_DIR=%cd%
echo Current DIR is %CURRENT_DIR%
cd ../workspace/MyDesktop/WEB-INF/locale
set CURRENT_DIR=%cd%
echo Current DIR changed to %CURRENT_DIR%
native2ascii.exe -encoding UTF-8 ./Gajax_zh.original.properties ./Gajax_zh.properties
echo Command 'native2ascii.exe -encoding UTF-8 ./Gajax_zh.original.properties ./Gajax_zh.properties' executed successfully
@pause</pre>
</div>
<p>在web.xml文件中配置这个serlet</p>
<div class="codeblock" style="margin: 5px 20px 20px;">
<pre>&lt;servlet&gt;
        &lt;servlet-name&gt;localeServlet&lt;/servlet-name&gt;
        &lt;servlet-class&gt;org.gajaxframework.i18n.LocaleServlet&lt;/servlet-class&gt;
        &lt;init-param&gt;
            &lt;param-name&gt;DEFAULT_LANGUAGE&lt;/param-name&gt;
            &lt;param-value&gt;EN&lt;/param-value&gt;
        &lt;/init-param&gt;
        &lt;init-param&gt;
            &lt;param-name&gt;localeConfigLocation&lt;/param-name&gt;
            &lt;param-value&gt;/WEB-INF/locale&lt;/param-value&gt;
        &lt;/init-param&gt;
        &lt;load-on-startup&gt;0&lt;/load-on-startup&gt;
&lt;/servlet&gt;
	
&lt;servlet-mapping&gt;
        &lt;servlet-name&gt;localeServlet&lt;/servlet-name&gt;
        &lt;url-pattern&gt;/jslib/i18n/GajaxLocale/*&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;</pre>
</div>
<p>2. html文件中用script标签下载locale资源</p>
<div class="codeblock" style="margin: 5px 20px 20px;">
<pre>&lt;!-- i18n resources --&gt;
&lt;script type="text/javascript" src="jslib/i18n/GajaxLocale/zh" charset="utf-8"&gt;&lt;/script&gt;</pre>
</div>
<p>注意这个script标签应该排在最前头，以保证locale资源对后续javascript可用<br /><br />3. 再来个helper -- locale.js</p>
<div class="codeblock" style="margin: 5px 20px 20px;">
<pre>/**
 * GRS.framework.data.Locale
 * @author Sam Chen
 * @version 1.0 11/21/2007 21:22
 * @version 1.0 05/24/2008 19:51 
 * (replaced hard-coded locale object with the JSON object downloaded from the server side)
 */
Ext.namespace("GRS.framework.data");
GRS.framework.data.Locale = function(M) {
   this.map = M || {}
};
Ext.extend(GRS.framework.data.Locale, Ext.util.Observable, {
   get : function(key) {
      var value = this.map[key] || (key + ' not found!'); 
      if(arguments.length &gt; 1 &amp;&amp; value.indexOf('{') &gt;= 0) {
         value = new Ext.Template(value).apply(Array.prototype.slice.call(arguments, 1))
      }
      return value
   }
});

// GajaxLocale is a JSON object downloaded from the server side
var locale = new GRS.framework.data.Locale(GajaxLocale);

// shortcut for the method locale.get
$ = locale.get.createDelegate(locale);</pre>
</div>
<p>4. html文件如下</p>
<pre name="code" class="html">&lt;html&gt;
&lt;head&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"&gt;
&lt;title&gt;MyDesktop App&lt;/title&gt;

    &lt;link rel="stylesheet" type="text/css" href="jslib/ext-2.1/resources/css/ext-all.css" /&gt;
    &lt;link rel="stylesheet" type="text/css" href="resources/css/icons/icons.css" /&gt;
    
    &lt;!-- i18n resources --&gt;
    &lt;script type="text/javascript" src="jslib/i18n/GajaxLocale/zh" charset="utf-8"&gt;&lt;/script&gt;
 	
    &lt;script type="text/javascript" src="jslib/ext-2.1/adapter/ext/ext-base.js"&gt;&lt;/script&gt;
    &lt;script type="text/javascript" src="jslib/ext-2.1/ext-all.js"&gt;&lt;/script&gt;
    
    &lt;script type="text/javascript" src="jslib/grsframework/data/Locale.js"&gt;&lt;/script&gt;

	&lt;!-- DESKTOP --&gt;
	&lt;script type="text/javascript" src="jslib/desktop/core/StartMenu.js"&gt;&lt;/script&gt;
	&lt;script type="text/javascript" src="jslib/desktop/core/TaskBar.js"&gt;&lt;/script&gt;
	&lt;script type="text/javascript" src="jslib/desktop/core/Desktop.js"&gt;&lt;/script&gt;
	&lt;script type="text/javascript" src="jslib/desktop/core/App.js"&gt;&lt;/script&gt;
	&lt;script type="text/javascript" src="jslib/desktop/core/Module.js"&gt;&lt;/script&gt;
	&lt;script type="text/javascript" src="jslib/desktop/core/DesktopConfig.js"&gt;&lt;/script&gt;

	&lt;!-- DESKTOP HELPERS --&gt;
	&lt;script type="text/javascript" src="jslib/desktop/helpers/color-picker/color-picker.ux.js"&gt;&lt;/script&gt;
	
	&lt;link rel="stylesheet" type="text/css" href="jslib/desktop/helpers/color-picker/color-picker.ux.css" /&gt;
	&lt;script type="text/javascript" src="jslib/desktop/helpers/preferences/Preferences.js"&gt;&lt;/script&gt;
	&lt;link rel="stylesheet" type="text/css" href="jslib/desktop/helpers/preferences/preferences.css" /&gt;
	
	&lt;!-- MODULES --&gt;
	&lt;script type="text/javascript" src="jslib/modules/layout-window/js/layout-window.js"&gt;&lt;/script&gt;
	&lt;script type="text/javascript" src="jslib/modules/docs/js/docs.js"&gt;&lt;/script&gt;
	&lt;link rel="stylesheet" type="text/css" href="jslib/modules/docs/css/docs.css" /&gt;
	
	&lt;!-- DESKTOP STYLES --&gt;
	&lt;link rel="stylesheet" type="text/css" href="jslib/ext-2.1/examples/desktop/css/desktop.css" /&gt;
	&lt;link rel="stylesheet" type="text/css" href="resources/css/desktop-sam.css" /&gt;
&lt;/head&gt;
&lt;body id="desktop-body" scroll="no" background="resources/wallpapers/blue-swirl.jpg"&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>&nbsp;谨发此文，以抛砖引玉。</p>
          <br/>
          <span style="color:red;">
            <a href="http://sam-ds-chen.javaeye.com/blog/196946#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 26 May 2008 11:30:24 +0800</pubDate>
        <link>http://sam-ds-chen.javaeye.com/blog/196946</link>
        <guid>http://sam-ds-chen.javaeye.com/blog/196946</guid>
      </item>
      <item>
        <title>应该先看文档，不能瞎猜（一不小心沦为新手帖，发帖宜三思后行...）</title>
        <author>sam.ds.chen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sam-ds-chen.javaeye.com">sam.ds.chen</a>&nbsp;
          链接：<a href="http://sam-ds-chen.javaeye.com/blog/195390" style="color:red;">http://sam-ds-chen.javaeye.com/blog/195390</a>&nbsp;
          发表时间: 2008年05月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          
          <br/>
          <span style="color:red;">
            <a href="http://sam-ds-chen.javaeye.com/blog/195390#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 21 May 2008 18:22:56 +0800</pubDate>
        <link>http://sam-ds-chen.javaeye.com/blog/195390</link>
        <guid>http://sam-ds-chen.javaeye.com/blog/195390</guid>
      </item>
      <item>
        <title>Web Services应用实例 -- Java Web App远程调用SAS程序的解决方案</title>
        <author>sam.ds.chen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sam-ds-chen.javaeye.com">sam.ds.chen</a>&nbsp;
          链接：<a href="http://sam-ds-chen.javaeye.com/blog/180905" style="color:red;">http://sam-ds-chen.javaeye.com/blog/180905</a>&nbsp;
          发表时间: 2008年04月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          最近要做个小项目WebView，让客户能通过浏览器看他的文件（由公司SAS程序产生的一些报表）。<br />这算是我做的第二个AJAX应用。<br />其实做个类似于Windows资源管理器的界面是很简单的，在ExtJS的examples基础上改改就好了--我一直是这么做的。当然还要实现的就是访问控制，对这个小项目而言都不值一提。<br />幕后英雄是SAS程序，它将被我的Java程序调用。至于SAS到底是什么东西，我不太了解，也不需要太了解，我只从公司SAS程序员那里知道，它是用来分析数据的。我只需要知道那个SAS命令的调法就足够了。<br /><br />问题是，SAS程序部署在SAS Server上，而我要开发的Java Web App将部署在另一台Server上。如果在同一台机器上，用Runtime.getRuntime().exec就可以直接调用SAS程序了。现在这种情况，宜用Web Services来做。<br /><br />1. 在SAS Server上安装JDK和Tomcat.<br />2. SASWebServices开发。同样，改改Google来的一个demo就好了（看来Google是软件开发人员的必备工具）<br />代码不多，多的是配置和依赖的JARs<br /><pre name="code" class="java">
package com.grs.webview.webservices.sas;

import java.io.IOException;

import javax.jws.WebService;

@WebService 
public interface ISASService {
	public void process() throws IOException;
}
</pre><br /><br /><pre name="code" class="java">
package com.grs.webview.webservices.sas;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

import javax.jws.WebService;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

@WebService( 
	serviceName = "SASService", 
	endpointInterface = "com.grs.webview.webservices.sas.ISASService" 
) 
public class SASServiceImpl implements ISASService {
	
	private static Log log = LogFactory.getLog(SASServiceImpl.class);

	/**
	 * invoke SAS command
	 */
	public void process() throws IOException {
		log.info("invoking SAS program...");
		
		StringBuffer cmd = new StringBuffer("cmd");
		
//		String[] cmds = new String[]{"mkdir sam_tmp_0", "cd sam_tmp_0", "mkdir sam_tmp_1", "cd sam_tmp_1", "mkdir sam_tmp_2"};
//		String[] cmds = new String[]{"cd D:\\wwwroot", "d:", "mkdir sam_tmp_1", "cd sam_tmp_1", "mkdir sam_tmp_2"};
		
		String[] cmds = new String[]{
				new StringBuilder()
					.append("\"C:\\Program Files\\SAS\\SAS 9.1\\SAS.EXE\" ")
					.append("D:\\wwwroot\\TEST.sas ")
					.append("-CONFIG \"C:\\Program Files\\SAS\\SAS 9.1\\nls\\en\\SASV9.CFG\" ") 
					.append("-nosplash ") 
					.append("-nologo ") 
					.append("-noautoexec ") 
					.append("–icon")
					.toString()};

		Process p = Runtime.getRuntime().exec(cmd.toString());
		
		new OutputStuffThread(p, cmds).start();
		
		BufferedInputStream buffer = new BufferedInputStream(p.getErrorStream());
		BufferedReader commandResult = new BufferedReader(new InputStreamReader(buffer));
		try {
			for (int count = 0; count &lt; cmds.length + 1;count++) {
				String s = commandResult.readLine();
				log.info("Command output #" + (count + 1) + " : " + s);			
			}
			commandResult.close();
		} catch (java.io.IOException e) {
			e.printStackTrace();
		}
		
		log.info("SAS program invoked.");
		
	}

}


/**
 * the class is needed for interactive commands
 * 
 * @author Sam Chen
 * @version 1.0 08/09/2007
 */
class OutputStuffThread extends Thread {
	private Process m_process;
	private String[] m_rest;

	public OutputStuffThread(Process process, String[] rest) {
		m_process = process;
		m_rest = rest;
	}

	public void run() {
		try {
			BufferedOutputStream bufferout = new BufferedOutputStream(m_process.getOutputStream());
			PrintWriter commandInput = new PrintWriter((new OutputStreamWriter(bufferout)), true);
			if (null == m_rest || m_rest.length == 0) {
				commandInput.println("exit");
			} else {
				for (int i = 0; i &lt; m_rest.length; i++) {
					commandInput.println(m_rest[i]);
				}
				if (!"exit".equals(m_rest[m_rest.length - 1])) {
					commandInput.println("exit");
				}
			}
			commandInput.close();
		} catch( Exception e ) {
			System.err.println(e);
		}
	}

}
</pre><br /><br /><pre name="code" class="java">
package test;

import org.codehaus.xfire.service.Service;
import org.codehaus.xfire.client.XFireProxyFactory;
import org.codehaus.xfire.annotations.AnnotationServiceFactory;

import com.grs.webview.webservices.sas.ISASService;
import com.grs.webview.webservices.sas.SASServiceImpl;

import java.io.IOException;
import java.net.MalformedURLException; 

public class TestRunner {

	public static void main(String[] args) throws IOException { 
		
		Service serviceModel = new AnnotationServiceFactory().create( SASServiceImpl.class);
		
//	    String url = "http://localhost:8888/SASWebServices/services/SASService";
		String url = "http://assasii.grs-cro.com:8080/SASWebServices/services/SASService";
		
	    try { 
			ISASService service = (ISASService)new XFireProxyFactory().create(serviceModel, url); 
			service.process();
		} catch (MalformedURLException e) { 
			e.printStackTrace(); 
		}
	
	} 
}
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://sam-ds-chen.javaeye.com/blog/180905#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 09 Apr 2008 16:58:16 +0800</pubDate>
        <link>http://sam-ds-chen.javaeye.com/blog/180905</link>
        <guid>http://sam-ds-chen.javaeye.com/blog/180905</guid>
      </item>
      <item>
        <title>ExtJS的s.gif问题</title>
        <author>sam.ds.chen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sam-ds-chen.javaeye.com">sam.ds.chen</a>&nbsp;
          链接：<a href="http://sam-ds-chen.javaeye.com/blog/178869" style="color:red;">http://sam-ds-chen.javaeye.com/blog/178869</a>&nbsp;
          发表时间: 2008年04月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          我的webapp framework写完了,做了个demo,在公司似乎跑得很正常。<br />还有几个地方不太满意--谁让我是完美主义者呢,于是下班后在家接着重构。<br />靠在床上,把它跑起来,去发现不对劲了：<br /><img src="http://sam-ds-chen.javaeye.com/upload/picture/pic/11010/f11e07f2-2bca-360f-bc4e-f0c3ea6f1d51.jpg" /><br />怎么变得如此面目可憎？什么图片在作怪？点右键看看它的url先,可是点右键却没反应--怨我自己,解铃还需系令人,把我的index.html中的<br />&lt;body id="body" scroll="no" onContextMenu="return false;" bgcolor="#c3daf9"><br />改成<br />&lt;body id="body" scroll="no" bgcolor="#c3daf9"><br />发现它的url为： http://extjs.com/s.gif<br />原来如此：在公司连着网,所以能得到这个blank image;在家没连网,所以在没有s.gif的情况下,界面上很难看了。<br />干嘛非得上extjs.com去拿这个东西呢？本地就有嘛。<br />开始在ExtJS(v2.2.2)的目录中搜索extjs.com/s.gif ... 结果在ext-base.js中找到：<br />BLANK_IMAGE_URL:"http:/"+"/extjs.com/s.gif",如果用http://extjs.com/s.gif还搜它不到呢,干嘛要拼接一下？不会是不想让我搜索到吧？不管那么多了,改了它先：<br />BLANK_IMAGE_URL:"resources/images/default/s.gif"/*Modified by Sam Chen on 04/01/2008"http:/"+"/extjs.com/s.gif"*/,<br />然后,就好了：<br /><img src="http://sam-ds-chen.javaeye.com/upload/picture/pic/11008/3fecbc92-c3c5-304a-8be4-7a4cf92f85a7.jpg" />
          <br/>
          <span style="color:red;">
            <a href="http://sam-ds-chen.javaeye.com/blog/178869#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 02 Apr 2008 15:55:12 +0800</pubDate>
        <link>http://sam-ds-chen.javaeye.com/blog/178869</link>
        <guid>http://sam-ds-chen.javaeye.com/blog/178869</guid>
      </item>
      <item>
        <title>Request和Response的线程安全问题的另一个解决方案</title>
        <author>sam.ds.chen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sam-ds-chen.javaeye.com">sam.ds.chen</a>&nbsp;
          链接：<a href="http://sam-ds-chen.javaeye.com/blog/177997" style="color:red;">http://sam-ds-chen.javaeye.com/blog/177997</a>&nbsp;
          发表时间: 2008年03月31日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Zigzag Chen的Swato框架提供了RequestAware和SessionAware接口,如果你的service需要访问Request或Response对象,需要实现RequestAware或SessionAware.在Swato的JSONServlet中调用你的service的setRequest, setResponse, setSession等之类的方法把Request, Response, Session注入 -- 但你的service自身需要解决线程安全问题,我原先的解决方案是,在service中整个Map,实现sessionId到Request, Response, Session的映射,这样每个session对应map中的一个entry,就不用担心不同线程的Request, Response, Session之间的相互覆盖问题了。<br />最近对代码进行了一番重构,总感觉这种线程安全问题的解决方案不够优雅。<br />看过JForum的源代码,从他那里学了一招,于是一种更优雅的解决方案产生了：<br /><pre name="code" class="java">
/*
 * Copyright (c) JForum Team
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, 
 * with or without modification, are permitted provided 
 * that the following conditions are met:
 * 
 * 1) Redistributions of source code must retain the above 
 * copyright notice, this list of conditions and the 
 * following  disclaimer.
 * 2)  Redistributions in binary form must reproduce the 
 * above copyright notice, this list of conditions and 
 * the following disclaimer in the documentation and/or 
 * other materials provided with the distribution.
 * 3) Neither the name of "Rafael Steil" nor 
 * the names of its contributors may be used to endorse 
 * or promote products derived from this software without 
 * specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT 
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 
 * IN CONTRACT, STRICT LIABILITY, OR TORT 
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
 * 
 * This file creation date: 29/01/2006 - 12:19:11
 * The JForum Project
 * http://www.jforum.net
 */
package com.grs.context;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * A request and response container -- thread-safe 
 * 
 * @author Rafael Steil
 * @author Sam Chen
 * @version 1.0 03/24/2008
 */
public class ExecutionContext {
    private static ThreadLocal&lt;ExecutionContext> userData = new ThreadLocal&lt;ExecutionContext>();
    private HttpServletRequest request;
    private HttpServletResponse response;
	
	/**
	 * Gets the execution context.
	 * @return ExecutionContext
	 */
	private static ExecutionContext getInstance() {
		ExecutionContext ex = userData.get();

		if (ex == null) {
			ex = new ExecutionContext();
			userData.set(ex);
		}
		
		return ex;
	}

	/**
	 * Sets the current thread's request
	 * @param request
	 */
	public static void setRequest(HttpServletRequest request) {
		ExecutionContext.getInstance().request = request;
	}
    /**
	 * Gets the current thread's request
	 * @return HttpServletRequest
	 */
    public static HttpServletRequest getRequest() {
        return ExecutionContext.getInstance().request;
    }

    /**
     * Sets the current thread's response
     * @param response
     */
    public static void setResponse(HttpServletResponse response) {
    	ExecutionContext.getInstance().response = response;
    }
    /**
     * Gets the current thread's response
     * @return HttpServletResponse
     */
    public static HttpServletResponse getResponse() {
        return ExecutionContext.getInstance().response;
    }

}

</pre><br /><br />有了这个Context,只需要在JSONServlet先调<br /><pre name="code" class="java">
ExecutionContext.setRequest(request);
ExecutionContext.setResponse(response);
</pre><br />然后在service调用<br /><pre name="code" class="java">
ExecutionContext.getRequest();
ExecutionContext.getResponse();
</pre><br />即可分别得到对应于当前线程的Request和Response
          <br/>
          <span style="color:red;">
            <a href="http://sam-ds-chen.javaeye.com/blog/177997#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 31 Mar 2008 12:28:29 +0800</pubDate>
        <link>http://sam-ds-chen.javaeye.com/blog/177997</link>
        <guid>http://sam-ds-chen.javaeye.com/blog/177997</guid>
      </item>
      <item>
        <title>写个适合自己的RPC Engine (续)</title>
        <author>sam.ds.chen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sam-ds-chen.javaeye.com">sam.ds.chen</a>&nbsp;
          链接：<a href="http://sam-ds-chen.javaeye.com/blog/177990" style="color:red;">http://sam-ds-chen.javaeye.com/blog/177990</a>&nbsp;
          发表时间: 2008年03月31日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="js">
Ext.namespace("GRS.framework.rpc");
/**
 * GRS.framework.rpc.RPCEngine
 * 
 * @param url
 * @param options
 * @author Zhijie Chen &lt;zigzag.chen@gmail.com>
 * @author Sam Chen (inspired by Zigzag Chen's swato-engine.js)
 * @version 1.0 11/22/2007
 * @version 1.1 11/26/2007
 * @version 1.2 12/07/2007
 * @version 1.3 12/26/2007
 * @version 1.4 03/29/2008 (should be final)
 */
GRS.framework.rpc.RPCEngine = function(url,options) {
   this.url = url;
   this.conn_id = Math.floor(Math.random()*100000000);
   this.options = options;
   GRS.framework.rpc.RPCEngine.superclass.constructor.call(this)
}
Ext.extend(
   GRS.framework.rpc.RPCEngine,
   Ext.util.Observable,
   /**
    * @public
    * @param callback the callback function that processes the reponse or response.responseText
    * @param serviceDotMethodName the remote source requested
    * @param params (Array) the parameters
    * @param options the options
    */
   {call: function(callback, serviceDotMethodName, params, options) {
       if (this.url == null) {
       	  Ext.MessageBox.show({
             title: 'Error',
             msg: 'Cannot make rpc request as url is not defined.',
             buttons: Ext.MessageBox.OK,
             icon: 'ext-mb-error'});
          return;
       }      
       var serviceName = serviceDotMethodName.substring(0,serviceDotMethodName.indexOf("."));
       var methodName = serviceDotMethodName.substring(serviceDotMethodName.indexOf(".") + 1, serviceDotMethodName.length);
       _onComplete = function(response){
       	  Ext.MessageBox.hide();
          eval("var rt = " + response.responseText);
          var error = rt.error;
          if (error) {
             // session timed out -> relogin
             if (Constants.MSG_CODE_LOGIN_RELOGIN == error.code) {
             	Ext.MessageBox.show({
                   title: 'Error',
                   msg: error.msg,
                   buttons: Ext.MessageBox.OK,
                   icon: 'ext-mb-error'});
                // TODO: clear password
             	GRS.loginDlg.show();
             } else {
                Ext.MessageBox.show({
                   title: 'Error',
                   msg: error.msg + '&lt;br>Please contact the system administrator.',
                   buttons: Ext.MessageBox.OK,
                   icon: 'ext-mb-error'});
             }
             return
          }
          if (options && options.returnResponse == true) {
             callback(response);
      	  } else {
             callback(rt);
      	  }	 
       }
       
       Ext.Ajax.request({
          url: this.url,
          params: JSON.stringify({
             'service': serviceName,
             'method': methodName,
             'params': params,
             'conn_id': this.conn_id}),
          success: _onComplete,
          failure: function(){
             Ext.MessageBox.show({
                title: 'Error',
                msg: 'The requested resource ' + this.url + ' is not available.&lt;br>Please contact the system administrator.',
                buttons: Ext.MessageBox.OK,
                icon: 'ext-mb-error'})
          },
          scope: this});
    }
   }
);

// global rpcengine
rpcengine = new GRS.framework.rpc.RPCEngine("GRS_AJAX_RPC");
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://sam-ds-chen.javaeye.com/blog/177990#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 31 Mar 2008 12:04:53 +0800</pubDate>
        <link>http://sam-ds-chen.javaeye.com/blog/177990</link>
        <guid>http://sam-ds-chen.javaeye.com/blog/177990</guid>
      </item>
      <item>
        <title>初试GWT：为什么GWT宿主模式没跑起来</title>
        <author>sam.ds.chen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sam-ds-chen.javaeye.com">sam.ds.chen</a>&nbsp;
          链接：<a href="http://sam-ds-chen.javaeye.com/blog/166991" style="color:red;">http://sam-ds-chen.javaeye.com/blog/166991</a>&nbsp;
          发表时间: 2008年03月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          前段时间开发了基于ExtJS,JSON-RPC的Framework及其应用（公司内部自用）.<br />用户（同事们）的反映是：Sam你做的这个东西好是好，就是慢了点.<br />我小心翼翼地回答，这个速度问题，跟服务器，网络状况还有你的机器都有关系（其实我知道性能的瓶颈在客户端）.这样吧，我再优化一下我的代码，性能可能会有所提升.<br />我花几天时间改了改代码，然后把js压了压再重新deploy.<br />现在的表现是，一打开IE访问这个应用，进度条一闪就过去了，登录框立马显示了出来（给用户的感觉确实快了很多）。但是执行主要操作时表现实在慢:<br /><br />从<img src="http://sam-ds-chen.javaeye.com/upload/picture/pic/8720/e1dbbf7a-66da-306b-9265-2a37c83ecd09.jpg?1204531013" /><br />到<br /><img src="http://sam-ds-chen.javaeye.com/upload/picture/pic/8722/c353a858-e7a7-345a-a7de-5f8332d42ff5.jpg?1204531174" /><br /><br />耗时4秒。<br />性能低的罪魁祸首乃是ExtJS的Grid -- 我才疏学浅，要优化它实在是Mission Impossible.<br />（刚刚Linda又跑过来说，Sam你能不能让它跑快点啊，我填个timesheet要半小时啊。。。）<br /><br />怎么解决这个问题呢？<br />听说GWT不错，于是拿来试试先。<br />弄了个Helloworld，可是一运行HelloWorld-shell.cmd，它总是出来个窗口闪一下，也不跟我说句bye-bye就没了，委实让人纳闷。<br />是可忍孰不可忍，不行，得让它告诉我为什么！<br />运行Windows的cmd后，在窗口里敲HelloWorld-shell.cmd，它终于给我扔过来一句话：<br />Port 8888 is already is use; you probably still have another session active<br />原来如此，Eclipse里面Tomcat一直开在那里，而GWT的开发者跟我一样喜欢用8888端口。<br />我停掉了Tomcat，宿主模式跑出来了...<br />继续学习GWT...
          <br/>
          <span style="color:red;">
            <a href="http://sam-ds-chen.javaeye.com/blog/166991#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 03 Mar 2008 16:35:45 +0800</pubDate>
        <link>http://sam-ds-chen.javaeye.com/blog/166991</link>
        <guid>http://sam-ds-chen.javaeye.com/blog/166991</guid>
      </item>
      <item>
        <title>换上1.6.0.2的prototype.js后ExtJS报错</title>
        <author>sam.ds.chen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sam-ds-chen.javaeye.com">sam.ds.chen</a>&nbsp;
          链接：<a href="http://sam-ds-chen.javaeye.com/blog/164260" style="color:red;">http://sam-ds-chen.javaeye.com/blog/164260</a>&nbsp;
          发表时间: 2008年02月22日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          更新了一批js之后，ExtJS报错了：<br /><img src="http://sam-ds-chen.javaeye.com/upload/picture/pic/8162/74b48454-28e6-3c32-883e-c8bf1d8fad80.jpg?1203665456" /><br />自打采用ExtJS以来，最讨厌跟踪ExtJS的代码单步调试了<img src="/images/smiles/icon_twisted.gif"/><br />所以不打算从ExtJS上面找原因了（实际上我很信赖它）<br />怎么找到错误的罪魁祸首呢？由于错误出现在更新js之后，我采用了我惯用的办法，充分利用操作系统的Search功能，搜索刚刚被更新的js，找到嫌疑人如下：<br /><img src="http://sam-ds-chen.javaeye.com/upload/picture/pic/8164/8987173f-d79b-3f08-be6e-fdb33fc787cf.jpg?1203666148" /><br />逐一检查，最终发现是因为把prototype1.5.0_rc0.js换成了高版本的prototype1.6.0.2.js所致(低版本好使，高版本反而不好使了，真是岂有此理！)<br />（我在这里用prototype实际上只是利用了它的Ajax类,因为要跟我的RPCEngine整合，ExtJS的Ajax类似乎不能满足要求，而我不想重复发明轮子，所以借用prototype.）<br /><br />改天有空再把Ajax类从prototype中抽离出来改写，不让它再依赖于prototype...
          <br/>
          <span style="color:red;">
            <a href="http://sam-ds-chen.javaeye.com/blog/164260#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 22 Feb 2008 15:55:50 +0800</pubDate>
        <link>http://sam-ds-chen.javaeye.com/blog/164260</link>
        <guid>http://sam-ds-chen.javaeye.com/blog/164260</guid>
      </item>
      <item>
        <title>小心js中的逗号</title>
        <author>sam.ds.chen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sam-ds-chen.javaeye.com">sam.ds.chen</a>&nbsp;
          链接：<a href="http://sam-ds-chen.javaeye.com/blog/159273" style="color:red;">http://sam-ds-chen.javaeye.com/blog/159273</a>&nbsp;
          发表时间: 2008年01月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          修改了一些js代码之后，FF正常，IE却报错了：<br />Expected identified, string or number<br />根据我上次的经验，应该是有多余的逗号。<br />于是我在eclipse中用正则表达式 ,\s*} 进行搜索，未找到任何匹配的字符串。<br />这就奇怪了！<br />只好另外想辙了，在我的project目录下搜索到今天修改的js文件列表，一共5个，我用肉眼逐一扫描这些js，最后发现问题出在这里：<br /><pre name="code" class="java">
Ext.MessageBox.show({
   msg: 'Loading data from template...',
   progressText: 'Loading...',
   width:300,
   wait:true,/*
   waitConfig: {interval:500}*/
});
var delegate = doLoad.createDelegate(doLoad, [], true);
templateDataStore.on('load', delegate);
templateDataStore.load({params:[tplId, userinfo.id]});
</pre><br />实际上这和上次的问题是同样类型的，有多余逗号，让IE噎住了，只是我写正则表达式的时候没考虑到这种/*****/的情况，没能把它揪出来。<br /><br />去掉这个多余的逗号，IE不报错了。
          <br/>
          <span style="color:red;">
            <a href="http://sam-ds-chen.javaeye.com/blog/159273#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 25 Jan 2008 11:10:47 +0800</pubDate>
        <link>http://sam-ds-chen.javaeye.com/blog/159273</link>
        <guid>http://sam-ds-chen.javaeye.com/blog/159273</guid>
      </item>
      <item>
        <title>写个适合自己的RPC Engine</title>
        <author>sam.ds.chen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sam-ds-chen.javaeye.com">sam.ds.chen</a>&nbsp;
          链接：<a href="http://sam-ds-chen.javaeye.com/blog/142958" style="color:red;">http://sam-ds-chen.javaeye.com/blog/142958</a>&nbsp;
          发表时间: 2007年11月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          学习了Swato之后，受到启发，对Zigzag Chen的代码作了点修改，写了个适合自己的RPC Engine:
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-c" start="1">
    <li class="alt"><span><span class="comment">//&nbsp;imports&nbsp;dependencies:</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>GRS.loadJS(<span class="string">&quot;../jslib/3rdparty/prototype.js&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>GRS.loadJS(<span class="string">&quot;../jslib/3rdparty/json.js&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>Ext.namespace(<span class="string">&quot;GRS.rpc&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class=""><span><span class="comment">/**</span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;*&nbsp;Constructor&nbsp;of&nbsp;GRS.rpc.Engine</span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;*&nbsp;@param&nbsp;url</span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;*&nbsp;@param&nbsp;options</span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;*&nbsp;@author&nbsp;Zhijie&nbsp;Chen&nbsp;&lt;zigzag.chen@gmail.com&gt;</span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;*&nbsp;@author&nbsp;Sam&nbsp;Chen&nbsp;(inspired&nbsp;by&nbsp;Zigzag&nbsp;Chen's&nbsp;swato-engine.js)</span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;*&nbsp;@version&nbsp;1.0&nbsp;11/22/2007</span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>GRS.rpc.Engine&nbsp;=&nbsp;<span class="keyword">function</span><span>(url,options)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.url&nbsp;=&nbsp;url;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.conn_id&nbsp;=&nbsp;Math.floor(Math.random()*100000000);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.options&nbsp;=&nbsp;options;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;GRS.rpc.Engine.superclass.constructor.call(<span class="keyword">this</span><span>)&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>}&nbsp;&nbsp;</span></li>
    <li class=""><span>Ext.extend(&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;GRS.rpc.Engine,&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;Ext.util.Observable,&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;{call:&nbsp;<span class="keyword">function</span><span>(catcher,serviceDotMethodName,params,options)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>&nbsp;(&nbsp;</span><span class="keyword">this</span><span>.url&nbsp;==&nbsp;</span><span class="keyword">null</span><span>&nbsp;)&nbsp;</span><span class="keyword">return</span><span>;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">var</span><span>&nbsp;serviceId=serviceDotMethodName.substring(0,serviceDotMethodName.indexOf(</span><span class="string">&quot;.&quot;</span><span>));&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">var</span><span>&nbsp;methodName=serviceDotMethodName.substring(serviceDotMethodName.indexOf(</span><span class="string">&quot;.&quot;</span><span>)+1,serviceDotMethodName.length);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">var</span><span>&nbsp;option=</span><span class="keyword">new</span><span>&nbsp;Object();&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object.extend(option,options);&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option.onComplete=<span class="keyword">this</span><span>._onRequestComplete.bind(catcher);&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">new</span><span>&nbsp;Ajax.Request(</span><span class="keyword">this</span><span>.url+</span><span class="string">&quot;/&quot;</span><span>+serviceId,&nbsp;</span><span class="keyword">this</span><span>._requestOptions(serviceId.hashCode||serviceId,methodName,params,option));&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;fetch:&nbsp;<span class="keyword">function</span><span>(catcher,url,options)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>&nbsp;(&nbsp;url&nbsp;==&nbsp;</span><span class="keyword">null</span><span>&nbsp;)&nbsp;</span><span class="keyword">return</span><span>;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">var</span><span>&nbsp;option=</span><span class="keyword">new</span><span>&nbsp;Object();&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object.extend(option,options);&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option.onComplete=<span class="keyword">this</span><span>._onRequestComplete.bind(catcher);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">new</span><span>&nbsp;Ajax.Request(url,option);&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;send:&nbsp;<span class="keyword">function</span><span>(catcher,jsObject,remoteObjectID,options)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.call(catcher,remoteObjectID,</span><span class="string">''</span><span>,[jsObject],options);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;_requestOptions:&nbsp;<span class="keyword">function</span><span>(remoteObjectID,methodName,params,options)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">var</span><span>&nbsp;sendingData={&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">&quot;params&quot;</span><span>:params,&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">&quot;method&quot;</span><span>:methodName,&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">&quot;id&quot;</span><span>:remoteObjectID,&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">&quot;conn_id&quot;</span><span>:</span><span class="keyword">this</span><span>.conn_id};&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">var</span><span>&nbsp;requestOptions=</span><span class="keyword">new</span><span>&nbsp;Object();&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object.extend(requestOptions,<span class="keyword">this</span><span>.options);&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object.extend(requestOptions,options);&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;requestOptions.parameters=JSON.stringify(sendingData);&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;requestOptions;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;_onRequestComplete&nbsp;:&nbsp;<span class="keyword">function</span><span>(response)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>&nbsp;(response.status&nbsp;!=&nbsp;200)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eval(<span class="string">&quot;var&nbsp;error&nbsp;=&nbsp;&quot;</span><span>&nbsp;+&nbsp;response.responseText.error);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>&nbsp;(error!=undefined)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>&nbsp;(</span><span class="keyword">this</span><span>.failure!=</span><span class="keyword">null</span><span>)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;call&nbsp;the&nbsp;failure&nbsp;handler</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.failure.apply(</span><span class="keyword">this</span><span>,&nbsp;[error]);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span class="keyword">else</span><span>&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert(<span class="string">&quot;Warning&nbsp;from&nbsp;rpc.js&nbsp;:&nbsp;Error&nbsp;occurred&nbsp;and&nbsp;no&nbsp;error&nbsp;handler&nbsp;defined.&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span class="keyword">else</span><span>&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>&nbsp;(</span><span class="keyword">this</span><span>.success!=</span><span class="keyword">null</span><span>){&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;call&nbsp;the&nbsp;success&nbsp;handler:</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.success.apply(</span><span class="keyword">this</span><span>,&nbsp;[response.responseText]);&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>);&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span><span class="comment">//&nbsp;global&nbsp;rpcengine</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>rpcengine=<span class="keyword">new</span><span>&nbsp;GRS.rpc.Engine(</span><span class="string">&quot;/RPCServlet&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<br />
简单的测试代码：<br />
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-c" start="1">
    <li class="alt"><span><span>&lt;script&nbsp;type=</span><span class="string">&quot;text/javascript&quot;</span><span>&nbsp;charset=</span><span class="string">&quot;UTF-8&quot;</span><span>&nbsp;src=</span><span class="string">&quot;../../3rdparty/ext-2.0-beta1/adapter/ext/ext-base.js&quot;</span><span>&gt;&lt;/script&gt;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&lt;script&nbsp;type=<span class="string">&quot;text/javascript&quot;</span><span>&nbsp;charset=</span><span class="string">&quot;UTF-8&quot;</span><span>&nbsp;src=</span><span class="string">&quot;../../3rdparty/ext-2.0-beta1/ext-all.js&quot;</span><span>&gt;&lt;/script&gt;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&lt;script&nbsp;type=<span class="string">&quot;text/javascript&quot;</span><span>&nbsp;charset=</span><span class="string">&quot;UTF-8&quot;</span><span>&nbsp;src=</span><span class="string">&quot;../grsframework-core.js&quot;</span><span>&gt;&lt;/script&gt;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&lt;script&nbsp;type=<span class="string">&quot;text/javascript&quot;</span><span>&nbsp;charset=</span><span class="string">&quot;UTF-8&quot;</span><span>&nbsp;src=</span><span class="string">&quot;../rpc.js&quot;</span><span>&gt;&lt;/script&gt;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&lt;script&gt;&nbsp;&nbsp;</span></li>
    <li class=""><span><span class="keyword">var</span><span>&nbsp;handler={&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;success:<span class="keyword">function</span><span>(ret){&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert(<span class="string">&quot;testRPC.html&nbsp;::&nbsp;Result&nbsp;::&nbsp;&quot;</span><span>&nbsp;+&nbsp;ret);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;failure:<span class="keyword">function</span><span>(err){&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert(<span class="string">&quot;Err&nbsp;occurred&nbsp;:&nbsp;&quot;</span><span>&nbsp;+&nbsp;err);&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>};&nbsp;&nbsp;</span></li>
    <li class=""><span>window.onload&nbsp;=&nbsp;<span class="keyword">function</span><span>()&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;alert(<span class="string">&quot;testing&nbsp;rpcengine...&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;rpcengine.call(handler,<span class="string">&quot;userManager.getUserList&quot;</span><span>,[]);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>}&nbsp;&nbsp;</span></li>
    <li class=""><span>&lt;/script&gt;&nbsp;&nbsp;</span></li>
</ol>
</div>
          <br/>
          <span style="color:red;">
            <a href="http://sam-ds-chen.javaeye.com/blog/142958#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 23 Nov 2007 10:34:54 +0800</pubDate>
        <link>http://sam-ds-chen.javaeye.com/blog/142958</link>
        <guid>http://sam-ds-chen.javaeye.com/blog/142958</guid>
      </item>
      <item>
        <title>才识Filespots，又晤JSON-RPC-Java</title>
        <author>sam.ds.chen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sam-ds-chen.javaeye.com">sam.ds.chen</a>&nbsp;
          链接：<a href="http://sam-ds-chen.javaeye.com/blog/141695" style="color:red;">http://sam-ds-chen.javaeye.com/blog/141695</a>&nbsp;
          发表时间: 2007年11月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <font color="#ff0000">声明：上周五在JavaEye发了篇文章&ldquo;Filespots的核心代码终于显出原形（后更名为：</font><font color="#ff0000">揭开Filespots核心代码的面纱）&rdquo;，由于内容涉嫌破译Filespots被加密的js，业已被Robbin删除。<br />
</font><font color="#ff0000"><font color="#000000">
<div class="dp-highlighter">
<ol class="dp-j" start="1"><font><font>
    <li class="alt">Sam says:</li>
    <li class="alt">我昨天发了一篇原创文章:揭开Filespots核心代码的面纱（http://www.javaeye.com/post/414100 ）,上午<br />
    还在的，不知何故，现在被删除了。<br />
    为什么？</li>
    <li class="alt"><font color="#ff0000"><font color="#000000"><font>Robbin says:</font></font></font></li>
    <li class="alt"><font color="#ff0000"><font color="#000000"><font>如果我没有记错，你写的是破解别人版权软件的内容吧？</font></font></font></li>
    </font> <br />
    </font></ol>
    </div>
    </font></font><font color="#ff0000"><br />
    感谢Robbin给我上了一课，让我认识到当技术交流跟版权保护冲突时，应当舍弃前者。<br />
    我以后不会再发涉嫌侵犯代码版权的文字。</font><br />
    <br />
    但是学习的热情不能被抹杀。<br />
    在不解密js的情况下，我们可以大致看一下人家的东西是怎么回事：<br />
    1. 在Eclipse中新建一个Tomcat工程，把js(无须解密)拷贝进去。<br />
    2. 写一个Filter, 实现doFilter方法：<br />
    <div class="dp-highlighter">
    <div class="bar">&nbsp;</div>
    <ol class="dp-j" start="1">
        <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;doFilter(&nbsp;&nbsp;</span></span></li>
        <li class=""><span>&nbsp;&nbsp;&nbsp; ServletRequest&nbsp;request,&nbsp;&nbsp;&nbsp;</span></li>
        <li class="alt"><span>&nbsp;&nbsp;&nbsp; ServletResponse&nbsp;response,&nbsp;&nbsp;</span></li>
        <li class=""><span>&nbsp;&nbsp;&nbsp; FilterChain&nbsp;filterChain)&nbsp;<span class="keyword">throws</span><span>&nbsp;IOException,&nbsp;ServletException&nbsp;{&nbsp;&nbsp;</span></span></li>
        <li class="alt"><span>&nbsp;&nbsp;&nbsp; <span class="keyword">try</span><span>&nbsp;{&nbsp;&nbsp;</span></span></li>
        <li class=""><span>&nbsp; &nbsp; &nbsp; &nbsp; HttpServletRequest&nbsp;req&nbsp;=&nbsp;(HttpServletRequest)&nbsp;request;&nbsp;&nbsp;</span></li>
        <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String&nbsp;requestUri&nbsp;=&nbsp;req.getRequestURI();&nbsp;&nbsp;</span></li>
        <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(<span class="string">&quot;RequestURI:&nbsp;&quot;</span><span>&nbsp;+&nbsp;requestUri);&nbsp;&nbsp;</span></span></li>
        <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; filterChain.doFilter(request,&nbsp;response);&nbsp; <br />
        </span></li>
        <li class="alt"><span>&nbsp;&nbsp;&nbsp; }&nbsp;<span class="keyword">catch</span><span>&nbsp;(Exception x)&nbsp;{&nbsp;&nbsp;</span></span></li>
        <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filterConfig.getServletContext().log(x.getMessage());&nbsp;&nbsp;</span></li>
        <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
        <li class=""><span>}&nbsp;&nbsp;</span></li>
    </ol>
    </div>
    这个Filter只有一个作用，就是记录RequestURI，看看后台都接收到哪些请求<br />
    3. 启动Tomcat, 在浏览器地址栏输入: http://${your_host}:${port}/${app_name_4_filespots}/index.html<br />
    4. 查看Eclipse Console, 看到<br />
    RequestURI: /Filespots.cracked/index.html<br />
    RequestURI: /Filespots.cracked/lib/filespots-deploy3.js<br />
    RequestURI: /Filespots.cracked/<strong><font color="#ff0000">JSON-RPC<br />
    &nbsp;(同时打开FF的Error Console, 我们可以看到 &ldquo;uncaught exception: JSONRpcClientException:/ Filespots.cracked/JSON-RPC&rdquo;)<br />
    </font></strong><font color="#ff0000"><font color="#000000">这告诉我们，它采用了JSON-RPC-Java.<br />
    什么是JSON-RPC-Java? 可以去http://oss.metaparadigm.com/看看，我不赘言（其实我也是今天刚看JSON-RPC-Java，不敢多说<img src="/javascripts/fckeditor/editor/images/smiley/msn/embaressed_smile.gif" alt="" />）...</font></font>
          <br/>
          <span style="color:red;">
            <a href="http://sam-ds-chen.javaeye.com/blog/141695#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 19 Nov 2007 14:17:38 +0800</pubDate>
        <link>http://sam-ds-chen.javaeye.com/blog/141695</link>
        <guid>http://sam-ds-chen.javaeye.com/blog/141695</guid>
      </item>
      <item>
        <title>Venkman -- js调试工具</title>
        <author>sam.ds.chen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sam-ds-chen.javaeye.com">sam.ds.chen</a>&nbsp;
          链接：<a href="http://sam-ds-chen.javaeye.com/blog/127597" style="color:red;">http://sam-ds-chen.javaeye.com/blog/127597</a>&nbsp;
          发表时间: 2007年09月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <br />
工具名称: Venkman<br />
下载地址: www.mozilla.org/projects/venkman/<br />
作者: Robert Ginda<br />
[quote]<br />
&nbsp;Venkman is based on the Mozilla JavaScript debugging<br />
API known as js/jsd. The js/jsd API formed the basis of the Netscape JavaScript Debugger 1.1<br />
that was available for the 4.x series of Netscape browsers.<br />
Once you&rsquo;ve installed it, you can start Venkman from the Tools ➤ JavaScript Debugger<br />
menu item from within Firefox. Figure 2-17 shows the default layout for Venkman.<br />
Venkman offers a plethora of information, divided into eight panes. The default layout<br />
consists of a large pane showing the selected source code. Smaller panes are arranged<br />
vertically on the left side of the window. Venkman&rsquo;s command-line interface resides on<br />
the bottom of the window under the Source Code pane.<br />
You can drag each pane with the mouse and dock them at other locations within the<br />
main window. You can also add each pane as a separate tab to an existing pane. For<br />
example, referring to Figure 2-17, to make the Loaded Scripts tab exist within the Local<br />
Variables pane, drag and drop the Loaded Scripts tab to the Local Variables tab. You can<br />
also undock the panes from the main window by clicking the docking button located on<br />
the left side of the pane&rsquo;s title bar. Docking the pane back to the main window is as easy as<br />
clicking the docking button again.<br />
As you work with Venkman, you&rsquo;ll get a feel for the panes that you use most often. Close<br />
the panes you don&rsquo;t often use by clicking the X button on the right side of the pane&rsquo;s title<br />
bar. You can reopen panes by selecting View ➤ Show/Hide. If at any time you want to<br />
return the pane layout to the default setting, enter &ldquo;/restore-layout factory&rdquo; at the commandline<br />
interface in the Interactive Session pane.<br />
[/quote]<br />
<br />
-- 摘自<em>Apress Pro Ajax and Java Frameworks</em>
          <br/>
          <span style="color:red;">
            <a href="http://sam-ds-chen.javaeye.com/blog/127597#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 27 Sep 2007 14:41:55 +0800</pubDate>
        <link>http://sam-ds-chen.javaeye.com/blog/127597</link>
        <guid>http://sam-ds-chen.javaeye.com/blog/127597</guid>
      </item>
      <item>
        <title>嵌在web app中的Quartz突然启动不了了</title>
        <author>sam.ds.chen</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sam-ds-chen.javaeye.com">sam.ds.chen</a>&nbsp;
          链接：<a href="http://sam-ds-chen.javaeye.com/blog/125686" style="color:red;">http://sam-ds-chen.javaeye.com/blog/125686</a>&nbsp;
          发表时间: 2007年09月20日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          两个多月前,在部署于远程服务器上的Tomcat中的web app中嵌入了Quartz,让它每周日00:00:00执行一个Job,生成一个报表并通过Email发送给指定的收件人.连续几个星期下来,一切正常.而且每次我重启Tomcat后,在log中都有关于Quartz的记录:<br />
[code]<br />
...<br />
Sep 13, 2007 2:26:23 AM org.apache.coyote.http11.Http11Protocol destroy<br />
INFO: Stopping Coyote HTTP/1.1 on http-8080<br />
2007-09-13 02:26:23,872 DEBUG SimpleThreadPool:564 - WorkerThread is shutting down<br />
2007-09-13 02:26:23,873 DEBUG SimpleThreadPool:564 - WorkerThread is shutting down<br />
2007-09-13 02:26:23,873 DEBUG SimpleThreadPool:564 - WorkerThread is shutting down<br />
2007-09-13 02:26:23,874 DEBUG SimpleThreadPool:564 - WorkerThread is shutting down<br />
2007-09-13 02:26:23,874 DEBUG SimpleThreadPool:564 - WorkerThread is shutting down<br />
2007-09-13 02:26:23,912  INFO ShutdownHookPlugin:133 - Shutting down Quartz...<br />
2007-09-13 02:26:23,913  INFO ShutdownHookPlugin:133 - Shutting down Quartz...<br />
Sep 13, 2007 2:26:29 AM org.apache.coyote.http11.Http11Protocol init<br />
INFO: Initializing Coyote HTTP/1.1 on http-8080<br />
Sep 13, 2007 2:26:29 AM org.apache.catalina.startup.Catalina load<br />
INFO: Initialization processed in 863 ms<br />
Sep 13, 2007 2:26:30 AM org.apache.catalina.core.StandardService start<br />
INFO: Starting service Catalina<br />
...<br />
2007-09-13 02:26:32,483 DEBUG ConvertUtils:418 - Convert string '20' to class 'int'<br />
2007-09-13 02:26:32,484 DEBUG ConvertUtils:426 -   Using converter org.apache.commons.beanutils.converters.Integ<br />
erConverter@1ce85c4<br />
2007-09-13 02:26:32,485 DEBUG ManagerBase:627 - Registering Catalina:type=Manager,path=/,host=localhost<br />
2007-09-13 02:26:32,486 DEBUG ManagerBase:650 - Force random number initialization starting<br />
2007-09-13 02:26:32,487 DEBUG ManagerBase:511 - Opening /dev/urandom<br />
2007-09-13 02:26:32,488 DEBUG ManagerBase:322 - Getting message digest component for algorithm MD5<br />
2007-09-13 02:26:32,489 DEBUG ManagerBase:336 - Completed getting message digest component<br />
2007-09-13 02:26:32,491 DEBUG ManagerBase:339 - getDigest() 3<br />
2007-09-13 02:26:32,492 DEBUG ManagerBase:653 - Force random number initialization completed<br />
2007-09-13 02:26:32,493 DEBUG ManagerBase:359 - Start: Loading persisted sessions<br />
2007-09-13 02:26:32,494 DEBUG ManagerBase:369 - Loading persisted sessions from SESSIONS.ser<br />
2007-09-13 02:26:32,495 DEBUG ManagerBase:383 - Creating custom object input stream for class loader<br />
2007-09-13 02:26:32,497 DEBUG ManagerBase:413 - Loading 4 persisted sessions<br />
2007-09-13 02:26:32,508 DEBUG ManagerBase:460 - Finish: Loading persisted sessions<br />
2007-09-13 02:26:32,642  INFO QuartzScheduler:209 - Quartz Scheduler v.1.6.0 created.<br />
2007-09-13 02:26:32,647  INFO JobInitializationPlugin:280 - Registering Quartz Job Initialization Plug-in.<br />
2007-09-13 02:26:32,650  INFO ShutdownHookPlugin:128 - Registering Quartz shutdown hook.<br />
2007-09-13 02:26:32,652  INFO RAMJobStore:141 - RAMJobStore initialized.<br />
2007-09-13 02:26:32,653  INFO StdSchedulerFactory:1208 - Quartz scheduler 'TestScheduler' initialized from defau<br />
lt resource file in Quartz package: 'quartz.properties'<br />
2007-09-13 02:26:32,654  INFO StdSchedulerFactory:1212 - Quartz scheduler version: 1.6.0<br />
...<br />
[/code]<br />
可是最近发现Job没有执行,而且启动日志中也没有上述信息了(Tomcat会经常被我重启).<br />
更奇怪的是,本地的开发环境中Job可以正常执行,log中也有记录.代码和配置我都比较过,完全一致.<br />
<br />
我试着在web.xml中把QuartzInitializer的启动延迟<br />
<servlet>[code]<br />
&lt;servlet&gt;<br />
</servlet>&lt;<servlet>servlet-name</servlet>&gt;<servlet>QuartzInitializer</servlet>&lt;<servlet>/servlet-name</servlet>&gt;<br />
<servlet>       </servlet>&lt;<servlet>servlet-class</servlet>&gt;<br />
<servlet>           org.quartz.ee.servlet.QuartzInitializerServlet<br />
</servlet>&lt;<servlet>/servlet-class</servlet>&gt;<br />
<servlet>       </servlet>&lt;<servlet>load-on-startup</servlet>&gt;<servlet>2</servlet>&lt;<servlet>/load-on-startup</servlet>&gt;<br />
&lt;<servlet>/servlet</servlet>&gt;<br />
[/code]<br />
本地仍然可以,可是远程还是不行.<br />
难道是我重启远程Tomcat的次数太多,导致Quartz启动不了了?<br />
可是关闭Tomcat的时候Quartz会做清理工作的呀:<br />
[code]<br />
INFO: Stopping Coyote HTTP/1.1 on http-8080<br />
2007-09-14 03:45:24,186  INFO ShutdownHookPlugin:133 - Shutting down Quartz...<br />
...<br />
[/code]<br />
有没有人遇到过类似的问题啊?
          <br/>
          <span style="color:red;">
            <a href="http://sam-ds-chen.javaeye.com/blog/125686#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 20 Sep 2007 16:39:15 +0800</pubDate>
        <link>http://sam-ds-chen.javaeye.com/blog/125686</link>
        <guid>http://sam-ds-chen.javaeye.com/blog/125686</guid>
      </item>
  </channel>
</rss>