【问题标题】:RequestMapping issue with multiple Angular clients in Spring Boot ApplicationSpring Boot 应用程序中多个 Angular 客户端的 RequestMapping 问题
【发布时间】:2019-06-13 02:33:12
【问题描述】:

我需要处理一些 GET 请求以便转发到多个 Angular 客户端。

https://example.com/web/index.html    // Client 1
https://example.com/admin/index.html  // Client 2

由于我不想为 /web 使用零散的 (#-ed) 路径,所以事情变得相当棘手。

这是我目前的不工作解决方案:

@Controller
public class ForwardController {

    @RequestMapping(value = "/*", method = RequestMethod.GET)
    public String redirectRoot(HttpServletRequest request) {

        String req = request.getRequestURI();

        if (req.startsWith("/admin/")) {
            return this.redirectAdminTool(request);
        }

        return "forward:/web/index.html";
    }

    @RequestMapping(value = "/web/{path:[^.]*}", method = RequestMethod.GET)
    public String redirectWeb(HttpServletRequest request) {
        return "forward:/web/index.html";
    }

    @RequestMapping(value = "/admin/{path:[^.]*}", method = RequestMethod.GET)
    public String redirectAdminTool(HttpServletRequest request) {
        return "forward:/admin/index.html";
    }
}

有了这个,工作就是访问例如

  • /web/pricing

但无法访问的是

  • /web/pricing/vienna

我可以通过浏览器访问/web/pricing,点击“刷新”,一切正常。但它不适用于/web/pricing/vienna

现在,我无法弄清楚如何处理请求以及如何转发它们以使 /web/pricing/vienna 之类的子路径也能正常工作。

我有什么办法可以完成这项工作吗?

如果我将@RequestMapping 路径更改为/web/** 之类的路径,那么整个事情就会陷入无限循环并破坏服务器。


我可能需要的是这样的表达式:

/web(/[^\\.]*)

这会导致

MATCH:    /web/pricing
MATCH:    /web/specials/city
MATCH:    /web/specials/city/street
NO MATCH: /web/index.html

但是,Spring 不喜欢这个正则表达式:/web(/[^\\.]*)

最后这个问题归结为找到一种方法来匹配除了/web下面的静态资源之外的所有东西。

【问题讨论】:

  • 你也许可以用 UrlRewriteFilter 做到这一点 - tuckey.org/urlrewrite
  • @GreyBeardedGeek 嗯,这个解决方案可能是我最后的手段,但如果可能的话,我想避免这样做。毕竟这是一个非常小的问题,可以用一个简单的正则表达式来解决,但似乎@RequestMapping 在这方面受到限制,或者我在文档中找不到相关部分。

标签: regex angular spring spring-boot


【解决方案1】:

这是我最终做的:

我将两个客户端都移到了一个子目录a/

static/a/web
static/a/admin

此外,我实现了这样的ForwardController

@Controller
public class ForwardController {

    @RequestMapping(value = "/*", method = RequestMethod.GET)
    public String redirectRoot(HttpServletRequest request) {
        return "forward:/a/web/index.html";
    }

    @RequestMapping(value = "/a/**/{path:[^.]*}", method = RequestMethod.GET)
    public String redirectClients(HttpServletRequest request) {

        String requestURI = request.getRequestURI();

        if (requestURI.startsWith("/a/admin/")) {
            return "forward:/a/admin/index.html";
        }

        return "forward:/a/web/index.html";
    }

}

【讨论】:

    【解决方案2】:

    子路由将不起作用,因为需要先加载主索引才能获取所有路由。 一种解决方法是每次服务器端找不到路径时重定向到主索引:

    @Controller
    @RequestMapping("/error")
    public class ErrorHandlerController extends AbstractErrorController {
    
    private static final String ROOT_PATH = "/";
    
    public ErrorHandlerController(ErrorAttributes errorAttributes) {
        super(errorAttributes);
    }
    
    @RequestMapping
    public void errorHtml(HttpServletRequest request,
            HttpServletResponse response) throws IOException {
        if(HttpStatus.NOT_FOUND.equals(getStatus(request))) {
            response.sendRedirect(ROOT_PATH);
        }
    }
    
    @Override
    public String getErrorPath() {
        return "error";
    }
    
    }
    

    【讨论】:

    • 我认为这不适用于多个客户。我有多个根 /web/index.html/admin/index.html 是两个独立的 Angular 应用程序。
    猜你喜欢
    • 1970-01-01
    • 2020-02-12
    • 1970-01-01
    • 2019-12-05
    • 1970-01-01
    • 2021-10-13
    • 2020-06-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多