これは簡単な質問だと思いますが、答えが見つからなかったか、少なくとも検索で正しい用語を使用できませんでした。
Angular2
とSpringboot
を一緒に設定しています。デフォルトでは、Angular
はlocalhost:8080\dashboard
やlocalhost:8080\dashboard\detail
などのパスを使用します。
可能であれば、パスをハッシュとして使用しないようにしたいと思います。 As Angular documentation 状態:
ルーターのprovideRouter関数は、LocationStrategyをPathLocationStrategyに設定し、デフォルトの戦略にします。必要に応じて、ブートストラップ処理中にオーバーライドを使用してHashLocationStrategyに切り替えることができます。
その後...
ほとんどすべてのAngular 2プロジェクトは、デフォルトのHTML 5スタイルを使用する必要があります。ユーザーが理解しやすいURLを生成します。
問題は、localhost:8080\dashboard
にアクセスしようとすると、Springはこのパスへのコントローラーマッピングを検索することですが、これはありません。
Whitelabel Error Page
There was an unexpected error (type=Not Found, status=404).
No message available
最初は、すべてのサービスをlocalhost:8080\api
の下に、静的をすべてlocalhost:8080\app
の下に置くと考えました。しかし、このapp
パスへのリクエストを無視するようにSpringに指示するにはどうすればよいですか?
Angular2またはBootのいずれかでより良いソリューションはありますか?
私はあなたのための解決策を持っています、あなたはSpringブートからAngular=にリクエストを転送するためにViewController
を追加することができます.
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class ViewController {
@RequestMapping({ "/bikes", "/milages", "/gallery", "/tracks", "/tracks/{id:\\w+}", "/location", "/about", "/tests","/tests/new","/tests/**","/questions","/answers" })
public String index() {
return "forward:/index.html";
}
}
ここで、すべてのangle2( "/ bikes"、 "/ milages"、 "/ gallery"、 "/ tracks"、 "/ tracks/{id:\ w +}"、 "/ location"、 "/ about"、 「/ tests」、「/ tests/new」、「/ tests/**」、「/ questions」、「/ answers」)をSPAに送信します。前の手順でも同じことができ、404エラーページもリダイレクトできますさらなるステップとしてインデックスページに。楽しい!
カスタムErrorViewResolverを提供することにより、見つからないすべてのリソースをメインページに転送できます。必要なのは、これを@Configurationクラスに追加することだけです。
@Bean
ErrorViewResolver supportPathBasedLocationStrategyWithoutHashes() {
return new ErrorViewResolver() {
@Override
public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
return status == HttpStatus.NOT_FOUND
? new ModelAndView("index.html", Collections.<String, Object>emptyMap(), HttpStatus.OK)
: null;
}
};
}
次のようなものを使用して、Angularにマッピングされていないすべてを転送できます。
@Controller
public class ForwardController {
@RequestMapping(value = "/**/{[path:[^\\.]*}")
public String redirect() {
// Forward to home page so that route is preserved.
return "forward:/";
}
}
ソース: https://stackoverflow.com/a/44850886/3854385
angularの私のSpring Bootサーバーは、angularページの前にログインページを持たない/api
へのAPI呼び出しを備えたゲートウェイサーバーでもあります。好む。
import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
/**
* This sets up basic authentication for the microservice, it is here to prevent
* massive screwups, many applications will require more secuity, some will require less
*/
@EnableOAuth2Sso
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{
@Override
public void configure(HttpSecurity http) throws Exception {
http
.logout().logoutSuccessUrl("/").and()
.authorizeRequests()
.antMatchers("/api/**").authenticated()
.anyRequest().permitAll().and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
}
より簡単にするために、ErrorPageRegistrarを直接実装することができます。
@Component
public class ErrorPageConfig implements ErrorPageRegistrar {
@Override
public void registerErrorPages(ErrorPageRegistry registry) {
registry.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/"));
}
}
これにより、リクエストがindex.htmlに転送されます。
@Controller
@RequestMapping("/")
public class MainPageController {
@ResponseStatus(HttpStatus.OK)
@RequestMapping({ "/" })
public String forward() {
return "forward:/";
}
}
forward all Angular index.htmlによるルーティング。basehrefを含む。
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class ViewController {
@RequestMapping({ "jsa/customer","jsa/customer/{id}",})
public String index() {
return "forward:/index.html";
}
}
私の場合、jsaはbase hrefです。
私は普通の古い filter でそれをしました:
public class PathLocationStrategyFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
if(request instanceof HttpServletRequest) {
HttpServletRequest servletRequest = (HttpServletRequest) request;
String uri = servletRequest.getRequestURI();
String contextPath = servletRequest.getContextPath();
if(!uri.startsWith(contextPath + "/api") &&
!uri.startsWith(contextPath + "/assets") &&
!uri.equals(contextPath) &&
// only forward if there's no file extension (exclude *.js, *.css etc)
uri.matches("^([^.]+)$")) {
RequestDispatcher dispatcher = request.getRequestDispatcher("/");
dispatcher.forward(request, response);
return;
}
}
chain.doFilter(request, response);
}
}
その後、web.xml
:
<web-app>
<filter>
<filter-name>PathLocationStrategyFilter</filter-name>
<filter-class>mypackage.PathLocationStrategyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PathLocationStrategyFilter</filter-name>
<url-pattern>*</url-pattern>
</filter-mapping>
</web-app>
次の3つの手順に従う必要があります。
独自のTomcatEmbeddedServletContainerFactory Beanを実装し、RewriteValveをセットアップします
import org.springframework.boot.context.embedded.Tomcat.TomcatEmbeddedServletContainerFactory;
...
import org.Apache.catalina.valves.rewrite.RewriteValve;
...
@Bean TomcatEmbeddedServletContainerFactory servletContainerFactory() {
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
factory.setPort(8080);
factory.addContextValves(new RewriteValve());
return factory;
}
Rewrite.confファイルをアプリケーションのWEB-INFディレクトリに追加し、書き換えルールを指定します。次に、rewrite.confのコンテンツの例を示します。これは、angularアプリケーションで、angularのPathLocationStrategyを利用するために使用します(基本的には、私はすべてをspringブートして静的Webコンテンツを提供します。そうでない場合は、RewriteCondルールでコントローラーを除外する必要があります)。
RewriteCond %{REQUEST_URI} !^.*\.(bmp|css|gif|htc|html?|ico|jpe?g|js|pdf|png|swf|txt|xml|svg|eot|woff|woff2|ttf|map)$
RewriteRule ^(.*)$ /index.html [L]
ルーティング宣言からuseHashを取り除きます(またはfalseに設定します)。
RouterModule.forRoot(routes)
または
RouterModule.forRoot(routes, {useHash: false})