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

 在dwr.xml中有,<creator>标签负责公开用于Web远程的类和类的方法,实际上最后调用的就是本包下面的script创建类。
creator类型在1.1版本的时候有如下几种,现在是3.0版本了,我查了下源码,种类好像比下面要多(查XXXCreator有多少个)。
    new: 用Java的new关键字创造对象。 
    none: 它不创建对象,看下面的原因。 (v1.1+) 
    scripted: 通过BSF使用脚本语言创建对象,例如BeanShell或Groovy。 
    spring: 通过Spring框架访问Bean。 
    jsf: 使用JSF的Bean。 (v1.1+) 
    struts: 使用Struts的FormBean。 (v1.1+) 
    pageflow: 访问Beehive或Weblogic的PageFlow。 (v1.1+) 
   
    creator是在什么时候调用的呢?
     实际上,在Serlvet加载的时候有个doPost方法,doPost方法调用handle,handle再调用 remotor,remotor最终调用相应的creator,比如NewCreator,creator实际上是执行创建script字符串的工作。
     举例来说,我们想在html中某个地方直接显示当前时间的long值,那么我们就可以调用java.util.Date类的getTime()方法。dwr.xml中写法如下:

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

 

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

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

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


才会触发下面

protected   void  doGet(HttpServletRequest req, HttpServletResponse resp)  throws  IOException, ServletException
    
{
        doPost(req, resp);
    }


doGet会调用到doPost

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

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

        
finally
        
{
            webContextBuilder.unset();
        }

    }

  在proccessor中我们看到如下代码

  public   void  handle(HttpServletRequest request, HttpServletResponse response)  throws  IOException
    
{
        
try
        
{
            String pathInfo 
= request.getPathInfo();
            contextPath 
= request.getContextPath();

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

            
else
            
{
                
// Loop through all the known URLs
                for (Entry<String, Object> entry : urlMapping.entrySet())
                
{
                    String url 
= entry.getKey();

                    
// If this URL matches, call the handler
                    if (pathInfo.startsWith(url))
                    
{
                        Handler handler 
= (Handler) entry.getValue();
                        handler.handle(request, response);
                        
return;
                    }

                }


                notFoundHandler.handle(request, response);
            }

        }

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

    }

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

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

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

     protected  String generateTemplate(HttpServletRequest request, HttpServletResponse response)  throws  IOException
    
{
        String scriptName 
= request.getPathInfo();
        scriptName 
= scriptName.replace(interfaceHandlerUrl, "");

        String contextServletPath 
= request.getContextPath() + request.getServletPath();

        
if (scriptName.endsWith(PathConstants.EXTENSION_JS))
        
{
            scriptName 
= scriptName.replace(PathConstants.EXTENSION_JS, "");
            
if (!LocalUtil.isJavaIdentifier(scriptName))
            
{
                log.debug(
"Throwing at request for script with name: '" + scriptName + "'");
                
throw new SecurityException("Script names may only contain Java Identifiers");
            }


            
return remoter.generateInterfaceScript(scriptName, contextServletPath);
        }

        
else if (scriptName.endsWith(PathConstants.EXTENSION_SDOC))
        
{
            scriptName 
= scriptName.replace(PathConstants.EXTENSION_SDOC, "");
            
if (!LocalUtil.isJavaIdentifier(scriptName))
            
{
                log.debug(
"Throwing at request for script with name: '" + scriptName + "'");
                
throw new SecurityException("Script names may only contain Java Identifiers");
            }


            
return remoter.generateInterfaceSDoc(scriptName, contextServletPath);
        }

        
else
        
{
            log.debug(
"Throwing at request for script with unknown extension: '" + scriptName + "'");
            
throw new SecurityException("Unknown extension");
        }

    }

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

protected  String generateCachableContent(HttpServletRequest request, HttpServletResponse response)  throws  IOException
    
{
        String output 
= super.generateCachableContent(request, response);

        
if (debug || compressor == null)
        
{
            
return output;
        }


        
try
        
{
            
return compressor.compressJavaScript(output);
        }

        
catch (Exception ex)
        
{
            log.warn(
"Compression system (" + compressor.getClass().getSimpleName() +") failed to compress script", ex);
            
return output;
        }

    }


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

     protected  String generateCachableContent(HttpServletRequest request, HttpServletResponse response)  throws  IOException
    
{
        String template 
= generateTemplate(request, response);

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

            }

        }


        
return template;
    }


    
/**
     * Generate a template to undergo search and replace processing according to
     * the search and replace pairs from {
@link #getSearchReplacePairs()}.
     * 
@param request The HTTP request data
     * 
@param response Where we write the HTTP response data
     * 
@return A template string containing ${} sections to be replaced
     
*/

    
protected   abstract  String generateTemplate(HttpServletRequest request, HttpServletResponse response)  throws  IOException;


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

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


        String output;

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

            scriptCache.put(url, output);
        }


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

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值