diff --git a/web-modules/jakarta-servlets-2/pom.xml b/web-modules/jakarta-servlets-2/pom.xml index 0c415b202042..d1c5334d282a 100644 --- a/web-modules/jakarta-servlets-2/pom.xml +++ b/web-modules/jakarta-servlets-2/pom.xml @@ -55,6 +55,26 @@ + + + org.eclipse.jetty + jetty-server + ${jetty.version} + test + + + org.eclipse.jetty + jetty-servlet + ${jetty.version} + test + + + org.eclipse.jetty + jetty-client + ${jetty.version} + test + + @@ -79,6 +99,7 @@ 6.1.0 4.0.0 3.0.0 + 11.0.24 2.11.0 2.0.0-M2 diff --git a/web-modules/jakarta-servlets-2/src/main/java/com/baeldung/context/ContextServlet.java b/web-modules/jakarta-servlets-2/src/main/java/com/baeldung/context/ContextServlet.java new file mode 100644 index 000000000000..548346208b46 --- /dev/null +++ b/web-modules/jakarta-servlets-2/src/main/java/com/baeldung/context/ContextServlet.java @@ -0,0 +1,59 @@ +package com.baeldung.context; + +import jakarta.servlet.ServletConfig; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.annotation.WebServlet; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import java.io.IOException; + +@WebServlet(ContextServlet.PATH) +public class ContextServlet extends HttpServlet { + + protected static final String PATH = "/context"; + + protected static final String LABEL_FROM_HTTP_SERVLET = "1) From HttpServlet: "; + protected static final String LABEL_FROM_SERVLET_CONFIG = "2) From ServletConfig: "; + protected static final String LABEL_FROM_HTTP_SERVLET_REQUEST = "3) From HttpServletRequest: "; + protected static final String LABEL_FROM_HTTP_SESSION = "4) From HttpSession: "; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { + + resp.setContentType("text/plain"); + + // 1. Direct Access From the Servlet + ServletContext contextFromServlet = this.getServletContext(); + resp.getWriter() + .println(LABEL_FROM_HTTP_SERVLET + contextFromServlet); + + resp.getWriter() + .println(); + + // 2. Accessing Through the ServletConfig + ServletConfig config = this.getServletConfig(); + ServletContext contextFromConfig = config.getServletContext(); + resp.getWriter() + .println(LABEL_FROM_SERVLET_CONFIG + contextFromConfig); + + resp.getWriter() + .println(); + + // 3. Getting the Context From the HttpServletRequest (Servlet 3.0+) + ServletContext contextFromRequest = req.getServletContext(); + resp.getWriter() + .println(LABEL_FROM_HTTP_SERVLET_REQUEST + contextFromRequest); + + resp.getWriter() + .println(); + + // 4. Retrieving Through the Session Object + ServletContext contextFromSession = req.getSession() + .getServletContext(); + resp.getWriter() + .println(LABEL_FROM_HTTP_SESSION + contextFromSession); + } +} diff --git a/web-modules/jakarta-servlets-2/src/test/java/com/baeldung/context/BaseServletTest.java b/web-modules/jakarta-servlets-2/src/test/java/com/baeldung/context/BaseServletTest.java new file mode 100644 index 000000000000..c4583ccd8de4 --- /dev/null +++ b/web-modules/jakarta-servlets-2/src/test/java/com/baeldung/context/BaseServletTest.java @@ -0,0 +1,64 @@ +package com.baeldung.context; + +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.junit.jupiter.api.*; + +import java.net.InetSocketAddress; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public abstract class BaseServletTest { + + protected HttpClient httpClient; + protected Server server; + + protected int port() { + return 0; // (random) available port + } + + protected String host() { + return "localhost"; + } + + protected String contextPath() { + return "/"; + } + + @BeforeAll + void startup() throws Exception { + httpClient = new HttpClient(); + httpClient.start(); + + ServletContextHandler context = prepareContextHandler(); + + server = new Server(new InetSocketAddress(host(), port())); + server.setHandler(context); + server.start(); + } + + private ServletContextHandler prepareContextHandler() { + ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); + context.setContextPath(contextPath()); + configure(context); + return context; + } + + protected abstract void configure(ServletContextHandler context); + + @AfterAll + void shutdown() throws Exception { + if (server != null) { + server.stop(); + } + if (httpClient != null) { + httpClient.stop(); + } + } + + protected String baseUri() { + String uri = server.getURI() + .toString(); + return uri.endsWith("/") ? uri.substring(0, uri.length() - 1) : uri; + } +} diff --git a/web-modules/jakarta-servlets-2/src/test/java/com/baeldung/context/ContextServletUnitTest.java b/web-modules/jakarta-servlets-2/src/test/java/com/baeldung/context/ContextServletUnitTest.java new file mode 100644 index 000000000000..c03d6fca8130 --- /dev/null +++ b/web-modules/jakarta-servlets-2/src/test/java/com/baeldung/context/ContextServletUnitTest.java @@ -0,0 +1,67 @@ +package com.baeldung.context; + +import org.apache.http.HttpStatus; +import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.junit.jupiter.api.Test; + +import java.net.URI; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import static org.junit.jupiter.api.Assertions.*; + +class ContextServletUnitTest extends BaseServletTest { + + private static final List CONTEXT_LABELS = List.of(ContextServlet.LABEL_FROM_HTTP_SERVLET, ContextServlet.LABEL_FROM_SERVLET_CONFIG, + ContextServlet.LABEL_FROM_HTTP_SERVLET_REQUEST, ContextServlet.LABEL_FROM_HTTP_SESSION); + + @Override + protected void configure(ServletContextHandler ctx) { + ctx.addServlet(ContextServlet.class, ContextServlet.PATH); + } + + @Test + void givenContextServlet_whenGetRequest_thenResponseContainsSameContextInstance() throws Exception { + ContentResponse response = httpClient.GET(URI.create(baseUri() + ContextServlet.PATH)); + + assertEquals(HttpStatus.SC_OK, response.getStatus()); + + String body = response.getContentAsString(); + + assertContextLinesIn(body); + + List tokens = parseServletContextTokens(body); + assertAllEqual(tokens); + } + + private static void assertContextLinesIn(String body) { + for (String label : CONTEXT_LABELS) { + assertTrue(body.contains(label)); + } + } + + private static List parseServletContextTokens(String body) { + List targetLines = body.lines() + .filter(line -> CONTEXT_LABELS.stream() + .anyMatch(line::startsWith)) + .collect(Collectors.toList()); + + assertEquals(CONTEXT_LABELS.size(), targetLines.size()); + + return targetLines.stream() + .map(line -> { + int indexOf = line.indexOf(':'); + assertTrue(indexOf >= 0); + return line.substring(indexOf + 1) + .trim(); + }) + .collect(Collectors.toList()); + } + + private static void assertAllEqual(List tokens) { + Set distinct = Set.copyOf(tokens); + assertEquals(1, distinct.size()); + } +}