perwendel / spark

A simple expressive web framework for java. Spark has a kotlin DSL https://github.com/perwendel/spark-kotlin
Apache License 2.0
9.64k stars 1.56k forks source link

Enable custom error pages, when deploy Sparkjava embedded by (Jetty) #197

Closed winterdl closed 7 years ago

winterdl commented 10 years ago

Jetty 9 config

<error-page>
        <error-code>404</error-code>
        <location>/errors/404.html</location>
</error-page>

When access /not_exists, current 404 error page return by Sparkjava embedded by Jetty is:

HTTP ERROR 404

Problem accessing /errors/404.html. Reason:

    Not Found

Powered by Jetty://

Expectation

Url should redirect from: /not_exists to /errors/404.html

jgangemi commented 9 years ago

this requires a custom error handler to be installed in order to fix.

question: how put off would you be if you couldn't configure this via the static interface and instead had to use a builder to get a spark instance? eg:

SparkServerBuilder serverBuilder = JettyServerBuilder.builder().<set options>.build();
SparkApi spark = SparkBuilder.build(serverBuilder).<set options>.build();

<setup routes, filters, etc>

spark.start();
debarshri commented 9 years ago

I am not sure if it would work like that..

The way it spark works is when there is 404 error, The body content is assigned to NOT_FOUND constant.. I think you can rewrite bodycontent when there is no match in the MatchFilter class. To be more specific, if there is NotConsumedException then we can rewrite the bodyContent and set header as 404. I am not sure if thats the right way to do it. For example,

 if (!consumed && hasOtherHandlers) {
      LOG.info("The requested route [" + uri + "] has not been mapped in Spark");
     httpResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
     bodyContent = String.format(NOT_FOUND);
    consumed = true;
     //  throw new NotConsumedException();
}

NOT_FOUND can be assigned to your custom html code. May be we can have a singleton that reads from resource directory where your custom page exists.

debarshri commented 9 years ago

I think this would kinda solve the problem.

dachaoli commented 8 years ago

After spending a few days scraping through the internet, reading jetty documents, and actually read spark's source code, I was able to combine the last comment(by Rob Eden) on this article: https://gsmblog.net/blog/spark-framework-the-tiny-framework-that-almost-could/ with stuff I learned from jetty and spark, to come up with a work around like this:

public static void main(String[] args) throws Exception {
    // Start can configure Jetty
    Server server = new Server(8080);
    WebAppContext webapp = new WebAppContext();
    webapp.setContextPath("/");
    webapp.setResourceBase("FULL_PATH_TO_MY_STATIC_FILE_FOLDER");

    // Not sure if this is needed, but it worked for me without it 
    //webapp.setWar( "/" );

    // Hooking up Spark
    // The Java equivalent of http://sparkjava.com/documentation.html#other-webserver
    FilterHolder holder = webapp.addFilter(
            SparkFilter.class,
            "/*",
            EnumSet.of(DispatcherType.REQUEST)
    );

    holder.setInitParameter(
            "applicationClass",
            MySparkFilter.class.getName()
    );

    // Setting up your custom error pages
    ErrorPageErrorHandler errorHandler = new ErrorPageErrorHandler();
    // The file is at FULL_PATH_TO_MY_STATIC_FILE_FOLDER/404.html
    errorHandler.addErrorPage(HttpServletResponse.SC_NOT_FOUND, "/404.html");
    webapp.setErrorHandler(errorHandler);

    server.setHandler(webapp);

    // Starting the Server
    server.start();
    System.out.println("Started!");
    server.join();
}

And MySparkFiter.java is like this

public class MySparkFilter implements SparkApplication {
    @Override
    public void init() {
        get("/hello", (req, res) -> "Hello World");
    }
}

So basically I'm starting and configuring the Jetty that comes with Spark, and deploy Spark to it, instead of letting Spark start Jetty with its defaults.

kshep92 commented 8 years ago

See my proposal for a short term fix for this in #555 It follows the same pattern of Play 1.x where you just drop in a 404.html and a 500.html in your resources folder. If the files aren't present then the default error pages (the ones we see now) are shown.

tipsy commented 7 years ago

Added in #719