JavaRush /Java Blog /Random EN /Creating a simple web application with servlets and jsp (...
Стас Пасинков
Level 26
Киев

Creating a simple web application with servlets and jsp (part 1)

Published in the Random EN group
The level of knowledge required to understand the article: you have already more or less figured out Java Core and would like to look at JavaEE technologies and web programming. It is most logical if you are currently studying the Java Collections quest, which deals with topics similar to the article. Creating a simple web application on servlets and jsp (part 1) - 1This material is a logical continuation of my article Creating a Basic Web Project in IntelliJ Idea Enterprise . In it, I demonstrated how to create a working web project template. This time, I'll show you how to create a simple yet pretty web application using the Java Servlet API and JavaServer Pages API technologies. Our application will have a main page with two links:
  • to the page for adding a user;
  • to the user list view page.
I will continue to use IntelliJ Idea Enterprise Edition, Apache Maven (just include a few dependencies) and Apache Tomcat. In the end, we will “decorate” our application using the W3.CSS framework . We will assume that at the moment you already have an empty project, which we will develop here. If not, go over the first article and make it. It only takes a few minutes :)

A little about the structure of the future application

The main page ( / ) will be the most common static html page with a header and two links / buttons:
  • add a new user (will send to /add );
  • View a list of users (sends to /list ).
Requests to these addresses will be caught by Tomcat and sent to one of the two servlets that we will make (we will write the mapping in the web.xml file ). And servlets, in turn, will process requests, prepare data (or save them if a user is added), and transfer control to the corresponding jsp files, which will already “draw” the result. We will store the data in the most common list (List).

Create a static homepage

If you have index.jsp in your web folder , delete it. Instead, in this folder, create a simple html file called index.html :
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>My super project!</title>
</head>
<body>
    <!-- header -->
    <div>
        <h1>Super app!<//h1>
    </div>

    <div>       <!-- content -->
        <div>    <!-- buttons holder -->
            <button onclick="location.href='/list'">List users<//button>
            <button onclick="location.href='/add'">Add user<//button>
        </div>
    </div>
</body>
</html>
There's nothing complicated here. The title is the title of our page. In the body of the page, we have two main divs: header (header) and content (content). In the content, we have a holder for our buttons, and, in fact, two buttons that, when pressed, are sent to the corresponding addresses. You can run the project and see what it looks like now. If you click on the buttons, 404 error pages open, because we don't have them yet. But it says that the buttons work. I note that this is not the most universal option, because if you suddenly have JavaScript disabled, these buttons are of no use in the browser. But let's assume that no one turned off JavaScript :). It is clear that simple links could be dispensed with, but I prefer buttons. You do as you please. And do not look that there will be many divs in my examples-ov. Then we will fill them with styles, and everything will look more beautiful :).

Create jsp files to render the result

In the same web directory , we will create a folder where we will put our jsp files . I called it views, but again, you can improvise. In this folder we will create two jsp files:
  • add.jsp - page for adding users;
  • list.jsp - page for displaying a list of users.
Let's give them the appropriate page titles. Something like "Add new user" and "Users list" and leave it like that for now.

Let's create two servlets

Servlets will accept and process requests that Tomcat will pass to them. In the src/main/java folder, let's create the app package , which will contain our sources. There we will have more different packages. Therefore, so that these packages are not created inside each other, let's create some class in the app package (then delete it). Now let's create three different packages in the app package:
  • entities - our entities will lie here (the class itself, which will describe user objects);
  • model - our model will be here (more on this later);
  • servlets - well, here will be our servlets.
After that, that class from the app package can be safely removed (if you created it, of course). Let's create two classes in the servlets package:
  • AddServlet - will process requests received at / add ;
  • ListServlet - will process requests received at / list .

Connecting dependencies in Maven

Tomcat version 9.* implements the Servlet version 4.0 and JavaServer Pages version 2.3 specifications. This is written in the official documentation of the 9th Tomcat in the first paragraph on the second line. This means that if, like me, you are using this version of Tomcat, then our code that we will write and send to run will use exactly the specified versions. But we would like to have these specifications in our project, so that our code that uses them at least compiles successfully. And for this we need to upload them to our project. This is where Maven comes to the rescue.

The general rule is that if you need to include something in your project using Maven:

  • go to the repository site from Maven;
  • look for the library of the required version there;
  • get the dependency code to paste into your pom.xml;
  • insert! :)
So let's start. First, let's prepare a pom file . Somewhere after the entry /version , but before /project, paste the following:
<dependencies>

</dependencies>
Thus, we indicated that inside these tags we will list the dependencies we need. Now go to mvnrepository.com, there will be a search box at the top. To get started, type servlet into the search. The first result, where more than seven thousand uses, suits us. Remember that we need version 4.0 (for the 9th Tomcat, older implementations may be suitable for other versions). This is a fairly recent version, so there are not many uses, but we need it. A page will open where you can get the code for this dependency for various package managers, and you can even just download it. But since we want to connect it using Maven, we also select the code on the Maven tab. Copy and paste into our pom file inside the dependencies section. If a notification pops up in the lower right corner of IDEA asking if we want to enable auto-import, we agree. If you accidentally refused, go to "Settings" and enable auto-import manually:Settings (Ctrl + Alt + S) -> Build, Execution, Deployment -> Maven -> Importing This will keep the pom and IDEA configuration files for this project in sync. Now, by the same principle, we will find and connect JavaServer Pages version 2.3 (in the search, type in jsp). And since we have already taken up Maven, let's immediately indicate to him that our sources comply with the Java 8 syntax, and that they need to be compiled into the bytecode of the same version. After all these manipulations, our pom.xml will look something like this:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>ru.codegym.info.fatfaggy</groupId>
    <artifactId>my-super-project</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>1.8</maven.compile.source>
        <maven.compiler.target>1.8</maven.compile.target>
    </properties>

    <dependencies>
        <!-- Servlet API 4.0 for tomcat 9 -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- JavaServer Pages API 2.3 for tomcat 9 -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

</project>

Making real servlets out of our servlets

Right now, a couple of the servlets we've created are actually regular classes. They don't have any functionality. But now we have connected the Servlet API to our project, and, if so, we can use the classes from there. To make our servlets "real" servlets, simply inherit from the HttpServlet class .

Mapping or markup

Now it would be nice to somehow tell Tomcat that requests from /add are handled by our servlet AddServlet , and accordingly requests from /list are handled by the ListServlet servlet . It is this process that is called mapping (markup) . This is done in the web.xml file according to this principle:
  • first, we describe the servlet (give some name and specify the path to the class itself);
  • then we bind this servlet to a specific address (we indicate the name of the servlet that we just gave it and indicate the address from which requests should be sent to this servlet).
Describing the servlet:
<servlet>
    <servlet-name>add</servlet-name>
    <servlet-class>app.servlets.AddServlet</servlet-class>
</servlet>
Now we bind it to the address:
<servlet-mapping>
    <servlet-name>add</servlet-name>
    <url-pattern>/add</url-pattern>
</servlet-mapping>
As you can see, the servlet-name is the same in both cases. This tells Tomcat that if a request comes in for /add , it should be passed to the app.servlets.AddServlet servlet . We do the same with the second servlet. As a result, our web.xml has the following content:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <!-- add servlet -->
    <servlet>
        <servlet-name>add</servlet-name>
        <servlet-class>app.servlets.AddServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>add</servlet-name>
        <url-pattern>/add</url-pattern>
    </servlet-mapping>

    <!-- list servlet -->
    <servlet>
        <servlet-name>list</servlet-name>
        <servlet-class>app.servlets.ListServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>list</servlet-name>
        <url-pattern>/list</url-pattern>
    </servlet-mapping>
</web-app>
By the way, we have not created the markup for the main page (at / ). The fact is that in this case we do not need it. Our main page is a simple html file that simply displays two buttons. There is no dynamic content there, so it makes no sense for us to start a separate servlet for it, to which requests from the address / will be transmitted, and which will not do anything except transfer execution to some jsp (which would also have to be started), which drew we would have two buttons. We do not need this, we are satisfied with a static resource. When Tomcat receives a request, it will check that there is not a single servlet that could process the request at such an address, and then it will see that there is actually a ready-made one at this address.html file , which it will successfully return. We can run our application again (restart the server or re-deploy, as you prefer) and make sure that the main page is rendered, nothing is broken when we click on the buttons - then the transitions occur, but so far an error is also written. By the way, if before we had a 404 error, now 405. So the mapping worked, the servlets were found, but they just didn’t find the appropriate methods to process the request. If you still have a 404 error at this stage, although everything is done correctly - maybe you should fix the deployment configuration in the idea. to do this, go to Edit configurations (there at the top near the start button), go to the Deployment tab in the right part of the window and make it so that the Application context simply says /

Brief digression: what is happening "under the hood"?

You probably already have time to think about how our application works in Tomcat? What is happening there? And where is the main() method ? As soon as you type localhost:8080 into your browser and go to this address, the browser sends a request to this address using the http protocol . I hope you already know that requests can be of different "types", the most popular being GET and POST . Every request must have a response. The GET request expects that in response it will be given a ready-made html code , which will return to the browser, and the browser will already beautifully replace this code with all sorts of letters, buttons, forms. POST requesta little more interesting, since it still carries some information with it. For example, in the user registration or authorization form, you entered your data and clicked "send". At this point, a POST request was sent to the server with your personal information inside. The server received this information, processed it, and returned some kind of response (for example, an html page with your profile). The fundamental difference between them is that GET requests are intended only for receiving data from the server, while POST requeststhat it can’t handle this type, Tomcat throws a 405 code in response to the client. Which just happened with us. But if a suitable servlet is found, and it has a suitable method, Tomcat creates an object of this servlet, starts it in a new thread (thread ), which allows the servlet to run in a separate thread, while Tomcat continues to work on its own, accepting and sending requests. In addition, Tomcat creates two more objects: one of type HttpServletRequest (I will call it a request for short), and the second one of type HttpServletResponse(I will call the answer). In the first object, it puts all the data that it received in the request from the client, so all that data can be pulled out of this object. Well, after all this, it passes these two objects to the appropriate method of the servlet that is running in a separate thread. As soon as the servlet is finished and has a response ready to be sent to the client, it raises a flag to Tomcat, saying, "I'm done, everything is ready." Tomcat takes the response and sends it to the client. This allows Tomcat to accept requests and send responses without being distracted, and servlets that spin in separate threads do all the work. Accordingly, when we write servlet code, we determine the work that will be performed. And yes, you can consider that the main() methodresides in Tomcat itself (yes, it's written in Java), and when we "start" Tomcat, the main().

We catch GET methods with servlets and send simple responses

At the moment, there are no suitable methods (GET) in our servlets, so Tomcat returns a 405 error to us. Let's make them! The HttpServlet class , from which we inherited our servlets, has various methods defined. In order to set some code for methods, we simply redefine them. In this case, we need to override the doGet() method in both servlets.
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

}
As you can see, this method takes two objects: req (request) and resp (response). These are the same objects that Tomcat will create and populate for us when it calls the appropriate method in this servlet. First, let's do the simplest answers. To do this, take the object resp and get from it the PrintWriter object , which can be used to compose answers. Well, with the help of it we will display some simple string.
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    PrintWriter writer = resp.getWriter();
    writer.println("Method GET from AddServlet");
}
We will do something similar in the ListServlet servlet , after which we will start our server again. As you can see, everything works! When you click on the buttons, pages open with the text that we “recorded” with the PrintWriter . Here are just those of our jsp , which we have prepared for the formation of pages with answers, are not used in any way. This is because the execution simply does not reach them. The servlet itself is now generating a response and finishing, signaling Tomcat that it has a response ready for the client. Tomcat simply takes this response and sends it back to the client. Transfer control from servlets to jsp Let's change the code of our methods in the following way:
  • we get the request manager object from the request object, where we pass the address of the jsp page to which we want to transfer control;
  • using the received object, we transfer control to the specified jsp page, and do not forget to attach the request and response objects that we received from Tomcat.
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    RequestDispatcher requestDispatcher = req.getRequestDispatcher("views/add.jsp");
    requestDispatcher.forward(req, resp);
}
In the body of jsp pages (inside the body tag), you can write something so that we can clearly see which page is being displayed. After that, restart the server and check. Buttons on the main page are pressed, pages open, which means that requests are sent to servlets, after which control is transferred to jsp pages that are already being rendered. That's all. In the next part of the article, we will deal with the functionality of our application.

What else to read:

Creating a simple web project in IntelliJ Idea Enterprise. Step by step with pictures


My chat
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION