代码之家  ›  专栏  ›  技术社区  ›  nanobar

修复Java Servlet(HTML5 PASSTATE)所服务的HTML中的相对路径

  •  3
  • nanobar  · 技术社区  · 6 年前

    我正在尝试修改一个JETTY服务器,它有一个servlet(RooRealth.java),它神奇地拿起并使用:

    @Singleton
    @Path("/")
    public class RootResource {
        @Context
        private ServletContext servletContext;
    
        @GET
        @Path("react-client/{path: .*\\..+$}")
        public Response serveReactClientContent(@Context HttpServletRequest httpServletRequest) {
            // This doesn't work, a resolved relative resource is not relative
            // to the /react-client base. See description of problem.
            final String pathToResource = httpServletRequest.getRequestURI();
            return serveStaticContent(pathToResource);
        }
    
        @GET
        @Path("react-client/{path: .*$}")
        public Response serveReactClientIndexPage(@Context HttpServletRequest httpServletRequest) {
            return serveStaticContent("/react-client/index.html");
        }
    
        private Response serveStaticContent(String pathToResource) {
            final String type = this.servletContext.getMimeType(pathToResource);
            final Response.ResponseBuilder response = Response.ok(servletContext.getResourceAsStream(pathToResource)).type(type);
            return response.build();
        }
    }
    

    想法是接受一个GET请求 react-client/some/path 并返回 react-client/index.html . 本质上,使Jetty的行为类似于使用客户端路由的webapp服务器。

    我面临的问题是 index.html 只有当路径深一层时才能工作 例如 react-client/products .

    <script src="./webapp.js"></script>
    

    在这种情况下,可以在index.html中找到上面的javascript文件,因为 webapp.js 是存在于的文件 react-client/webapp.js .

    一旦我尝试更深入的链接,例如 react-client/products/97357361 当servlet试图找到 WebAPP.JS 在里面 react-client/products/webapp.js 这是不存在的。

    我怎样才能让它总是请求资源,就好像它来自 /react-client ?谢谢

    2 回复  |  直到 6 年前
        1
  •  0
  •   Montri M    6 年前

    自从你 index.html 可以通过多个URL访问,例如

    • /反应客户/产品
    • /反应客户/产品/97357361
    • /反应客户/部分
    • /响应客户端/部分/路径

    添加一个 <base> 标记在HTML页面的标题处。

    <head>
        ...
        <base href="https://www.yourwebsite.com/react-content/" />
        <script src="./script.js"></script>
        ...
    </head>
    

    这将告诉浏览器解析在页面中找到的与 https://www.yourwebsite.com/react-content/

    所以,根据上面的例子, <script src="./script.js"></script> 将作为 "https://www.yourwebsite.com/react-content/script.js" 无论当前用于访问此页的URL是什么。

    然后,您可以在Jetty上恢复这些设置并保持简单。

        2
  •  0
  •   nanobar    6 年前

    我试过很多东西,比如过滤器和 rewrite handlers 但在任何时候,Jetty都没有提供原始未解决的相对进口(例如 ./webapp )所以我从来没有机会重写相关资源。

    最后,我不得不用一个黑客程序来检测它们,因为我知道它们几乎都是从 /static/ 子目录(我必须为 favicon.ico manifest.json .

    @GET
    @Path("react-client/{path: .*\\..+$}")
    public Response serveReactClientContent(@Context HttpServletRequest httpServletRequest) {
        final String pathToResource = httpServletRequest.getRequestURI();
    
        Pattern p = Pattern.compile("/react-client/(.+?(?=static/|favicon.ico))", Pattern.CASE_INSENSITIVE);
        Matcher m = p.matcher(pathToResource);
        String resolveResourcePath = m.replaceAll("/react-client/");
        return serveStaticContent(resolveResourcePath);
    }
    

    对它不满意,但它起作用了。