Vaadin 7使用外部js库时组织js文件路径的一个方法

     Vaddin 7中要整合外部的js库(或者js组件)必须使用@JavaScript标签来指定要加载的js文件,并且继承AbstractJavaScriptComponent这样的抽象类;这时候的js文件必须放在类路径下,或者使用全限定名路径一般可以是CDN的路径。
      如果是本服务器的相对路径,客户端在请求时会加上APP/PUBLISHED/的前缀,这样服务端在解析时总是去掉前缀后在类路径下找js文件。 这种形式非常不方便,有时候同样的类库因为用在了不同的地方(定义了不同package下的component)就需要在不同的package路径下方多分js代码副本,另一方面,js代码放在类路径下也极为不易管理。
       如果直接使用全限定路径,例如在@JavaScript指定http://host/address这样,则适应性不广,因为@JavaScript无法在部署时修改,必须为不同主机地址重新编译;在一些没有DNS的局域网中,更是要为不同ip地址重新编译;在不能访问外网的局域网中,CDN也无法起作用。
        所以,最好的办法是想办法使得系统在请求js代码时能够鉴别出静态js文件的请求,并定位到统一存储的静态路径。 经过阅读vaddin 7.1.0的代码,我们可以发现VaadinServlet有一个注册服务模块的protected方法createServletService。在这个方法中,会用deploymentConfiguration为参数new一个VaadinServletService对象,并调用init()。deploymentConfiguration主要被VaadinServletService的基类VaadinService用于初始化一些配置。
        重头在init方法中,在这个方法中基类VaadinService调用createRequestHandlers创建了一个服务请求处理器列表,并且按加入列表顺序的倒序来初始化成员变量requestHandlers(一个Iterable)。也就是说,越晚加入到列表中的服务将会越早被调用来处理请求。这样就给了我我们一个把我们自己的服务请求处理器加入到requestHandlers并优先处理请求的机会。

        要完成这个工作,我们需要实现三个类;

        第一个类是新建一个继承自VaadinServlet的类,我们给它命名JsWrapServlet(因我们这里只处理js文件),并把它代替VaadinServlet配置到web.xml中。

         第二个类是继承自VaadinServletService的类JSFileService,这个类主要用于把第三个类js文件请求处理器注册到requestHandlers。

       第三个类JSFileHandler继承自RequestHandler,主要是在第一时间拦截特定格式js文件请求并处理。

代码片段:

public class JsWrapServlet extends VaadinServlet {
…
@Override
    protected VaadinServletService createServletService(DeploymentConfiguration deploymentConfiguration) throws ServiceException
    {
    	VaadinServletService service = new JSFileService(this,
                deploymentConfiguration);
        service.init();
		return service;
	}
…
}
public class JSFileService extends VaadinServletService {

	public JSFileService(VaadinServlet servlet,
			DeploymentConfiguration deploymentConfiguration)
			throws ServiceException {
		super(servlet, deploymentConfiguration);
	}

	/* (non-Javadoc)
	 * @see com.vaadin.server.VaadinServletService#createRequestHandlers()
	 */
	@Override
	protected List<RequestHandler> createRequestHandlers()
			throws ServiceException {
		 List<RequestHandler> handlers = super.createRequestHandlers();
		 handlers.add(new JSFileHandler());
		 return handlers;
	}
}
public class JSFileHandler implements RequestHandler {


 /* (non-Javadoc)
 * @see com.vaadin.server.RequestHandler#handleRequest(com.vaadin.server.VaadinSession, com.vaadin.server.VaadinRequest, com.vaadin.server.VaadinResponse)
 */
 @Override
 public boolean handleRequest(VaadinSession session, VaadinRequest request,
 VaadinResponse response) throws IOException {
 //判断是否特定的路径标识,我们把js文件放在了/VAADIN/static 
if ( !hasPathPrefix(request, ApplicationConstants.PUBLISHED_FILE_PATH
                + "/VAADIN/static/")){
 return false;
 }
 String pathInfo = request.getPathInfo();
 String fileName = pathInfo
                .substring(ApplicationConstants.PUBLISHED_FILE_PATH.length() + 2);
        
     // 找到服务端路径
        String basepath = VaadinService.getCurrent()
                          .getBaseDirectory().getAbsolutePath();


        FileResource resource = new FileResource(new File(basepath +"/"+ fileName));
        writeResponse(response,resource.getStream()); //写入响应
        return true;
 }
 
 /**
 * 复制自 {@link com.vaadin.server.DownloadStream#writeResponse}
 * @param data
 * @throws IOException
 */
 private void writeResponse(VaadinResponse response,DownloadStream ds)
            throws IOException {
        //略
        
    }
 
}

你可能感兴趣的:(JavaScript,component,vaddin)