1

pushStateでBackbone.jsクライアントルーティングを使用しているシングルページWebアプリがあります。これを機能させるには、サーバー(Java、Spring 3、Tomcat)に、サーバー上で解決する必要のあるURL(実際のJSPビュー、API要求)と、インデックスページに送信する必要があるURLを通知する必要があります。クライアントによって処理されます。現在、InternalResourceViewResolverを使用して、URLリクエストの名前に一致するJSPビューを提供しています。クライアント側のURLにはサーバー上のビューがないため、サーバーは404を返します。

いくつかの特定のURL(クライアント側のルート)をすべてindex.jspに解決し、その他のURLをInternalResourceViewResolverに渡すように、Spring(またはTomcat)に指定する最良の方法は何ですか?

4

3 に答える 3

3

Spring MVC 3が、私が必要としていることを正確に実行するタグ、タグを追加したことがわかりましたmvc:view-controller。これは私のためにそれを成し遂げました:

<mvc:view-controller path="/" view-name="index" />
<mvc:view-controller path="/admin" view-name="index" />
<mvc:view-controller path="/volume" view-name="index" />

http://static.springsource.org/spring/docs/3.0.x/reference/mvc.html

于 2012-11-12T16:18:56.050 に答える
1

理論的には、history.pushStateを介してナビゲーションを処理するには、未処理のリソースに対してindex.htmlを返します。最新のWebフレームワークの公式ドキュメントを見ると、404ステータスに基づいて実現されていることがよくあります。

春には、次の順序でリソースを処理する必要があります。

  • パスマップされたRESTコントローラー
  • アプリの静的リソース
  • 他の人のためのindex.html

これを行うには、少なくとも4つの可能な解決策があります。

EmbeddedServletContainerCustomizerとカスタム404ハンドラーの使用

@Controller
static class SpaController {
    @RequestMapping("resourceNotFound")
    public String handle() {
        return "forward:/index.html";
    }
}

@Bean
public EmbeddedServletContainerCustomizer containerCustomizer() {
    return container -> container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/resourceNotFound"));
}

カスタムのデフォルトのリクエストマッピングハンドラーを使用する

@Autowired
private RequestMappingHandlerMapping requestMappingHandlerMapping;

static class SpaWithHistoryPushStateHandler {

}

static class SpaWithHistoryPushStateHandlerAdapter implements HandlerAdapter {

    @Override
    public boolean supports(final Object handler) {
        return handler instanceof SpaWithHistoryPushStateHandler;
    }

    @Override
    public ModelAndView handle(final HttpServletRequest request, final HttpServletResponse response, final Object handler) throws Exception {
        response.getOutputStream().println("default index.html");
        return null;
    }

    @Override
    public long getLastModified(final HttpServletRequest request, final Object handler) {
        return -1;
    }
}

@Bean
public SpaWithHistoryPushStateHandlerAdapter spaWithHistoryPushStateHandlerAdapter() {
    return new SpaWithHistoryPushStateHandlerAdapter();
}

@PostConstruct
public void setupDefaultHandler() {
    requestMappingHandlerMapping.setDefaultHandler(new SpaWithHistoryPushStateHandler());
}

カスタムResourceResolverの使用

@Autowired
private ResourceProperties resourceProperties;

@Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/**")
            .addResourceLocations(resourceProperties.getStaticLocations())
            .setCachePeriod(resourceProperties.getCachePeriod())
            .resourceChain(resourceProperties.getChain().isCache())
            .addResolver(new PathResourceResolver() {
                @Override
                public Resource resolveResource(final HttpServletRequest request, final String requestPath, final List<? extends Resource> locations, final ResourceResolverChain chain) {
                    final Resource resource = super.resolveResource(request, requestPath, locations, chain);
                    if (resource != null) {
                        return resource;
                    } else {
                        return super.resolveResource(request, "/index.html", locations, chain);
                    }
                }
            });
}

カスタムErrorViewResolverの使用

@Bean
public ErrorViewResolver customErrorViewResolver() {
    final ModelAndView redirectToIndexHtml = new ModelAndView("forward:/index.html", Collections.emptyMap(), HttpStatus.OK);
    return (request, status, model) -> status == HttpStatus.NOT_FOUND ? redirectToIndexHtml : null;
}

概要

4番目のオプションは最も単純に見えますが、いつものように、必要なものによって異なります。また、リクエストがtext / htmlを期待している場合にのみindex.htmlを返すように制限することもできます(BasicErrorControllerは「produces」ヘッダーに基づいてすでに実行しています)。

このオプションの1つがあなたのケースに役立つことを願っています。

于 2016-12-06T21:38:55.853 に答える
-1

私は自分のURLに明確なスキームを与え、フロントエンドをバックエンドから分離します。

いくつかの提案:

  • 最初にすべてのリクエストを/serverバックエンドにルーティングし、他のすべてのリクエストをフロントエンドにルーティングします。
  • 2つの異なるドメインを設定します。1つはバックエンド用、もう1つはフロントエンド用です。
于 2012-11-09T00:17:36.530 に答える