2017-07-24 29 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