1. Create simplest project with HttpServlet and JSP.
me@MacBook:~/dev/my-servlet$ find . -type f | grep -v .idea | grep -v target | grep -v *.iml ./pom.xml ./src/main/webapp/index.html ./src/main/webapp/redirected.jsp ./src/main/webapp/forwarded.jsp ./src/main/java/com/bawi/servlet/MyServlet.java
./pom.xml:
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.bawi</groupId> <artifactId>my-servlet</artifactId> <packaging>war</packaging> <version>0.1-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>3.3.1</version> </plugin> <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>9.4.35.v20201120</version> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> </dependencies> </project>
./src/main/java/com/bawi/servlet/MyServlet.java:
package com.bawi.servlet; import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Date; @WebServlet(urlPatterns = {"/do"}) public class MyServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String action = req.getParameter("action"); if (action == null) { resp.setContentType("text/plain;charset=UTF-8"); ServletOutputStream out = resp.getOutputStream(); out.print("Hello from MyServlet!" + new Date()); return; } switch (action) { case "forward": { ServletContext servletContext = getServletContext(); RequestDispatcher dispatcher = servletContext.getRequestDispatcher("/forwarded.jsp"); dispatcher.forward(req, resp); break; } case "redirect": { resp.sendRedirect(req.getContextPath() + "/redirected.jsp"); break; } } } }
./src/main/webapp/index.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Home page</title> </head> <body> <p>This is home page.</p> <p>Call <a href="/do?action=forward">forward</a></p> <p>Call <a href="/do?action=redirect">redirect</a></p> </body> </html>
./src/main/webapp/forwarded.jsp:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Forwarded page</title> </head> <body> <p>Action parameter: <%= request.getParameter("action") %>. This is forwarded page. Go to <a href="/">home</a></p> </body> </html>
./src/main/webapp/redirected.jsp:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Redirected page</title> </head> <body> <p>Action parameter: <%= request.getParameter("action") %>. This is redirected page. Go to <a href="/">home</a></p> </body> </html>
me@MacBook:~/dev/my-servlet$ mvn jetty:run
[INFO] webAppSourceDirectory not set. Trying src/main/webapp [INFO] Reload Mechanic: automatic [INFO] nonBlocking:false [INFO] Classes = /Users/me/dev/my-servlet/target/classes [INFO] Configuring Jetty for project: my-servlet [INFO] Logging initialized @3943ms to org.eclipse.jetty.util.log.Slf4jLog [INFO] Context path = / [INFO] Tmp directory = /Users/me/dev/my-servlet/target/tmp [INFO] Web defaults = org/eclipse/jetty/webapp/webdefault.xml [INFO] Web overrides = none [INFO] web.xml file = null [INFO] Webapp directory = /Users/me/dev/my-servlet/src/main/webapp [INFO] jetty-9.4.35.v20201120; built: 2020-11-20T21:17:03.964Z; git: bdc54f03a5e0a7e280fab27f55c3c75ee8da89fb; jvm 1.8.0_241-b07 [INFO] Scanning elapsed time=26ms [INFO] DefaultSessionIdManager workerName=node0 [INFO] No SessionScavenger set, using defaults [INFO] node0 Scavenging every 660000ms [INFO] Started o.e.j.m.p.JettyWebAppContext@760cf594{/,file:///Users/me/dev/my-servlet/src/main/webapp/,AVAILABLE}{file:///Users/me/dev/my-servlet/src/main/webapp/} [INFO] Started ServerConnector@254f906e{HTTP/1.1, (http/1.1)}{0.0.0.0:8080} [INFO] Started @4422ms [INFO] Started Jetty Server
2. Testing
curl http://localhost:8080/do
Hello from MyServlet!Wed Dec 02 15:09:17 CET 2020
forward
Note action parameter is passed automatically
me@MacBook:~$ curl -vv http://localhost:8080/do?action=forward
* Trying ::1... * TCP_NODELAY set * Connected to localhost (::1) port 8080 (#0) > GET /do?action=forward HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/7.64.1 > Accept: */* > < HTTP/1.1 200 OK < Date: Wed, 02 Dec 2020 14:11:26 GMT < Content-Type: text/html;charset=utf-8 < Set-Cookie: JSESSIONID=node0vruwimbjjsy5uwywzhy51gy81.node0; Path=/ < Expires: Thu, 01 Jan 1970 00:00:00 GMT < Content-Length: 248 < Server: Jetty(9.4.35.v20201120) < <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Forwarded page</title> </head> <body> <p>Action parameter: forward. This is forwarded page. Go to <a href="/">home</a></p> </body> * Connection #0 to host localhost left intact </html>* Closing connection 0
redirect
Note response code is 302 and redirect location is returned.
me@MacBook:~$ curl -vv http://localhost:8080/do?action=redirect
* Trying ::1... * TCP_NODELAY set * Connected to localhost (::1) port 8080 (#0) > GET /do?action=redirect HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/7.64.1 > Accept: */* > < HTTP/1.1 302 Found < Date: Wed, 02 Dec 2020 14:11:39 GMT < Location: http://localhost:8080/redirected.jsp < Content-Length: 0 < Server: Jetty(9.4.35.v20201120) < * Connection #0 to host localhost left intact * Closing connection 0
With option to follow redirect location:
Note action parameter is NOT passed to second request.
me@MacBook:~$ curl -v -L http://localhost:8080/do?action=redirect
* Trying ::1... * TCP_NODELAY set * Connected to localhost (::1) port 8080 (#0) > GET /do?action=redirect HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/7.64.1 > Accept: */* > < HTTP/1.1 302 Found < Date: Wed, 02 Dec 2020 17:14:59 GMT < Location: http://localhost:8080/redirected.jsp < Content-Length: 0 < Server: Jetty(9.4.35.v20201120) < * Connection #0 to host localhost left intact * Issue another request to this URL: 'http://localhost:8080/redirected.jsp' * Found bundle for host localhost: 0x7fe33a818310 [can pipeline] * Could pipeline, but not asked to! * Re-using existing connection! (#0) with host localhost * Connected to localhost (::1) port 8080 (#0) > GET /redirected.jsp HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/7.64.1 > Accept: */* > < HTTP/1.1 200 OK < Date: Wed, 02 Dec 2020 17:14:59 GMT < Content-Type: text/html;charset=utf-8 < Set-Cookie: JSESSIONID=node0gd5vxmsu6xgkh3ltwabj2jh810.node0; Path=/ < Expires: Thu, 01 Jan 1970 00:00:00 GMT < Content-Length: 247 < Server: Jetty(9.4.35.v20201120) < <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Redirected page</title> </head> <body> <p>Action parameter: null. This is redirected page. Go to <a href="/">home</a></p> </body> * Connection #0 to host localhost left intact </html>* Closing connection 0
3. Automatically reload classes and resources when debugging (change is seen after first request)
me@MacBook:~$ curl http://localhost:8080/do
Hello from MyServlet!Wed Dec 02 18:47:14 CET 2020
Now modify servlet java code
first request to trigger reloading
me@MacBook:~$ curl http://localhost:8080/do
Hello from MyServlet!Wed Dec 02 18:48:03 CET 2020
second request returns modified response
me@MacBook:~$ curl http://localhost:8080/do
Hello from MyServlet! - modifiedWed Dec 02 18:48:07 CET 2020