首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >使Spring/Tomcat与HTML5 pushState兼容

使Spring/Tomcat与HTML5 pushState兼容
EN

Stack Overflow用户
提问于 2012-11-08 18:23:19
回答 3查看 2.5K关注 0票数 0

我有一个使用pushState的Backbone.js客户端路由的单页web应用程序。为了让它工作,我必须告诉我的服务器(Java、Spring3、Tomcat)哪些URL应该在服务器上解析(实际的JSP视图、API请求),哪些应该简单地发送到索引页由客户端处理。目前,我使用InternalResourceViewResolver简单地提供与URL请求名称匹配的JSP视图。由于客户端URL在服务器上没有视图,因此服务器返回404。

向Spring (或Tomcat)指定几个特定的URL(我的客户端路由)都应该解析到index.jsp,而其他任何东西都应该解析到InternalResourceViewResolver,最好的方法是什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-11-12 16:18:56

我发现Spring MVC3添加了一个我需要的标签,即mvc:view-controller标签。这就帮我完成了:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<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

票数 2
EN

Stack Overflow用户

发布于 2016-12-06 21:38:56

理论上,要通过history.pushState处理导航,您需要为未处理的资源返回index.html。如果你看一下现代web框架的官方文档,它通常是基于404状态实现的。

在spring中,你应该按顺序处理资源:

适用于其他的REST controllers

  • app static resources

  • index.html的
  • 路径映射

要做到这一点,你至少有4种可能的解决方案。

使用EmbeddedServletContainerCustomizer和自定义404处理程序

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@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"));
}

使用自定义默认请求映射处理程序

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@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;
}

摘要

第四种选择看起来最简单,但一如既往地取决于你需要什么。您可能还希望仅当请求需要文本/html时才返回index.html ( BasicErrorController已经基于"produces“标头执行了此操作)。

我希望其中一个选项对您的情况有所帮助。

票数 1
EN

Stack Overflow用户

发布于 2012-11-09 00:17:37

我会给我的urls一个明确的方案,并将前端与后端分开。

一些建议:

  • 将所有以/server开头的请求路由到后端,将所有其他请求路由到frontend.
  • Setup两个不同的域,一个用于后端,一个用于前端。
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13295300

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文