如何在@Controller中让静态内容通过并转发非静态内容请求?

时间:2019-01-27 20:38:54

标签: spring spring-boot

我有一个项目,该项目运行一个Spring Boot应用程序,该应用程序在static/中提供两个Angular应用程序。

为了能够使事情正常进行,我不得不四处走动一些内因(see my old question)。以下适用于/a下的两个应用程序和/api下的REST API:

@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";
    }

}

唯一起作用的是在根/处提供的任何静态内容,例如sitemap.xml

问题是我在根上匹配/*,这意味着任何请求,/sitemap.xml也会被ForwardController捕获。我已经用/{path:[^.]*}进行过尝试-然后我只能访问/sitemap.xml,但是将无法再访问到/a/web/index.html的重定向。

实际上-我不明白为什么/{path:[^.]*}在这里不起作用,因为这应该匹配任何看起来不像静态内容的内容,例如/a-song.wav

有什么办法可以使我工作?


总结:

我有两个Web应用程序客户端:

/a/admin/index.html
/a/web/index.html

并且我希望对根/任何请求都转发到/a/web/index.html ,但仍然可以从中访问静态内容根,例如/sitemap.xml,依此类推。

问题是/{path:^[.]*}仅允许我访问静态文件,但中断了转发给客户端的操作,/*将适用于转发给客户端的操作,但无法访问根目录上的静态文件

2 个答案:

答案 0 :(得分:1)

IIRC在Spring MVC控制器中的方法顺序可能很重要,您可以根据自己的情况使用它。如果您这样定义控制器:

@Controller
public class ForwardController {

    @RequestMapping(value = "/sitemap.xml", method = RequestMethod.GET)
    public String redirectSitemap(HttpServletRequest request) {
        return "forward:/a/web/sitemap.xml";
    }

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

    ...

}

Spring将首先匹配sitemap.xml路径,如果不匹配,则转到第二个。如果顶级资源的数量不是那么多,则可以将其放在顶部以进行优先级匹配。

答案 1 :(得分:-1)

除非我丢失了某些东西,否则我将创建两个端点。

@Controller
public class ForwardController {

    @RequestMapping(value = {"/", "/**/{path:[^.]*}"}, 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";
    }

}

下面是所有对我有用的模拟请求。

除静态以外的所有根请求(/ web&/&&/ web / 2)与第一个端点匹配。

所有静态请求(/sitemap.xml&/a/web/index.html)与任何端点都不匹配,并且直接由ResourceHttpRequestHandler提供服务。在我的情况下,静态资源位于src / main内部/resources/static/a/web/index.html和src / main / resources / static / sitemap.xml。

所有Web和管理员请求(/ a / web&/ a / admin)都匹配到/ a / ** / {path:[^。] *}