diff --git a/2-0-servlet-api/2-0-1-date-servlet-api/README.MD b/2-0-servlet-api/2-0-1-date-servlet-api/README.MD new file mode 100644 index 0000000..b8999b8 --- /dev/null +++ b/2-0-servlet-api/2-0-1-date-servlet-api/README.MD @@ -0,0 +1,45 @@ +# Welcome Date Servlet +Your first acquaintance with Servlets, JSP and servlet Container πŸ‘€ + +[Servlets are the Java platform technology of choice for extending and enhancing Web servers.](https://www.oracle.com/java/technologies/servlet-technology.html) + +### Pre-conditions ❗ +You're supposed to be familiar with [Java Fundamentals](https://github.com/bobocode-projects/java-fundamentals-course) + +### Objectives +* **install** [Apache Tomcat Container](https://tomcat.apache.org/download-90.cgi) if you didn't βœ… + + -*Servlets don’t have any main() method. Instead, are used Containers to control Servlets. + Containers are other Java applications such as Tomcat, GlassFish or Jetty. You have to install one of it if you didn't. + We suggest to use Tomcat as more lightweight and easier in configuration.* +* βš™ **configure a Container** depending on your environment βœ… + - [IntelliJ IDEA:](https://www.jetbrains.com/help/idea/run-debug-configuration-tomcat-server.html) + 1. Create a new server configuration: + + **Run** β–Ά **Edit configurations...** β–Ά (βž•)Add New Configuration β–Ά Tomcat Server (Local) + 2. Configure or choose Application Server in **Run/Debug Configurations**: + + **Server** tab β–Ά **Configure** β–Ά (βž•)**Add Application Server** β–Ά Add a path to folder with Tomcat + 3. Deploy welcome-servlet application into Container in **Run/Debug Configurations**: + + **Deployment** tab β–Ά (βž•)Artifact β–Ά `welcome-servlet:war exploded` β–Ά ❗ Clear **Application Context** field + + - Eclipse + - Open Eclipse Java EE (Enterprise edition ) environment. Click on Servers tab at bottom. Click on No servers are available. + - A dialog box will appear. Select Tomcat 9.0 server folder. Click Next. + - Browse to Apache Tomcat 9.0 folder select it. Click Finish. +* **create a new Servlet** with a name `DateServlet` βœ… + 1. Create a new class `DateServlet` in the same package + 2. Extend the class from `HttpServlet` + 3. Annotate the class as `@WebServlet` with parameter `"/date""` to create a path to the servlet. + 4. Override `doGet` method to return present date in the response using `LocalDate.now()`. +* **run `DateServletTest`** to check your code βœ… +* **run configured server** βœ… + - If everything is configured properly, the server should run `WelcomeServlet` on [http://localhost:8080/](http://localhost:8080/) +* **send request to `DateServlet`** using [http://localhost:8080/date](http://localhost:8080/date) URL in order to get present date βœ… + +### Related Materials ℹ️ +todo + +--- +#### πŸ†• First time here? – [See Introduction](https://github.com/bobocode-projects/java-fundamentals-course/tree/main/0-0-intro#introduction) diff --git a/2-0-servlet-api/2-0-1-date-servlet-api/pom.xml b/2-0-servlet-api/2-0-1-date-servlet-api/pom.xml new file mode 100644 index 0000000..b1c6a26 --- /dev/null +++ b/2-0-servlet-api/2-0-1-date-servlet-api/pom.xml @@ -0,0 +1,46 @@ + + + + 2-0-servlet-api + com.bobocode + 1.0-SNAPSHOT + + 4.0.0 + + 2-0-1-date-servlet-api + war + + + 11 + 11 + UTF-8 + UTF-8 + + + + + org.mockito + mockito-core + 3.8.0 + test + + + org.mockito + mockito-junit-jupiter + 3.8.0 + test + + + + + + + org.apache.maven.plugins + maven-war-plugin + 3.3.0 + + + + \ No newline at end of file diff --git a/2-0-servlet-api/2-0-1-date-servlet-api/src/main/java/com/bobocode/servlet/WelcomeServlet.java b/2-0-servlet-api/2-0-1-date-servlet-api/src/main/java/com/bobocode/servlet/WelcomeServlet.java new file mode 100644 index 0000000..d6c54a4 --- /dev/null +++ b/2-0-servlet-api/2-0-1-date-servlet-api/src/main/java/com/bobocode/servlet/WelcomeServlet.java @@ -0,0 +1,41 @@ +package com.bobocode.servlet; + +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.io.PrintWriter; + +/** + * To create a servlet you have to extend your class from {@link HttpServlet}. + * Also add annotation {@link WebServlet} with parameter to map a path for URL. + */ +@WebServlet("/") +public class WelcomeServlet extends HttpServlet { + + /** + * This method is overridden from {@link HttpServlet} class. + * It called by the server (container) to allow servlets to handle GET requests. + * + * @param request an {@link HttpServletRequest} object that contains the request + * the client has made of the servlet. + * @param response an {@link HttpServletResponse} object that contains the response + * the servlet sends to the client. + */ + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { + response.setContentType("text/html"); + + PrintWriter out = response.getWriter(); + + out.println(""); + out.println(""); + out.println("

" + "Good job! This page is a response of WelcomeServlet object." + "

"); + out.println("

" + "You should create your own class DateServlet which returns " + + "current date as a response on /date path.
Use LocalDate.now() " + + "to get current date." + "

"); + out.println(""); + } +} \ No newline at end of file diff --git a/2-0-servlet-api/2-0-1-date-servlet-api/src/test/java/com/bobocode/DateServletTest.java b/2-0-servlet-api/2-0-1-date-servlet-api/src/test/java/com/bobocode/DateServletTest.java new file mode 100644 index 0000000..acb0053 --- /dev/null +++ b/2-0-servlet-api/2-0-1-date-servlet-api/src/test/java/com/bobocode/DateServletTest.java @@ -0,0 +1,114 @@ +package com.bobocode; + +import org.junit.jupiter.api.*; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.reflections.Reflections; + +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.io.PrintWriter; +import java.io.StringWriter; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.time.LocalDate; +import java.util.Optional; +import java.util.Set; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + + +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +@ExtendWith(MockitoExtension.class) +public class DateServletTest { + + @Mock + private HttpServletRequest request; + + @Mock + private HttpServletResponse response; + + @Mock + private ServletOutputStream outputStream; + + private Object dateServletObject; + private Class dateServletClass; + + public static final String SERVLET_PACKAGE = "com.bobocode.servlet"; + public static final String DATE_SERVLET = "DateServlet"; + Reflections reflections; + + @BeforeEach + public void init() throws ClassNotFoundException, IllegalAccessException, InvocationTargetException, + InstantiationException { + reflections = new Reflections(SERVLET_PACKAGE); + dateServletClass = Class.forName(SERVLET_PACKAGE + "." + DATE_SERVLET); + dateServletObject = dateServletClass.getConstructors()[0].newInstance(); + } + + @Test + @Order(1) + void dateServletClassExists() throws ClassNotFoundException { + Class.forName(SERVLET_PACKAGE + "." + DATE_SERVLET); + } + + @Test + @Order(2) + void dateServletExtendsHttpServlet() { + + Set> httpServlets = + reflections.getSubTypesOf(HttpServlet.class); + + Optional anyDateHttpServlet = httpServlets.stream() + .map(Class::getSimpleName) + .filter(servlet -> servlet.equals(DATE_SERVLET)) + .findAny(); + assertThat(anyDateHttpServlet).isNotEmpty(); + } + + @Test + @Order(3) + void dateServletIsMarkedAsWebServlet() { + Set> servlets = + reflections.getTypesAnnotatedWith(WebServlet.class); + Optional anyMarkedDateServlet = servlets.stream() + .map(Class::getSimpleName) + .filter(servlet -> servlet.equals(DATE_SERVLET)) + .findAny(); + assertThat(anyMarkedDateServlet).isNotEmpty(); + } + + @Test + @Order(4) + void dateServletIsMarkedWithProperPath() throws ClassNotFoundException { + String[] value = Class.forName(SERVLET_PACKAGE + "." + DATE_SERVLET) + .getAnnotation(WebServlet.class).value(); + assertThat(value).contains("/date"); + } + + @Test + @Order(5) + void dateServletReturnsDateInResponse() throws IOException, NoSuchMethodException, InvocationTargetException, + IllegalAccessException { + Method doGetMethod = getDoGetMethod(); + + StringWriter stringWriter = new StringWriter(); + PrintWriter printWriter = new PrintWriter(stringWriter); + when(response.getWriter()).thenReturn(printWriter); + + doGetMethod.invoke(dateServletObject, request, response); + assertThat(stringWriter.getBuffer().toString()).contains(LocalDate.now().toString()); + } + + private Method getDoGetMethod() throws NoSuchMethodException { + return dateServletClass + .getMethod("doGet", HttpServletRequest.class, HttpServletResponse.class); + } +} \ No newline at end of file diff --git a/2-0-servlet-api/pom.xml b/2-0-servlet-api/pom.xml index 47419d4..1090242 100644 --- a/2-0-servlet-api/pom.xml +++ b/2-0-servlet-api/pom.xml @@ -10,5 +10,19 @@ 4.0.0 2-0-servlet-api + pom + + 2-0-1-date-servlet-api + + + + + + javax.servlet + javax.servlet-api + 4.0.1 + provided + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 674ac9d..483c8b6 100644 --- a/pom.xml +++ b/pom.xml @@ -23,5 +23,29 @@ 11 - + + + org.junit.jupiter + junit-jupiter-engine + 5.7.0 + test + + + org.junit.jupiter + junit-jupiter-params + 5.7.0 + test + + + org.assertj + assertj-core + 3.18.1 + test + + + org.reflections + reflections + 0.9.12 + + \ No newline at end of file