Несколько контекстных путей в одном файле jetty-web.xml для приложения JAX-RS, работающего на сервере Tomcat - PullRequest
0 голосов
/ 25 октября 2019

Я видел версии этого вопроса и даже одну версию из несколько лет назад , это именно то, о чем я спрашиваю, но, увы, ответа на этот вопрос не было. Итак, вот и все: у меня есть веб-приложение на основе Tomcat, которое может принимать различные формы в зависимости от настроек нескольких встроенных файлов JSON. Я пытаюсь использовать URL-адрес в качестве основы для информирования приложения о том, какую версию использовать, вместо создания нескольких экземпляров приложения для каждой отдельной конфигурации.

Текущая версия:

http://<server>/Version1, http://<server>/Version2, http://<server>/Version3

одно и то же приложение, три файла WAR, просто переименованные друг от друга / один контекстный путь к серверу каждый

Предпочтение:

http://<server>/Version1, http://<server>/Version2, http://<server>/Version3

одно приложение / один файл WAR / три пути к контексту сервера

Возможно ли это? Если так, как это достигнуто? Если нет, у кого-нибудь есть умная идея?

Примечание: ни Maven, ни Gradle не используются.

1 Ответ

0 голосов
/ 26 октября 2019

Вы уверены, что хотите несколько контекстных путей?

Даже если у вас есть 1 война и 3 контекстных пути, эта война будет загружена 3 раза, и каждый из них будет изолирован друг от друга (загрузчик классов, экземпляры объектов). , сеансы, файлы cookie, ресурсы и т. д.)

С другой стороны, вы можете выполнить некоторые пользовательские манипуляции с URI перед одним веб-приложением.

Вот пример загрузки одного WebApp (войны)в корневом контексте (/) только один раз, а затем HandlerWrapper (концепция Jetty), который выполняет идентификацию версии URI и манипулирование URI, с атрибутом запроса, используемым для передачи версии обратно веб-приложению и его сервлетам.

package jetty;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URI;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.resource.PathResource;
import org.eclipse.jetty.webapp.WebAppContext;

import static java.nio.charset.StandardCharsets.UTF_8;

/**
 * This is a single Webapp on root, and a Handler that identifies a URI pattern
 * and informs the webapp what version to use.
 */
public class UriIdentifiedBehaviorDemo
{
    public static void main(String[] args) throws Exception
    {
        Server server = new Server(8080);

        WebAppContext webapp = createWebApp();
        webapp.setContextPath("/"); // root

        UriVersionHandler uriVersionHandler = new UriVersionHandler();
        uriVersionHandler.setHandler(webapp);

        server.setHandler(uriVersionHandler);
        server.start();

        try
        {
            // direct access
            demoCall(server.getURI().resolve("/demo/"));
            // attempt at version, but missing number
            demoCall(server.getURI().resolve("/version/demo/"));
            // versioned
            demoCall(server.getURI().resolve("/version1/demo/"));
            demoCall(server.getURI().resolve("/version99/demo/"));
        }
        finally
        {
            server.stop();
        }
    }

    private static void demoCall(URI destUri) throws IOException
    {
        HttpURLConnection http = (HttpURLConnection)destUri.toURL().openConnection();
        int statusCode = http.getResponseCode();
        System.out.printf("GET [%s] resulted in Response Status Code [%d]%n", 
            destUri, statusCode);

        if (statusCode != HttpURLConnection.HTTP_OK)
        {
            return;
        }

        try (InputStream in = http.getInputStream())
        {
            String responseBody = IO.toString(in, UTF_8);
            System.out.printf("Response Body: %s%n", responseBody);
        }
    }

    private static WebAppContext createWebApp()
    {
        WebAppContext webapp = new WebAppContext();
        Path warPath = Paths.get("src/main/wars/webapp-a.war");
        webapp.setBaseResource(new PathResource(warPath));

        webapp.addServlet(DemoServlet.class, "/demo/*");

        return webapp;
    }

    public static class DemoServlet extends HttpServlet
    {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException
        {
            resp.setContentType("text/plain");
            resp.setCharacterEncoding("utf-8");
            PrintWriter out = resp.getWriter();
            out.printf("Version (header) is [%s]%n", 
                req.getAttribute("my.uri.version"));
        }
    }

    public static class UriVersionHandler extends HandlerWrapper
    {
        @Override
        public void handle(String target, 
                           Request baseRequest, 
                           HttpServletRequest request, 
                           HttpServletResponse response) 
            throws IOException, ServletException
        {
            String actualTarget = target;
            String requestPath = baseRequest.getHttpURI().getPath();
            Pattern pat = Pattern.compile("^\\/version([0-9]+)\\/");
            Matcher mat = pat.matcher(requestPath);
            if (mat.find())
            {
                // we are in a version identified syntax!
                String version = mat.group(1);
                request.setAttribute("my.uri.version", version);
                actualTarget = requestPath.substring(mat.end(1));
            }

            getHandler().handle(actualTarget, baseRequest, request, response);
        }
    }

}

, который показывает следующий вывод ...

GET [http://127.0.1.1:8080/demo/] resulted in Response Status Code [200]
Response Body: Version (header) is [null]

GET [http://127.0.1.1:8080/version/demo/] resulted in Response Status Code [404]
GET [http://127.0.1.1:8080/version1/demo/] resulted in Response Status Code [200]
Response Body: Version (header) is [1]

GET [http://127.0.1.1:8080/version99/demo/] resulted in Response Status Code [200]
Response Body: Version (header) is [99]

К вашему сведению, этот вид спекулятивного вопроса лучше всего подходит для списка рассылки jetty-users , иликак проблема на Eclipse Jetty Issue tracker (как вопрос).

...