私は単一のページを持っています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を保持します。
別の方法-#ErrorViewResolverを追加してみてください Springboot/Angular2-HTML5 URLの処理方法
すべてのローカルREST/apiで始まっていないリクエストは、デフォルトのwebapp/index.htmlに上書きしてリダイレクトします。スプリングコントローラーに/ apiを提供する予定です。
2017年5月15日更新
他の読者のためにあなたの質問を言い換えてみましょう。 (誤解された場合は修正してください)
背景
Spring Bootの使用とクラスパスからの静的リソースの提供
要件
すべての404
api以外リクエストは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.
数時間後pon hours数十のスタックオーバーフローやブログ投稿から散らばったすべてのアドバイスに従おうとすると、PUREスプリングブートの最小値+ angular 6アプリケーションが見つかりましたすべてのREST API
エンドポイントパスを維持しながら、非ルートページの更新後に常にindex.htmlにリダイレクトします。@EnableWebMvc
、@ControllerAdvice
、application.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;
}
}
resources/static
に含めると、スプリングビューのリダイレクト("forward:/index.html"
)が成功します。 Springはresourcesフォルダの外にリダイレクトできないようですので、サイトのルートにあるページにアクセスしようとしても機能しません。@EnableWebMvc
の追加またはapplication.properties
への変更なし)で/
に移動すると、index.htmlが自動的に提供されます(resources/static
フォルダーに含まれていた場合)そこで変更を加える必要はありません。/error
にルーティングされ、ErrorController
を実装すると、その動作がオーバーライドされます-推測-index.html
にルーティングAngular
はルーティングを引き継ぎます。HashLocationStrategy
がAngularによって推奨されていないため、この問題を解決するために落ち着かないでください。 https://angular.io/guide/router#which-strategy-is-best =代わりにこれを試してください
@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:/";
}
}
@Controller
public class RedirectController {
/*
* Redirects all routes to FrontEnd except: '/', '/index.html', '/api', '/api/**'
*/
@RequestMapping(value = "{_:^(?!index\\.html|api).*$}")
public String redirectApi() {
return "forward:/";
}
}
では、質問の簡単な部分から始めましょう。
すべてのコントローラーの前に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);
}
}
もちろん、プロジェクトに合わせてカスタマイズする必要があります。
アプリケーション全体では、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に入れます
試す必要があるのは、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
@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;
}