web-dev-qa-db-ja.com

単一ページのangular2でリダイレクトするスプリングブート

私は単一のページを持っていますangular spring bootのアプリ。次のようになります

src
  main
  Java
    controller
       HomeController
       CustomerController
       OtherController
  webapp
    js/angular-files.js
    index.html

Springブートはwebappフォルダーに正しくデフォルト設定され、index.htmlファイルを提供します。

私がやろうとしているのは

1)ローカルごとにREST requestnot/ apiで始まり、デフォルトに上書きしてデフォルトにリダイレクトwebapp/index.html。Springコントローラーに/ apiを提供する予定です。

2)すべてのコントローラーにapiをプレフィックスとして付けることで、毎回apiを記述する必要がないようにする方法はありますか。

例えば.

@RequestMapping("/api/home") can write shorthand in code  @RequestMapping("/home")

または

@RequestMapping("/api/other-controller/:id") can write shorthand  @RequestMapping("/other-controller/:id")

編集..上記の説明を改善するための注記を追加

すべてのAPIリクエストを探しています。 1) http:// localhost:8080/api/home apiをapiに保ち、正しいコントローラーに解決してjsonを返します。

ただし、誰かが http:/// localhost/some-url または http:/// localhost/some-other/123/url のようなURLを入力すると、 index.htmlページとURLを保持します。

enter image description here

別の方法-#ErrorViewResolverを追加してみてください Springboot/Angular2-HTML5 URLの処理方法

13
Robbo_UK

すべてのローカルREST/apiで始まっていないリクエストは、デフォルトのwebapp/index.htmlに上書きしてリダイレクトします。スプリングコントローラーに/ apiを提供する予定です。

2017年5月15日更新

他の読者のためにあなたの質問を言い換えてみましょう。 (誤解された場合は修正してください

背景
Spring Bootの使用とクラスパスからの静的リソースの提供

要件
すべての404api以外リクエストはindex.htmlにリダイレクトする必要があります。

NON API-URLが/apiで始まらないリクエストを意味します。
[〜#〜] api [〜#〜]-404は通常どおり404をスローする必要があります。

応答のサンプル
/api/something-404をスローします
/index.html-index.htmlをサーバーに提供します
/something-index.htmlにリダイレクトします

私の解決策

特定のリソースに対してハンドラーが利用できない場合、Spring MVCに例外をスローさせます。

以下をapplication.propertiesに追加します

spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false

次のようにControllerAdviceを追加します

@ControllerAdvice
public class RedirectOnResourceNotFoundException {

    @ExceptionHandler(value = NoHandlerFoundException.class)
    public Object handleStaticResourceNotFound(final NoHandlerFoundException ex, HttpServletRequest req, RedirectAttributes redirectAttributes) {
        if (req.getRequestURI().startsWith("/api"))
            return this.getApiResourceNotFoundBody(ex, req);
        else {
            redirectAttributes.addFlashAttribute("errorMessage", "My Custom error message");
            return "redirect:/index.html";
        }
    }

    private ResponseEntity<String> getApiResourceNotFoundBody(NoHandlerFoundException ex, HttpServletRequest req) {
        return new ResponseEntity<>("Not Found !!", HttpStatus.NOT_FOUND);
    }
}

エラーメッセージは自由にカスタマイズできます。

すべてのコントローラーの前にapiを付ける方法があるので、毎回apiを書く必要はありません。

このために、BaseControllerを作成し、RequestMappingパスを/apiに設定できます

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/api")
public abstract class BaseController {}

そして、このBaseControllerを拡張し、しない子クラスに@RequestMappingアノテーションを付けていることを確認してください

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FirstTestController extends BaseController {
    @RequestMapping(path = "/something")
    public String sayHello() {
        return "Hello World !!";
    }

}

前の回答

リクエストパスが/index.htmlで始まらない場合、/apiにリダイレクトするFilterを作成できます。

// CODE REMOVED. Check Edit History If you want.
17
ansh

非常に多くの相反する解決策に従うことでこの問題を解決しようとすることにうんざりしているなら、こちらをご覧ください!!

数時間後pon hours数十のスタックオーバーフローやブログ投稿から散らばったすべてのアドバイスに従おうとすると、PUREスプリングブートの最小値+ angular 6アプリケーションが見つかりましたすべてのREST APIエンドポイントパスを維持しながら、非ルートページの更新後に常にindex.htmlにリダイレクトします。@EnableWebMvc@ControllerAdviceapplication.propertiesへの変更なし、カスタムResourceHandlerRegistry変更なし、単純化:

非常に重要な前提条件

* must * include the output of ng buildをSpringのresources/staticフォルダーに含めます。これはmaven-resources-pluginを介して実現できます。ここで学ぶ: mavenを使用して複数のリソースディレクトリを独立したターゲットディレクトリにコピーする

コード

@Controller
@SpringBootApplication
public class MyApp implements ErrorController {

    public static void main(String[] args) {
        SpringApplication.run(MyApp.class, args);
    }

    private static final String PATH = "/error";

    @RequestMapping(value = PATH)
    public String error() {
        return "forward:/index.html";
    }

    @Override
    public String getErrorPath() {
        return PATH;
    }
}

推論

  • ビルド時にng-buildの出力をresources/staticに含めると、スプリングビューのリダイレクト("forward:/index.html")が成功します。 Springはresourcesフォルダの外にリダイレクトできないようですので、サイトのルートにあるページにアクセスしようとしても機能しません。
  • デフォルトの機能(つまり、@EnableWebMvcの追加またはapplication.propertiesへの変更なし)で/に移動すると、index.htmlが自動的に提供されます(resources/staticフォルダーに含まれていた場合)そこで変更を加える必要はありません。
  • 上記のデフォルト機能により、スプリングブートアプリで発生したエラーは/errorにルーティングされ、ErrorControllerを実装すると、その動作がオーバーライドされます-推測-index.htmlにルーティングAngularはルーティングを引き継ぎます。

備考

代わりにこれを試してください

@SpringBootApplication
@RestController
class YourSpringBootApp { 

    // Match everything without a suffix (so not a static resource)
    @RequestMapping(value = "/**/{path:[^.]*}")       
    public String redirect() {
        // Forward to home page so that route is preserved.
        return "forward:/";
    }
}
13
Eduardo Eljaiek
@Controller
public class RedirectController {
    /*
     * Redirects all routes to FrontEnd except: '/', '/index.html', '/api', '/api/**'
     */
    @RequestMapping(value = "{_:^(?!index\\.html|api).*$}")
    public String redirectApi() {
        return "forward:/";
    }
}
1
Anton

では、質問の簡単な部分から始めましょう。

すべてのコントローラーの前にapiを付けることで、毎回apiを記述する必要がないようにする方法はありますか?

答えは「はい」です。コントローラに「グローバル」@RequestMapping注釈を付けるだけです。たとえば、

@RestController
@RequestMapping("/api")
public class ApiController{

   @RequestMapping("/hello") 
   public String hello(){
      return "hello simple controller";
   }

   @RequestMapping("/hello2") 
   public String hello2(){
      return "hello2 simple controller";
   }
}

上記の例では、次のURLでhelloメソッドを呼び出すことができます:/api/hello

および次のURLの2番目の方法:/api/hello2

これは、/apiプレフィックスで各メソッドをマークする必要がなかった方法です。

さて、あなたの質問のより複雑な部分に:

リクエストが/apiプレフィックスで始まらない場合にリダイレクトを達成する方法は?

リダイレクトのHTTPステータスコード(302)を返すことで、それを行うことができます。結局、angularJsはネイティブに「話す」RESTに使用。

次に、ステータスコード302のHTTPメッセージを返すだけで、angularJSで実際のリダイレクトが行われます。

例えば:

AngularJSの場合:

var headers = {'Content-Type':'application/json', 'Accept':'application/json'}

var config = {
    method:'GET'
    url:'http://localhost:8080/hello',
    headers:headers
};

http(config).then(
    function onSuccess(response){
        if(response.status == 302){
            console.log("Redirect");
            $location("/")
        }
}, function onError(response){
    console.log("An error occured while trying to open a new game room...");
});

春:

@RestController
@RequestMapping("/api")
public class ApiController{

   @RequestMapping("/hello") 
   public ResponseEntity<String> hello(){
      HttpHeaders header = new HttpHeaders();
      header.add("Content-Type", "application/json");
      return new ResponseEntity<String>("", header, HttpStatus.FOUND);
   }
}

もちろん、プロジェクトに合わせてカスタマイズする必要があります。

0
Moshe Arad

アプリケーション全体では、application.propertiesにコンテキストパスを追加できます。

server.contextPath =/api

http:// localhost:8080/api/home の後に、要求されたすべてのURLに「/ api」を追加します

リダイレクトの場合、

@Override
public void addViewControllers(ViewControllerRegistry registry) {
    registry.addRedirectViewController("/", "/home");
    registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
    super.addViewControllers(registry);
}

このコードの束をWebMVCConfig.Javaに入れます

0
Anksss

試す必要があるのは、index.htmlからsrc/main/resources/static/

例を参照してください:https://github.com/reflexdemon/shop/tree/master/src/main/resources/static =

私のpackage.josnこの場所にコピーしようとしています。

PackageJSONを参照:https://github.com/reflexdemon/shop/blob/master/package.json#L14

0
reflexdemon

@Configuration BeanでServletRegistrationBeanを追加して、/ api/* resquest専用のスプリングサーバーを作成できます。その後、Controllerで追加する必要はありません。

@Bean
public ServletRegistrationBean dispatcherRegistration() {
    ServletRegistrationBean registration = new ServletRegistrationBean(
            dispatcherServlet());
    registration.addUrlMappings("/api/*");
    registration.setLoadOnStartup(1);
    registration.setName("mvc-dispatcher");
    return registration;
}
0
Jane