web-dev-qa-db-ja.com

Springboot / Angular2-HTML5 URLの処理方法

これは簡単な質問だと思いますが、答えが見つからなかったか、少なくとも検索で正しい用語を使用できませんでした。

Angular2Springbootを一緒に設定しています。デフォルトでは、Angularlocalhost:8080\dashboardlocalhost: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のいずれかでより良いソリューションはありますか?

37
Felipe S.

私はあなたのための解決策を持っています、あなたは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エラーページもリダイレクトできますさらなるステップとしてインデックスページに。楽しい!

46
AndroidLover

カスタム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;
        }
    };
}
12
Dmitry Serdiuk

次のようなものを使用して、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());
    }
}
7
Loren

より簡単にするために、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:/";
    }
}
1
Akhil Bojedla

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です。

0
Anis Mulla

私は普通の古い 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>
0
fidke

次の3つの手順に従う必要があります。

  1. 独自の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;
      }
    
  2. 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]
    
  3. ルーティング宣言からuseHashを取り除きます(またはfalseに設定します)。

      RouterModule.forRoot(routes)
    

または

      RouterModule.forRoot(routes, {useHash: false})
0