簡體   English   中英

Angular 與 Spring 引導 static 不工作

[英]Angular with Spring boot static does not work

我有一個 spring 啟動應用程序,其中包含一個 angular 前面

像這樣:

src/main/resources/static/zanori2

在 zanori2 中,我得到了ng build的結果,例如:

index.html、index.js、favico.ico 等

我試過這個資源句柄:

@Configuration
@EnableWebMvc
public class WebMvcConfig implements WebMvcConfigurer {
    /*@Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {*/
        //registry.addResourceHandler("/**/*")
        /*.addResourceLocations("classpath:/static/zanori2/")
        .resourceChain(true)
        .addResolver(new PathResourceResolver() {
            @Override
            protected Resource getResource(String resourcePath,
                Resource location) throws IOException {
                Resource requestedResource = location.createRelative(resourcePath);
                return requestedResource.exists() && requestedResource.isReadable() ? requestedResource
                : new ClassPathResource("/static/zanori2/index.html");
            }
        });
    }
}

但是,當我將 go 發送到: localhost:8080/zanori2/index.html時,它會將我返回到localhost:8080並且 js 文件有效。

然而,這很奇怪,因為我不允許共享 url,因為如果我將 go 直接發送到 localhost:8080,我會得到一個未找到的頁面。

並使用其他配置:

@Configuration
@EnableWebMvc
public class WebMvcConfig implements WebMvcConfigurer {

    @Autowired
    private Environment env;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

        /* Caching strategy */
        boolean prodMode = Arrays.asList(env.getActiveProfiles()).contains("pro");
        Integer cachePeriod = prodMode ? null : 0;
        boolean useResourceCache = prodMode;

        VersionResourceResolver versionResourceResolver = new VersionResourceResolver();
        versionResourceResolver.addContentVersionStrategy("/**/*.js", "/**/*.css");
        AppCacheManifestTransformer transformer = new AppCacheManifestTransformer();

        /* robots.txt */
        registry.addResourceHandler("/robots.txt")
                .addResourceLocations("classpath:/static/robots.txt");

        /* All other resources */
        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:/static/zanori2")
                .setCachePeriod(cachePeriod)
                .resourceChain(useResourceCache)
                .addResolver(versionResourceResolver)
                .addTransformer(transformer);
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        /* Make sure Thymeleaf views are not accessible directly as static resources */
        registry.addRedirectViewController("/app/*.html", "/");
        /* Default mapping */
        registry.addRedirectViewController("/", "/app/index.html");
        /* Application entry */
        registry.addViewController("/app/index.html").setViewName("index");
    }
}

我 go 到localhost:8080/zanori2/index.html並且我保留在同一個 url 但是我的 js 文件找不到所以也不起作用。

我沒有找到任何正常工作的例子。

問題示例: 在此處輸入圖像描述

static資產映射

Spring 將自動在多個位置搜索與 web 配置中的任何控制器或其他設置不匹配的路徑。 這些位置當前默認選中:

classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public/

您可以通過設置

spring.web.resources.static-locations

應用程序屬性。

從一個干凈的項目開始並添加:

spring.web.resources.static-locations=classpath:/static/zanori2/

到您的application.properties將使 Spring 搜索 static 資源的預期路徑。

將單頁前端中的路徑映射到/

請記住,在下面的所有內容中,到 static 資產的映射已被上面更改,因此在下面,路徑/a/b將真正獲取/static/zanori2/a/b 另請記住,Spring controller 將始終優先於 static 資產,因此如果您定義 Spring controller 干擾 static 路徑,它將被使用。

如果您還支持具有內部路由的單頁前端,則需要向WebMvcConfigurer添加一些配置。 訣竅是仍然從其真實位置加載所有 static 內容,但將單頁應用程序內的所有路徑轉發到/ 假設應用程序內的路徑永遠不會有一個以句點 (.) 開頭的文件后綴,通常來自后端的所有真實 static 文件都有,這可以通過向WebMvcConfigurer添加一些內容來完成。

添加取決於SpringMVC 中使用哪種模式匹配

路徑模式匹配

使用路徑模式匹配(這是最新 Spring Boot 中的新默認值):

@Override
public void addViewControllers(ViewControllerRegistry registry) {
    registry
        .addViewController("/{path1:[\\w]+}")
        .setViewName("forward:/")
    registry
        .addViewController("/{path1}/{path2:[\\w]+}")
        .setViewName("forward:/")
    registry
        .addViewController("/{path1}/{path2}/{path3:[\\w]+}")
        .setViewName("forward:/")
}

對於路徑模式匹配,沒有簡單的方法可以針對任意數量的路徑級別執行此操作,因此您必須為前端內部路徑應支持的每個嵌套級別添加這些語句之一。 這是因為路徑模式只允許在模式末尾匹配多個路徑級別 ( ** )。

以上最多支持三級所以在瀏覽器地址欄直接輸入時:

/
/* / is served */

/a 
/* / is served which can then route internally to /a */

/a/b 
/* / is served which can then route internally to /a/b */

/a/b/c 
/* / is served which can then route internally to /a/b/c */

/a/b/c/d
/* will NOT work, tries to serve actual /a/b/c/d */

/a/b/c.txt 
/* / will NOT work, tries to serve actual /a/b/c.txt since contains a period */

這里發生了什么? 如前所述,這些是您可以在此處閱讀的路徑模式:

  • 每個{pathX}匹配一個路徑段並將路徑存儲在變量pathX (我們不關心)。
  • 每個變量在其匹配模式中必須具有唯一的名稱。
  • 在最后一個路徑段中,我們匹配一個非空的數字、字母和下划線序列。 如果需要,您可以修改此正則表達式,但您可以執行的操作非常受限。 目標是不匹配任何帶有句點的路徑,因為這些可能是真實的 static 文件。
  • 還有其他有用的路徑模式,但它們可能不會與我們最終的正則表達式模式結合使用。

Ant 模式匹配

對於ant 模式匹配,它曾經是默認的,適用類似的規則,但有一些不同。 路徑模式匹配通常更有效,但如前所述,它不允許您在最后的其他地方匹配任意數量的路徑級別 ( ** )。

加上ant模式匹配,前面的config可以簡化為

@Override
public void addViewControllers(ViewControllerRegistry registry) {
    registry
        .addViewController("/**/{path:[\\w]+}")
        .setViewName("forward:/")
}

現在,我們在最后一條路徑之前匹配任意數量的路徑級別,產生以下結果:

/
/* / is served */

/a 
/* / is served which can then route internally to /a */

/a/b 
/* / is served which can then route internally to /a/b */

/a/b/c 
/* / is served which can then route internally to /a/b/c */

/a/b/c/d
/* / is served which can then route internally to /a/b/c/d */

/a/b/c.txt 
/* / will NOT work, tries to serve actual /a/b/c.txt since contains a period */

因此,根據您在應用程序 rest 中的需求,我會選擇其中一種解決方案,最好是具有 ant 模式的解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM