私は、クライアント側のルーティングに反応ルーターを使用する、反応ベースの単一ページアプリケーション用のスプリングバックエンドを開発しています。
Index.htmlページの他に、バックエンドはパス/api/**
でデータを提供します。
アプリケーションのルートパスsrc/main/resources/public/index.html
上の/
からindex.htmlを提供するために、リソースハンドラーを追加しました
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/").addResourceLocations("/index.html");
}
私がしたいのは、他のルートが一致しないときは常にindex.htmlページを提供することです。 /api
以外のパスを呼び出すとき。
このようなキャッチオールルートを春に設定するにはどうすればよいですか?
私の反応アプリはルートを前方ターゲットとして使用できるため、これは私のために機能しました
@Configuration
public class WebConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/{spring:\\w+}")
.setViewName("forward:/");
registry.addViewController("/**/{spring:\\w+}")
.setViewName("forward:/");
registry.addViewController("/{spring:\\w+}/**{spring:?!(\\.js|\\.css)$}")
.setViewName("forward:/");
}
}
正直に言うと、無限の転送ループを回避するために、この特定の形式にする必要がある理由はわかりません。
Spring Bootアプリ内でホストされるPolymerベースのPWAに加えて、画像などの静的Webリソース、および「/ api/...」の下のREST APIがあります。クライアント側のアプリでPWAのURLルーティングを処理する必要があります。私が使用するものは次のとおりです。
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
/**
* Ensure client-side paths redirect to index.html because client handles routing. NOTE: Do NOT use @EnableWebMvc or it will break this.
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// Map "/"
registry.addViewController("/")
.setViewName("forward:/index.html");
// Map "/Word", "/Word/word", and "/Word/word/Word" - except for anything starting with "/api/..." or ending with
// a file extension like ".js" - to index.html. By doing this, the client receives and routes the url. It also
// allows client-side URLs to be bookmarked.
// Single directory level - no need to exclude "api"
registry.addViewController("/{x:[\\w\\-]+}")
.setViewName("forward:/index.html");
// Multi-level directory path, need to exclude "api" on the first part of the path
registry.addViewController("/{x:^(?!api$).*$}/**/{y:[\\w\\-]+}")
.setViewName("forward:/index.html");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("classpath:/webapp/");
}
}
これは、AngularおよびReactアプリでも機能するはずです。
@ EnableWebMvcを避ける
デフォルトでは、Spring-Bootはsrc/main/resources
の静的コンテンツを提供します。
または@EnableWebMvcを保持してaddViewControllersをオーバーライドします
@EnableWebMvc
を指定しましたか? Java Spring Boot:アプリのルート(「/」)をindex.htmlにマップする方法?
@EnableWebMvcを削除するか、addViewControllers
を再定義できます。
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("forward:/index.html");
}
または、/
をキャッチするコントローラーを定義します
あなたはこれを見ることができます githubのspring-boot-reactjsサンプルプロジェクト :
コントローラーを使用して必要なことを行います。
@Controller
public class HomeController {
@RequestMapping(value = "/")
public String index() {
return "index";
}
}
そのindex.html
はsrc/main/resources/templates
の下にあります
私は私のスプリングブートアプリで反応および反応ルーターを使用し、/
および/users/**
のような私のウェブサイトのサブツリーへのマッピングを持つコントローラーを作成するのと同じくらい簡単でした
@Controller
public class SinglePageAppController {
@RequestMapping(value = {"/", "/users/**", "/campaigns/**"})
public String index() {
return "index";
}
}
API呼び出しはこのコントローラーによってキャッチされず、リソースは自動的に処理されます。
この質問 を見て答えを見つけました
@Bean
public EmbeddedServletContainerCustomizer notFoundCustomizer() {
return new EmbeddedServletContainerCustomizer() {
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/"));
}
};
}
すべての場合にシングルページアプリ(SPA)を提供する特定の質問に答えるにはexcept/ api ここでのルートは、ペトリの答えを修正するために私がしたことです。
SPAのindex.htmlを含むpolymerという名前のテンプレートがあります。そのため、チャレンジは/ apiと/ public-apiを除くすべてのルートをそのビューに転送することになりました。
WebMvcConfigurerAdapterでは、addViewControllersをオーバーライドし、正規表現を使用しました:^((?!/ api/|/public-api /).)*$
あなたの場合、正規表現が必要です:^((?!/ api /).)*$
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/{spring:^((?!/api/).)*$}").setViewName("polymer");
super.addViewControllers(registry);
}
これにより、 http:// localhost または http:// localhost/community をヒットして、SPAと、SPAが行う残りのすべての呼び出しを処理できます。 http:// localhost/api/posts 、 http:// localhost/public-api/posts などに正常にルーティングされました.