简体   繁体   English

使用Jetty支持Angular 2的PathLocationHandler(使用404错误页面)

[英]Supporting Angular 2's PathLocationHandler with Jetty (using a 404 error page)

I'm trying to work out how to support Angular 2's PathLocationHandler with an embedded Jetty server. 我正在尝试研究如何使用嵌入式Jetty服务器支持Angular 2的PathLocationHandler。 To do that, as I understand it, I need to redirect any 404 request to the top-level index.html file ( https://stackoverflow.com/a/34104534/797 ) 要做到这一点,据我所知,我需要将任何404请求重定向到顶级index.html文件( https://stackoverflow.com/a/34104534/797

I figured the way to do that was to give the ContextHandler and ErrorHandler which redirected all 404 requests back to /index.html with something like the code below (I'm actually doing it in a context xml file, but the code might be easier to conceptualize/debug). 我认为这样做的方法是给ContextHandler和ErrorHandler,它将所有404请求重定向回/index.html,类似下面的代码(我实际上是在上下文xml文件中做的,但代码可能更容易概念化/调试)。

What I see is that my error handler is completely ignored, and I'm not sure how to fix that or, alternately, how I ought be configuring things instead. 我看到的是我的错误处理程序被完全忽略了,我不知道如何解决这个问题,或者我不知道应该如何配置。


import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.servlet.ErrorPageErrorHandler;

public class JettyTest {

    public static void main(String[] args) throws Exception {
        Server server = new Server(8080);

        ResourceHandler resourceHandler = new ResourceHandler();
        resourceHandler.setResourceBase("/tmp/directory-with-just-an-index.html-file");

        ContextHandler contextHandler = new ContextHandler("/context-path");

        ErrorPageErrorHandler errorHandler = new ErrorPageErrorHandler();
        errorHandler.addErrorPage(404, "/index.html");

        contextHandler.setHandler(resourceHandler);
        contextHandler.setErrorHandler(errorHandler);

        server.setHandler(contextHandler);

        server.start();
        System.out.println("Started!");
        server.join();
    }

}

Stepping through the Jetty code for a request like http://localhost:8080/context-path/some-file-which-is-not-present.html , what I see is that the ResourceHandler finds no matching files in it's resourceBase, and then calls... 逐步执行Jetty代码以获取http:// localhost:8080 / context-path / some-file-which-not-present.html等请求,我看到的是ResourceHandler在其资源库中找不到匹配的文件,然后打电话给......

    //no resource - try other handlers
    super.handle(target, baseRequest, request, response);
    return;

...then we bubble up out of the ContextHandler and eventually HttpChannelOverHttp sends out a 404 because the request isn't considered to have been handled. ...然后我们从ContextHandler中冒出来,最终HttpChannelOverHttp发出404,因为该请求不被认为已被处理。

    if (!_response.isCommitted() && !_request.isHandled())
        _response.sendError(404);

Perhaps Jetty is expecting ResourceHandler to signal the 404 error in some different way? 也许Jetty期望ResourceHandler以某种不同的方式发出404错误的信号? Or more likely, I'm failing to account for something in the way I'm configuring things. 或者更可能的是,我没有按照我配置的方式来解释某些事情。

The misconfiguration hint may be that https://www.eclipse.org/jetty/documentation/9.3.x/resource-handler.html mentions for ResourceHandler "Requests for resources that do not exist are let pass (Eg no 404's).", but that leaves me unclear on where to go next other than 'write your own handler' which I'd prefer to avoid. 错误配置提示可能是https://www.eclipse.org/jetty/documentation/9.3.x/resource-handler.html提到的ResourceHandler“请求不存在的资源被允许通过(例如没有404)。” ,但这让我不知道下次去哪里,除了“编写自己的处理程序”,我宁愿避免。

Any pointers much appreciated! 任何指针都非常感谢!

Some amount of banging my head against things brought me to the following, which does do what I want, though I'd still certainly accept an answer which explained why ResourceHandler isn't appropriate for what I want... 一些针对事情的事情让我接受了以下事情,这确实做了我想要的事情,尽管我仍然肯定会接受一个解释为什么ResourceHandler不适合我想要的答案......

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;

public class JettyTest {

    public static void main(String[] args) throws Exception {
        Server server = new Server(8080);

        ServletContextHandler servletContextHandler = new ServletContextHandler();
        servletContextHandler.setContextPath("/context-path");
        servletContextHandler.setResourceBase("/tmp/directory-with-just-an-index.html-file");
        servletContextHandler.addServlet(new ServletHolder(new DefaultServlet()), "/*");

        ErrorPageErrorHandler errorHandler = new ErrorPageErrorHandler();
        errorHandler.addErrorPage(404, "/index.html");

        servletContextHandler.setErrorHandler(errorHandler);

        server.setHandler(servletContextHandler);

        server.start();
        System.out.println("Started!");
        server.join();
    }

}

...Now to try to turn that back into an xml context file :) ...现在尝试将其转换回xml上下文文件:)


...which I eventually did with the following in case anyone needs it later. ...我最终用以下内容做了以防任何人以后需要它。

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">

<Configure class="org.eclipse.jetty.servlet.ServletContextHandler" id="myContext">

    <Set name="contextPath">/context-path</Set>
    <Set name="resourceBase">/tmp/directory-with-just-an-index.html-file</Set>

    <!-- Direct all 404s to index.html (required by Angular's PathLocationStrategy) -->
    <Set name="errorHandler">
        <New class="org.eclipse.jetty.servlet.ErrorPageErrorHandler">
            <Call name="addErrorPage">
                <Arg type="int">404</Arg>
                <Arg type="String">/index.html</Arg>
            </Call>
        </New>
    </Set>

    <Call name="addServlet">
        <Arg><New class="org.eclipse.jetty.servlet.ServletHolder">
            <Arg>
                <New class="org.eclipse.jetty.servlet.DefaultServlet"></New>
            </Arg>
        </New></Arg>
        <Arg>/*</Arg>
    </Call>

</Configure>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM