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並優先處理請求的機會。

        要完成這個工做,咱們須要實現三個類; java

        第一個類是新建一個繼承自VaadinServlet的類,咱們給它命名JsWrapServlet(因咱們這裏只處理js文件),並把它代替VaadinServlet配置到web.xml中。 web

         第二個類是繼承自VaadinServletService的類JSFileService,這個類主要用於把第三個類js文件請求處理器註冊到requestHandlers。

       第三個類JSFileHandler繼承自RequestHandler,主要是在第一時間攔截特定格式js文件請求並處理。 服務器

代碼片斷: session

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 {
        //略
        
    }
 
}
相關文章
相關標籤/搜索