【问题标题】:AngularJS and Spring MVC with nested routeAngularJS 和 Spring MVC 与嵌套路由
【发布时间】:2015-07-26 16:34:33
【问题描述】:

我对这个主题做了很多研究,但没有找到正确或具体的答案,所以在打开 Spring MVC 项目的 jira 票之前,我在这里问它。

我的应用程序是使用 Spring MVC(带有 spring boot)作为后端和 AngularJS 1.x 在前端构建的。我还激活了 html5mode(所以,没有使用 #,只是像 http://podcast.dk.lan/podcasts/123/items/456/player 这样的普通 url)。

我在后端有一个 @Controller 路由,将“/”请求重定向到我的 index.html。 所有其他路由都由 @RestController 处理并使用 JSON(在“/api”或“/system”上)。

我已经寻找了将所有 AngularJS 路由映射到我的应用程序的 index.html 的正确方法,而不会破坏后端解析器的其他部分(例如资源)。

我尝试了以下元素:

@Controller
public class HomeController {   
    @RequestMapping(value = "/{.*}")
    private String home() {
    return "forward:/";
    }
}

它不起作用,因为如果我尝试直接访问前端的嵌套 url(如 /podcasts/1/items/1 ),则请求映射正则表达式不会捕获该 url。

@Controller
public class HomeController {   
    @RequestMapping(value = "/**/{.*}")
    private String home() {
    return "forward:/";
    }
}

此配置导致 StackOverFlow 错误,因为 url 将重定向到自身...

最近,在一篇关于 Spring-Security 和 AngularJS 的非常好的教程中,他们使用了以下模式:

@Controller
public class HomeController {   
@RequestMapping(value = "/{[path:[^\\.]*}")
    private String home() {
    return "forward:/";
    }
}

此模式通过排除任何带有 . (点)在网址中。不幸的是,它不适用于嵌套路由...返回 404 错误。

所以,我的应用后端现在链接到我的路由前端,因为我必须将前端使用的 AngularJS 路由硬编码为请求映射值:

@Controller
public class HomeController {

    @RequestMapping(value = {"", "items", "podcasts", "podcasts/**", "player", "podcast-creation", "download", "stats"})
    private String home() {
        return "forward:/";
    }
}

我认为(并且我希望)有一个更好的解决方案可以将所有“尚未映射的 url 后端映射”重定向到这样的特定方法。

我项目的所有代码都托管在 github 上(如果您想查看更多代码)davinkevin/Podcast-Server

感谢您的帮助

【问题讨论】:

  • Angular 路由应该只映射到客户端。在后端,您应该只映射入口点页面。作为单页应用程序,其余的路由在客户端进行管理。
  • 放下你的控制器。添加 2 个视图控制器,第一个用于 /index.html/** 用于转发。视图控制器将在所有其他控制器之后处理(最低优先级)。
  • @tarini :我谈论的问题与 Angular 中激活的 HTML5Mode 相关联,创建没有任何 hashbang 的 url。如果什么都不做,这个引导特定路由(除了简单的“/”)将由后端系统解释。
  • @M.Deinum:你能给我举个例子吗?您谈论在扩展 WebMvcConfigurerAdapter 的类中定义的视图控制器?
  • 覆盖addViewControllers 方法并创建2 个视图控制器,而不是尝试添加自己的。在/** 之前映射/ 应该可以工作,或者只是创建一个/** 将所有内容重定向到index.html 文件。

标签: angularjs spring spring-mvc


【解决方案1】:

我不知道这是否是最好的解决方案,但它非常简单并且对我们有用,我相信它应该能够处理您的情况。

这里的主要目标是让后端将所有应该由角度路由解析的请求(换句话说,后端中没有真正的资源URI)转发到根@987654321 @,所以当浏览器再次加载 index 和 angular 应用时,angular 可以在客户端解析路由。如果您对所有角度路由都有一个众所周知的保留前缀(即:/fe[前端的缩写]),您可以使用类似于 /fe/** 的请求映射模式,它返回 @ 987654324@。

您只需要确保您的所有角度路由都以/fe/ 开头,并且fe 文件夹中没有静态资源或没有其他以此前缀开头的请求映射。

@Controller
public class HomeController { 
    @RequestMapping(value = "/fe/**")
    public String redirect() {
        return "forward:/";
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-10
    • 2016-05-26
    • 2015-07-06
    • 2015-04-02
    • 1970-01-01
    • 2014-11-22
    • 1970-01-01
    • 2011-01-15
    相关资源
    最近更新 更多