2017-07-24 27 views
3

在彈簧引導的vaadin項目中使用彈簧安全性時出現問題。所以我使用一個PdfViewer插件來顯示PDF文件。但是,我發現了以下錯誤消息:404使用彈簧引導與vaadin時的js文件

error:"Not Found" 
message:"No message available" 
path:"/APP/PUBLISHED/pdf.worker.js" 
status:404 

和我的春天的安全配置是這樣的:

@Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http 
       .headers() 
       .defaultsDisabled() 
       .frameOptions().sameOrigin().and() 
       .csrf().disable() // Use Vaadin's CSRF protection 
       .authorizeRequests().antMatchers("/").permitAll() 
       .antMatchers("/vaadinServlet/HEARTBEAT/**").permitAll() 
       .antMatchers("/vaadinServlet/UIDL/**").permitAll() 
       .antMatchers("/vaadinServlet/APP/PUBLISHED/**").permitAll() 
       .antMatchers("login?debug").permitAll() 
       .antMatchers("/#!pwdreset/*").permitAll() 
       .antMatchers("/pwdreset/*").permitAll() 
       .and() 
       .authorizeRequests() 
       .and() 
       .formLogin().loginPage("/#!login").permitAll() 
       .and() 
       .logout().logoutUrl("/#!login?logout").logoutSuccessUrl("/").permitAll().and() 
       .sessionManagement().sessionFixation().newSession(); 

    } 

@Override 
    public void configure(WebSecurity web) throws Exception { 
     web.ignoring().antMatchers("/resources/**", "/VAADIN/**"); 
    } 

所以,檢查在Chrome加載的文件,我看到一個文件夾/vaadinServlet/APP/PUBLISHED/並且有所有需要的文件。

使用沒有Spring Security的插件工作正常,所以任何人有任何想法?


更新

它似乎並不涉及到Spring Security的,因爲我得到了類似的行爲,而在一個新的簡單的項目測試附加組件。這似乎是與春季啓動問題。

要重現此問題,您需要(full project for download):

  • 基本春天開機+ vaadin應用骨架
  • 簡單的PDF和下/webapp/files
  • PdfViewer add-on在你的POM和視窗元件
  • 下面編譯簡單的用戶界面
@Theme("mytheme") 
@SpringUI 
@Widgetset("org.test.AppWidgetSet") 
public class MyUI extends UI { 
    @Override 
    protected void init(VaadinRequest vaadinRequest) { 
     final VerticalLayout layout = new VerticalLayout(); 
     String basepath = VaadinService.getCurrent().getBaseDirectory().getAbsolutePath(); 
     File file = new File(basepath.concat("/files/test.pdf")); 
     if (file.exists()) { 
      PdfViewer pdfViewer = new PdfViewer(file); 
      Label info = new Label("File was found!"); 
      layout.addComponents(info, pdfViewer); 
     } else { 
      Label info = new Label("no file found!"); 
      layout.addComponent(info); 
     } 
     setContent(layout); 
    } 
} 
  • 打開鉻&開發人員工具與Network選項卡選中,訪問該應用程序,你應該看到一個請求pdf.worker.js失敗。
+0

你能提供一個[SSCCE(http://sscce.org)來重現問題了嗎?沒有什麼奇特的,只是一個最小的POM,UI,彈簧引導配置和發射器(主類)產生這個錯誤。我沒有看到你的配置有什麼問題,也許你可以將所有靜態資源路徑移動到'configure'方法中的'ignore'匹配器列表,但它不應該是一個問題。我有一個類似的設置,但我的工作正常,所以沒有重現它會很難理解(至少對我來說) – Morfic

+0

@Morfic我剛剛更新了我的問題,因爲它似乎是與春季啓動問題,它沒有與春季安全有關。雖然創建一個例子,我得到了像我的項目一樣的錯誤。可能你對如何解決這個問題有任何想法。 –

回答

1

TL; DR;版本:

第二個請求是由pdf.js觸發下載pdf.worker.js,但它不匹配由自動配置VaadinServlet處理的路徑/vaadinServlet/APP/PUBLISHED/pdf.worker.js,它只是/APP/PUBLISHED/pdf.worker.js

我能想出最簡單的方案,是一個控制器,它forwards請求到VaadinServlet

import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestMapping; 

@Controller 
public class PdfJsRedirectController { 
    private static final String WORKER_JS_INCORRECT_PATH = "/APP/PUBLISHED/pdf.worker.js"; 
    private static final String WORKER_JS_CORRECT_FORWARD_PATH = "forward:/vaadinServlet/APP/PUBLISHED/pdf.worker.js"; 

    @RequestMapping(value = WORKER_JS_INCORRECT_PATH) 
    public String forwardWorkerJsRequestToVaadin() { 
     return WORKER_JS_CORRECT_FORWARD_PATH; 
    } 
} 

詳細版本:

所以,我花了一些實時調試這個,並且它變成了不幸的配置的組合:

  • 春季調度的servlet聽
  • vaadin春天的servlet聽
  • 一個pdf.js bug修正/ woraround

什麼情況是,春季註冊了一個/*服務DispatcherServlet請求。和Vaadin寄存器用於/vaadinServlet/* & /VAADIN路徑的VaadinSpringServlet

ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/] 
ServletRegistrationBean : Mapping servlet: 'springVaadinServlet' to [/vaadinServlet/*, /VAADIN/*] 

共存與調度程序的servlet,並能夠還用作上的請求「/ *」不同,Vaadin還註冊一個轉發控制器爲UI路徑。例如/MyUI上的請求將被轉發至/vaadinServlet/MyUI(詳情請參閱VaadinServletConfiguration sources)。

到現在爲止一切正常,你不應該有任何問題。就像你說的那樣,看着chrome開發工具的所有js文件都在那裏,那麼怎麼回事?如果你提出的要求closley看,當你訪問你的應用程序,你會發現,其實有2個請求pdf.worker.js - 第一個是成功的,它給你的404的一個:

pdf.worker.js requests

失敗調用的Initiator列實際上是pdf.js:2344,如果您設置了斷點,您實際上可以看到workerSrc=/APP/PUBLISHED/pdf.worker.js,該值在pl.pdfviewer.client.ui.PdfViewer.java中定義。您可能需要水平滾動了一下,能看到的代碼,所以我下面格式化它:

public native void loadResourcePdf(String fileName, VPdfViewer instance)/*-{ 
    var pdfviewer = [email protected]::jsObject; 
    pdfviewer.work = false; 
    if ((pdfviewer.fileName == null || pdfviewer.fileName != fileName) && fileName != null) { 
     $wnd.PDFJS.disableStream = true; 
======> $wnd.PDFJS.workerSrc = 'APP/PUBLISHED/pdf.worker.js'; 
     $wnd.PDFJS.getDocument(fileName).then(function (pdf) { 
      pdfviewer.pdfFile = pdf; 
      pdfviewer.fileName = fileName; 
      pdfviewer.pageCount = pdf.numPages; 
      if (pdfviewer.pageNumber == 0 && pdf.numPages > 0) { 
       pdfviewer.pageNumber = 1; 
      } 
      pdfviewer.showPdfPage(pdfviewer.pageNumber); 
     }); 
    } 

}-*/; 

js debug

在常規Vaadin環境,/APP/PUBLISHED/pdf.worker.js將工作開箱即用,但我們現在處於稍微改變的狀態,所以我們需要進行一些調整。底線,我們可以使用類似的方法來進行Vaadin自動配置,並將/APP/PUBLISHED/pdf.worker.js請求重定向到/vaadinServlet/APP/PUBLISHED/pdf.worker.js,最後解決問題。爲了簡潔起見,重定向控制器可以在本文開頭看到。

working pdf

+0

謝謝,這有效!我沒有看看來源。我將爲插件創建者創建一個問題。 –

+0

@RedGato沒問題。沒有時間進一步調查,但我不確定他是否能做些什麼。如果可以動態確定路徑,那麼我們可以修復,否則我們仍然需要依靠此解決方法。儘管如此,如果你確實打開了這個問題,請確保添加一個鏈接到這個問題以供參考。乾杯 – Morfic