使用vaadin的Spring Boot时的404 for js文件

Red*_*ato 4 java spring spring-security vaadin spring-boot

在带有spring-boot的vaadin项目中使用spring security时遇到问题。因此,我正在使用PdfViewer插件来显示PDF文件。但是我收到以下错误消息:

error:"Not Found"
message:"No message available"
path:"/APP/PUBLISHED/pdf.worker.js"
status:404
Run Code Online (Sandbox Code Playgroud)

我的春季安全配置如下所示:

@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/**");
    }
Run Code Online (Sandbox Code Playgroud)

因此,在Chrome浏览器中检查了已加载的文件,我看到了/ vaadinServlet / APP / PUBLISHED /文件夹,其中包含所有需要的文件。

在不使用Spring Security的情况下使用Addon可以正常工作,所以有人有想法吗?


更新资料

它似乎与Spring安全性无关,因为我在一个新的简单项目中测试Addon时得到了类似的行为。弹簧靴似乎是个问题。

要重现此问题,您需要(要下载的完整项目):

  • 基本的春季启动+ vaadin应用程序框架
  • 简单的PDF及以下 /webapp/files
  • 在pom和widgetset中编译的PdfViewer加载项
  • 下面的简单UI
error:"Not Found"
message:"No message available"
path:"/APP/PUBLISHED/pdf.worker.js"
status:404
Run Code Online (Sandbox Code Playgroud)
  • 打开chrome和开发者工具,并Network选择标签,访问该应用,您应该会看到一个pdf.worker.js失败请求。

Mor*_*fic 5

TL; DR; 版:

正在pdf.js下载触发第二个请求pdf.worker.js,但/vaadinServlet/APP/PUBLISHED/pdf.worker.js与自动配置处理的路径不匹配VaadinServlet,只是/APP/PUBLISHED/pdf.worker.js

我能想到的最简单的解决方案是请求转发到的控制器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;
    }
}
Run Code Online (Sandbox Code Playgroud)

详细版本:

因此,我花了一些时间对此进行调试,结果发现这是不幸的配置的组合:

  • Spring Dispatcher Servlet侦听
  • vaadin spring servlet侦听
  • pdf.js错误修正/解决方法

发生的是,spring注册了的DispatcherServlet投放请求/*。Vaadin VaadinSpringServlet/vaadinServlet/*/VAADIN路径注册a :

ServletRegistrationBean  : Mapping servlet: 'dispatcherServlet' to [/]
ServletRegistrationBean  : Mapping servlet: 'springVaadinServlet' to [/vaadinServlet/*, /VAADIN/*]
Run Code Online (Sandbox Code Playgroud)

为了与调度程序servlet共存并能够在“ / *”上处理请求,Vaadin还为UI路径注册了转发控制器。例如,请求/MyUI将被转发到/vaadinServlet/MyUI(有关更多详细信息,请参阅VaadinServletConfiguration)。

到目前为止,一切正常,您应该没有任何问题。就像您说的那样,看着chrome开发工具,所有js文件都在那里,那怎么了?如果您在访问应用程序时查看closley的请求,您会注意到实际上有2个请求pdf.worker.js-第一个成功,而给您404的请求:

pdf.worker.js请求

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 = instance.@pl.pdfviewer.client.ui.VPdfViewer::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);
        });
    }

}-*/;
Run Code Online (Sandbox Code Playgroud)

js调试

在常规的Vaadin环境中,/APP/PUBLISHED/pdf.worker.js可以直接使用,但我们现在的环境略有变化,因此需要进行一些调整。最重要的是,我们可以对Vaadin自动配置使用类似的方法,并将/APP/PUBLISHED/pdf.worker.js请求重定向 到/vaadinServlet/APP/PUBLISHED/pdf.worker.js,最终解决该问题。为了简洁起见,可以在本文开头看到重定向控制器。

工作PDF