How to programmatically display jsp

I use jetty. The task is to output jsp without using the web.xml, just through the code. How do I do this?

Tried to use the code: request.getRequestDispatcher("webapp/index.jsp").forward(request, resp);

But it knocks out StackOverflowError.

Author: Nofate, 2016-02-17

1 answers

To begin with, about what index does not see.jsp, the answer is not correct.

If you are talking about my answer, then you should not mark it as correct if it is incorrect (which is incorrect). It was necessary to add details to the original question.

For starters, the fact that it's just about a line of code.

There are no problems with the line of code. I wrote to you for the first time that JSP processing requires additional initialization. JSP is not just a template for HTML, which you will give it to the response. This is the source code for compiling a separate servlet class, which in turn will already form the final HTML and give it to the user.

Anyway... The demo that I offered you to watch is more than workable. It took about 20 minutes to adapt to your conditions.

We look.


The folder structure that is standard for maven:

src
- main
| - java
| | - demo
| |   - App.java
| |   - PageServlet1.java
| - resources
|   - webapp
|     - index.jsp
pom.xml

Index.jsp - without changes

<!DOCTYPE html>
<html lang="en">
<head>
    <title>SO question 2370960</title>
</head>
<body>
<p>Message: ${message}</p>
</body>
</html>

PageServlet1.java

public class PageServlet1 extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        String message = "Hello World";
        request.setAttribute("message", message); // This will be available as ${message}
        request.getRequestDispatcher("/index.jsp").forward(request, response);
    }
}

App.java

package demo;

import org.apache.tomcat.InstanceManager;
import org.apache.tomcat.SimpleInstanceManager;
import org.eclipse.jetty.apache.jsp.JettyJasperInitializer;
import org.eclipse.jetty.jsp.JettyJspServlet;
import org.eclipse.jetty.plus.annotation.ContainerInitializer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;


public class App 
{
    public static void main(String[] args) throws IOException, URISyntaxException {
        Server server = new Server(1600);
        // указываем базовый путь к директории webapp в ресурсах
        URI baseUri = App.class.getResource("/webapp").toURI();

        // отключаем использование компилятора Eclipse JDT, но для запуска потребуется JDK, а не JRE
        System.setProperty("org.apache.jasper.compiler.disablejsr199", "false");

        JettyJasperInitializer sci = new JettyJasperInitializer();
        ContainerInitializer initializer = new ContainerInitializer(sci, null);
        List<ContainerInitializer> initializers = new ArrayList<ContainerInitializer>();
        initializers.add(initializer);

        // Инициализация контекста
        ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
        context.setContextPath("/");
        // временная директория требуется для компиляции JSP
        context.setAttribute("javax.servlet.context.tempdir", getScratchDir());
        context.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",
                ".*/[^/]*servlet-api-[^/]*\\.jar$|.*/javax.servlet.jsp.jstl-.*\\.jar$|.*/.*taglibs.*\\.jar$");
        context.setResourceBase(baseUri.toASCIIString());
        context.setAttribute("org.eclipse.jetty.containerInitializers", initializers);
        context.setAttribute(InstanceManager.class.getName(), new SimpleInstanceManager());

        // по спецификации JSP стандартный загрузчик классов не годится, используем URLClassLoader
        context.setClassLoader(new URLClassLoader(new URL[0], App.class.getClassLoader()));

        // Наконец, создаем сервлет для обработки JSP. Он обязан называться "jsp" 
        ServletHolder holderJsp = new ServletHolder("jsp", JettyJspServlet.class);
        holderJsp.setInitOrder(0);
        holderJsp.setInitParameter("logVerbosityLevel", "DEBUG");
        holderJsp.setInitParameter("fork", "false");
        holderJsp.setInitParameter("xpoweredBy", "false");
        holderJsp.setInitParameter("compilerTargetVM", "1.7");
        holderJsp.setInitParameter("compilerSourceVM", "1.7");
        holderJsp.setInitParameter("keepgenerated", "true");
        context.addServlet(holderJsp, "*.jsp");

        // Также должен существовать сервлет с именем "default". Это будет ваш PageServlet1
        ServletHolder holderDefault = new ServletHolder("default", PageServlet1.class);
        holderDefault.setInitParameter("resourceBase", baseUri.toASCIIString());
        holderDefault.setInitParameter("dirAllowed", "true");
        context.addServlet(holderDefault, "/");

        // Поехали
        server.setHandler(context);

        try {
            server.start();
            server.join();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    // Вспомогательный метод, создающий временную директорию. Хорошо бы ее удалять после использования.
    private static File getScratchDir() throws IOException {
        File tempDir = new File(System.getProperty("java.io.tmpdir"));
        File scratchDir = new File(tempDir.toString(), "embedded-jetty-jsp");

        if (!scratchDir.exists())
        {
            if (!scratchDir.mkdirs())
            {
                throw new IOException("Unable to create scratch directory: " + scratchDir);
            }
        }
        return scratchDir;
    }
}

The CLASSPATH must contain all the necessary libraries. If you use maven, here are the dependencies:

<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-server</artifactId>
    <version>9.3.7.v20160115</version>
</dependency>

<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-http</artifactId>
    <version>9.3.7.v20160115</version>
</dependency>

<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-servlet</artifactId>
    <version>9.3.7.v20160115</version>
</dependency>
<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-webapp</artifactId>
    <version>9.3.7.v20160115</version>
</dependency>
<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>apache-jsp</artifactId>
    <version>9.3.7.v20160115</version>
</dependency>
<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-runner</artifactId>
    <version>9.3.7.v20160115</version>
</dependency>
 4
Author: Nofate, 2016-02-17 21:50:19