복붙노트

[SPRING] vaadin과 함께 스프링 부트를 사용할 때 js 파일 용 404

SPRING

vaadin과 함께 스프링 부트를 사용할 때 js 파일 용 404

spring-boot로 vaadin 프로젝트에서 스프링 보안을 사용할 때 문제가 있습니다. 그래서 PDF 파일을 표시하기 위해 PdfViewer Addon을 사용합니다. 하지만 다음과 같은 오류 메시지가 나타납니다.

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/**");
    }

따라서 크롬에서로드 된 파일을 확인하면 / vaadinServlet / APP / PUBLISHED / 폴더가 있고 필요한 모든 파일이 있습니다.

스프링 보안없이 애드온을 사용하면 아무 문제가 없으므로 잘 작동합니까?

최신 정보

새로운 간단한 프로젝트에서 Addon을 테스트하는 동안 유사한 동작을하기 때문에 봄 보안과 관련이없는 것 같습니다. 봄 부츠에 문제가있는 것 같습니다.

이 문제를 재현하려면 (전체 프로젝트 다운로드 필요) :

@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);
    }
}

해결법

  1. ==============================

    1.TL; DR; 번역:

    TL; DR; 번역:

    두 번째 요청이 pdf.js에 의해 pdf.worker.js를 다운로드하도록 트리거되지만 자동 구성된 VaadinServlet에서 처리하는 /vaadinServlet/APP/PUBLISHED/pdf.worker.js 경로와 일치하지 않습니다. 단지 / 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;
        }
    }
    

    상세 버전 :

    그래서, 나는 이것을 디버깅하는데 약간의 시간을 할애했고, 불행한 설정의 조합으로 판명되었다.

    무슨 일이 벌어지면, Spring은 / *에 대한 요청을 처리하는 DispatcherServlet을 등록합니다. Vaadin은 / vaadinServlet / * 및 / VAADIN 경로에 대해 VaadinSpringServlet을 등록합니다.

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

    Dispatcher 서블릿과 공존하고 "/ *"에 대한 요청을 처리 할 수 ​​있도록 Vaadin은 UI 경로에 대한 전달 컨트롤러도 등록합니다. 예를 들어, / MyUI에 대한 요청은 / vaadinServlet / MyUI로 전달됩니다 (자세한 내용은 VaadinServletConfiguration 소스 참조).

    지금까지 모든 것이 잘 작동하고 문제가 없어야합니다. 당신이 말했듯이, 크롬 dev-tools를 보면 모든 js 파일이 있습니다. 그래서 무엇이 잘못 되었습니까? 앱에 액세스 할 때 요청한 내용을 살펴보면 실제로 pdf.worker.js에 대한 두 가지 요청 (첫 번째는 성공)과 404 :

    실패한 호출의 Initiator 열은 실제로 pdf.js : 2344이며 중단 점을 설정하면 pl.pdfviewer에 정의 된 workerSrc = / APP / PUBLISHED / pdf.worker.js 값을 실제로 볼 수 있습니다. 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);
            });
        }
    
    }-*/;
    

    정규 Vaadin 환경에서 /APP/PUBLISHED/pdf.worker.js는 즉시 사용할 수 있지만 약간 수정되었으므로 약간의 조정이 필요합니다. 결론적으로 우리는 Vaadin 자동 구성이 수행하는 것과 유사한 접근법을 사용할 수 있으며 /APP/PUBLISHED/pdf.worker.js 요청을 /vaadinServlet/APP/PUBLISHED/pdf.worker.js로 리디렉션하고 마지막으로이 문제를 해결할 수 있습니다 . 간결함을 위해이 게시물의 시작 부분에 리디렉션 컨트롤러가 표시됩니다.

  2. from https://stackoverflow.com/questions/45288885/404-for-js-files-when-using-spring-boot-with-vaadin by cc-by-sa and MIT license