JavaRush /Java Blog /Random-KO /Java 서블릿을 사용한 첫 번째 애플리케이션

Java 서블릿을 사용한 첫 번째 애플리케이션

Random-KO 그룹에 게시되었습니다
안녕하세요 여러분! 이 기사에서는 서블릿의 기본 웹 개발 개념에 익숙해지고 이를 사용하여 간단한 애플리케이션을 작성할 수 있습니다. Java 서블릿을 사용한 첫 번째 애플리케이션 - 1불필요한 단계를 피하기 위해 처음부터 시작하지 않고 Hibernate에 관한 이전 기사 의 애플리케이션 작업을 계속할 것입니다 . 그러나 이제 막 서블릿을 시작했기 때문에 애플리케이션에서 Auto 클래스와 관련된 모든 것을 제거하고 User 클래스와 해당 작업만 남겨 두었습니다. 프로젝트 구조는 다음과 같습니다. Java 서블릿을 사용한 첫 번째 애플리케이션 - 2즉, 서블릿입니다! Wikipedia에서는 "서블릿은 구현이 서버의 기능을 확장하는 Java 인터페이스입니다. 서블릿은 요청-응답 원칙을 통해 클라이언트와 상호 작용합니다."라고 말합니다. 그리고 실제로 그렇습니다. 여기서 우리는 "클라이언트-서버 애플리케이션 아키텍처"라는 개념을 처음 접하게 됩니다. 그 본질은 매우 간단하며 하나의 그림에 들어 맞습니다 ( 여기에서 가져옴 ).
Java 서블릿을 사용한 첫 번째 애플리케이션 - 3
클라이언트는 HTTP 요청을 보내 서버에 접속합니다. 서버는 필요한 데이터를 생성하고(예: 데이터베이스에서 데이터 수신) 이를 클라이언트에 반환합니다. 가장 간단한 예: 특정 소셜 네트워크에서 "친구" 버튼을 클릭하면 서버에 요청이 전송됩니다. 서버는 데이터베이스에 있는 친구 목록을 확인하고 이를 귀하(클라이언트)에게 반환합니다. HTTP 요청 목록은 꽤 크지만, 한 번도 본 적이 없다면 더 나은 이해를 위해 여기에 대해 읽어 보는 것이 좋습니다 . 우리의 임무는 다음과 같습니다. 서블릿을 사용하여 CRUD 애플리케이션을 만듭니다. 애플리케이션은 HTTP 요청을 처리하는 서블릿을 사용하여 데이터베이스에서 사용자를 생성, 수정 및 삭제할 수 있어야 합니다. Hibernate에 관한 기사에서 우리의 애플리케이션은 이미 이를 수행하는 방법을 알고 있었지만 Java 코드, 더 정확하게는 main() 메소드에서 직접 제어되었습니다. 여기서 요청은 클라이언트, 즉 귀하에 의해 전송됩니다. :) 가장 먼저 해야 할 일은 pom.xml 파일에 새로운 종속성을 추가하는 것입니다.
<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>com.itis4</groupId>
    <artifactId>UsersDaoProject</artifactId>
    <version>1.0-SNAPSHOT</version>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.6</version>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <!-- PostgreSQL  -->
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>9.4.1212.jre7</version>
        </dependency>

        <!-- Hibernate 5.2.6 Final -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.2.6.Final</version>
        </dependency>

        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.3.4.RELEASE</version>
        </dependency>

    </dependencies>

</project>
우리는 3가지 종속성을 추가했습니다:
  1. javax.servlet-api 라이브러리 자체.
  2. JSTL 태그 라이브러리. 클라이언트측, 즉 JSP 페이지를 생성하는 데 필요합니다.
  3. 스프링-WebMVC. 우리는 하나의 Spring 클래스가 필요할 것이고, 이에 대해서는 잠시 후에 이야기하겠습니다.
서블릿의 작업은 서블릿 컨테이너에 의해 관리됩니다. 우리의 경우에는 Apache Tomcat을 사용하겠습니다. 매우 인기 있는 내용이며 아마도 이미 들어보셨을 것입니다. :) 서블릿의 수명 주기는 다음 단계로 구성됩니다.
  1. 컨테이너에 서블릿이 없는 경우.
    • 서블릿 클래스는 컨테이너에 의해 로드됩니다.
    • 컨테이너는 서블릿 클래스의 인스턴스를 생성합니다.
    • 컨테이너는 init() 메서드를 호출합니다. 이 메소드는 서블릿을 초기화하고 서블릿이 요청을 처리하기 전에 먼저 호출됩니다. init() 메서드는 전체 수명 주기 동안 한 번만 호출됩니다.
  2. 클라이언트 요청을 처리합니다. 각 요청은 별도의 자체 스레드에서 처리됩니다. 컨테이너는 각 요청에 대해 service() 메서드를 호출합니다. 이 메서드는 들어오는 요청의 유형을 결정하고 요청을 처리하기 위해 이 유형에 해당하는 메서드에 배포합니다. 서블릿 개발자는 이러한 메소드에 대한 구현을 제공해야 합니다. 메소드가 구현되지 않은 요청이 수신되면 상위 클래스의 메소드가 호출되고 일반적으로 요청자에게 오류가 반환되면서 종료됩니다.
  3. 컨테이너가 서블릿을 삭제해야 하는 경우 서비스에서 서블릿을 제거하는 destroy() 메서드를 호출합니다. init() 메소드와 마찬가지로 이 메소드도 전체 서블릿 주기 동안 한 번 호출됩니다.
우리의 서블릿은 매우 단순해 보일 것입니다:
package servlets;

import models.User;
import services.UserService;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

public class UserSimpleServlet extends HttpServlet {

    private UserService service = new UserService();

    public void init(ServletConfig servletConfig) {
        try {
            super.init(servletConfig);
        } catch (ServletException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        List<User> users = service.findAllUsers();
        req.setAttribute("users", users);
        RequestDispatcher dispatcher = req.getRequestDispatcher("/showUsers.jsp");
        dispatcher.forward(req, resp);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        String name = req.getParameter("name");
        int age = Integer.parseInt(req.getParameter("age"));
        User user = new User(name, age);
        service.saveUser(user);
        resp.sendRedirect("/users");

    }

    @Override
    protected void  doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        int id = Integer.parseInt(req.getParameter("id"));
        User user = service.findUser(id);
        user.setName(req.getParameter("name"));
        user.setAge(Integer.parseInt(req.getParameter("age")));
        service.updateUser(user);
        resp.sendRedirect("/users");
    }

    @Override
    protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        int id = Integer.parseInt(req.getParameter("id"));
        service.deleteUser(service.findUser(id));
        resp.sendRedirect("/users");
    }
}
보시다시피 위에서 설명한 init() 메서드가 포함되어 있으며 4개의 HTTP 요청과 일치하는 4개의 메서드(doGet(), doPost(), doPut() 및 doDelete()))를 구현합니다. 각각을 통해 우리는 각각 사용자를 수신, 생성, 편집 및 삭제할 수 있습니다. 메소드는 javax.servlet.http.HttpServletRequest 및 javax.servlet.http.HttpServletResponse 클래스의 입력 객체, 즉 서버로 전송된 요청과 클라이언트가 수신하는 응답을 사용합니다. 메소드 내부에서는 UserService 클래스의 필요한 메소드가 실행되고 클라이언트에 대한 응답이 생성된 후 /users 주소로 리디렉션됩니다. 예를 들어, doGet() 메소드에서는 모든 사용자 목록을 얻습니다. 다음으로, RequestDispatcher 클래스의 객체를 생성합니다. 이를 통해 Http 요청에 객체를 포함할 수 있을 뿐만 아니라 이를 특정 리소스(예: 클라이언트 JSP 페이지)로 리디렉션할 수 있습니다. doPut() 메소드(사용자 데이터 업데이트)에서 우리는 HTTP 요청을 처리하고, 여기에서 id, name 및 age 매개변수를 추출하고, 지정된 ID를 가진 사용자를 찾고, 해당 사용자에게 해당 사용자와 함께 제공된 이름과 나이를 할당합니다. 요청하고 /users 페이지로 돌아갑니다. 그러나 이러한 모든 방법이 올바르게 작동하려면 서블릿을 구성해야 합니다. 이를 위해 WEB-INF 폴더에 있는 web.xml 파일을 사용합니다.
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1"
         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">

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

    <servlet>
        <servlet-name>UserSimpleServlet</servlet-name>
        <servlet-class>servlets.UserSimpleServlet</servlet-class>
    </servlet>

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

    <filter>
        <filter-name>hiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>hiddenHttpMethodFilter</filter-name>
        <servlet-name>UserSimpleServlet</servlet-name>
    </filter-mapping>

</web-app>
이 파일의 모든 태그는 원칙적으로 직관적이지만 순차적으로 살펴보겠습니다. <welcome-file-list> - 시작 JSP 페이지가 지정되며, 애플리케이션이 시작될 때 가장 먼저 열립니다. 우리의 경우 이것은 index.jsp 페이지입니다. <servlet> - UserSimpleServlet 클래스를 서블릿으로 등록합니다. <servlet-mapping>은 매우 중요한 태그입니다. 서블릿이 처리할 URL을 정의합니다. 우리의 경우에는 모두 URL이므로 단순히 "/"만 표시합니다. 그러나 예를 들어 사용자와 사용자의 컴퓨터가 포함된 애플리케이션이 있다면 두 번째 서블릿인 SimpleAutoServlet을 만들 수 있습니다. 그러면 사용자 서블릿에 대한 매핑은 "/users"(즉, 사용자 처리와 관련된 요청)가 되고 자동 서블릿에 대한 매핑은 "/autos"가 됩니다. 그리고 마지막으로 <필터>입니다. 내부적으로 org.springframework.web.filter.HiddenHttpMethodFilter 클래스의 객체를 정의합니다. 이 기사에서는 Spring에 관한 내용이 아니므로 자세한 내용은 다루지 않겠습니다. 단지 추가 기능으로만 우리 애플리케이션에 첨부되어 있다고 말씀드리고 싶습니다. 요점은 JSP 페이지를 사용하여 클라이언트 측을 생성한다는 것입니다. 우리의 데이터는 사용자 목록이 포함된 테이블로 페이지에 표시됩니다. JSP 페이지 내에서는 HTML <form/> 태그가 사용됩니다. 그리고 HTTP GET 및 POST 요청만 <form/>에서 데이터를 보내는 데 사용할 수 있습니다. 즉, 세 가지 작업(사용자 업데이트, 삭제, 생성) 모두에 대해 POST 요청만 사용해야 합니다. PUT 및 DELETE 요청을 사용할 수 없습니다. 그리고 원칙적으로 이는 매우 정상적이고 구현하기 쉽지만 HiddenHttpMethodFilter 클래스를 사용하면 이를 사용할 수 있습니다. 이렇게 하면 독자가 애플리케이션의 작업 간의 차이점을 더 명확하게 알 수 있습니다. 마지막으로 클라이언트 측으로 넘어가겠습니다. 이는 5개의 JSP 페이지로 표시됩니다. index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Здравствуйте!</title>
</head>
<body>
Если вы хотите начать работу с базой данных пользователей - <br>
нажмите кнопку ниже:

<form action = "users" method="get">
    <input type="submit" value="Начать работу с базой данных">
</form>
</body>
</html>
addUser.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Добавить нового пользователя</title>
</head>
<body>
<form action = "/users" method="post">
    <input required type="text" name="name" placeholder="Name">
    <input required type="text" name="age" placeholder="Возраст">
    <input type="submit" value="Сохранить">
</form>
</body>
</html>
deleteUser.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Удалить пользователя</title>
</head>
<body>

Вы действительно хотите удалить пользователя ${param.id}?

&lform action="/users/${param.id}" method="post">
    <input type="hidden" name="id" value="${param.id}">
    <input type="hidden" name="_method" value="delete">
    <input type="submit" value="Удалить">
</form>

</body>
</html>
showUsers.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Список пользователей</title>
</head>
<body>
<table border="2">
    <tr>
        <td>ID</td>
        <td>Name</td>
        <td>Возраст</td>
        <td>Действия</td>
    </tr>
    <c:forEach items="${users}" var = "user">
        <tr>
            <td>${user.getId()}</td>
            <td>${user.getName()}</td>
            <td>${user.getAge()}</td>
            <td>
                <form action = "updateUser.jsp" method="post">
                    <input type="hidden" name="id" value="${user.getId()}">
                    <input type="hidden" name="name" value="${user.getName()}">
                    <input type="hidden" name="age" value="${user.getAge()}">
                    <input type="submit" value="Изменить" style="float:left">
                </form>
                <form action="deleteUser.jsp" method="post">
                    <input type="hidden" name="id" value="${user.getId()}">
                    <input type="submit" value="Удалить" style="float:left">
                </form></td>
        </tr>
    </c:forEach>
</table>

<form action = "addUser.jsp">
    <input type="submit" value="Добавить нового пользователя">
</form>
</body>
</html>
updateUser.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Изменить данные пользователя</title>
</head>
<body>

Редактировать пользователя

<form action="/users/${param.id}" method="post">
    <input type="hidden" name = "id" value="${param.id}">
    <input type="text" name="name" value="${param.name}" placeholder=${param.name}>
    <input type="text" name="age" value="${param.age}" placeholder=${param.age}>
    <input type="hidden" name="_method" value="put">
    <input type="submit" value="Обновить">
</form>

</body>
</html>
JSP 페이지(Java Server Page)에는 텍스트 형식(HTML, SVG, WML 또는 XML) 중 하나일 수 있는 정적 소스 데이터와 동적 콘텐츠를 구성하는 JSP 요소라는 두 가지 유형의 텍스트가 포함되어 있습니다. JSP가 무엇인지 이해하기 위해 한 저자의 매우 훌륭한 기사를 복사하여 붙여넣겠습니다( 여기에서 ). "본질적으로 JSP는 처음 액세스할 때 서블릿으로 변환되어 서블릿으로 작동합니다. 이를 이해하는 것이 매우 중요합니다. JSP는 HTML 페이지와 같은 페이지가 아닙니다 . 초보 프로그래머가 이 점을 명확하게 이해하는 것이 중요합니다. 또 다른 서블릿입니다. 출력을 프로그래밍할 필요가 없습니다. 간단히 그릴 수 있습니다. 그리고 올바른 위치에 데이터를 대체할 수 있습니다. 그러나 JSP 페이지는 적어도 HTML과 유사하므로 디자이너에게는 확실히 더 쉬울 것입니다. 그리고 초보자들에게 다시 한 번 강조합니다. JSP는 SERVLET입니다 . 서버의 모든 데이터가 준비되어 있습니다. 여기에 모든 데이터가 삽입됩니다. 그리고 사용자는 브라우저에서 미리 만들어진 HTML 페이지를 받습니다. JAVA의 흔적이 있습니다." 각 페이지에는 실행해야 하는 메소드가 포함되어 있으므로 JSP 페이지가 실제로 서블릿이라는 것을 직접 확인할 수 있습니다. 예를 들어, 시작 페이지 index.jsp에는 "데이터베이스 작업 시작" 버튼을 클릭하면 method="get"이 실행될 것이라고 명시되어 있습니다. 새로운 사용자 생성을 담당하는 addUser.jsp 페이지에서 저장 버튼을 클릭하면 method="post"가 실행됩니다. JSP의 나머지 부분은 일반적인 정적 HTML 마크업으로 구성되어 있으므로 이에 대해 자세히 설명하지 않겠습니다. 이는 인터넷에 많은 내용이 있는 별도의 기사에서 다루는 주제입니다. 이제 애플리케이션을 만들었으니 이제 실제로 테스트하는 일만 남았습니다! 이를 위해서는 위에서 언급한 Apache Tomcat 서블릿 컨테이너가 필요합니다. 공식 웹사이트에서 고양이를 다운로드할 수 있습니다 (저는 버전 8을 사용합니다). 다음으로 Tomcat을 통해 애플리케이션을 실행하려면 IDEA에서 구성을 생성해야 합니다. 이렇게 하려면 "구성 편집" 탭을 열고 Java 서블릿을 사용한 첫 번째 애플리케이션 - 4새 구성을 생성한 Java 서블릿을 사용한 첫 번째 애플리케이션 - 5후 Tomcat 서버 로컬을 선택하십시오. Application Server 탭에서 Tomcat이 위치한 폴더의 경로를 지정한 Java 서블릿을 사용한 첫 번째 애플리케이션 - 6후, 배포 탭으로 이동합니다. Ваше первое приложение с использованием Java-сервлетов - 7여기서는 로컬 서버에 애플리케이션 배포를 구성합니다. "+"를 클릭하고 "Artifact" -> 프로젝트 이름: war를 선택합니다(애플리케이션을 war 파일로 조합합니다). Ваше первое приложение с использованием Java-сервлетов - 8기본적으로 그게 다야! "서버" 페이지에서 동일한 애플리케이션이 "http://localhost:8080/"에서 실행되는 것을 볼 수 있습니다. 이 구성을 저장하고 이름을 지정합니다(내 구성 이름은 "Tommy"입니다). 다음으로 IDEA(오른쪽)의 Maven 탭에서 war 플러그인을 사용하여 프로젝트를 war 파일로 빌드합니다(플러그인 -> war -> war:war). Ваше первое приложение с использованием Java-сервлетов - 9Ваше первое приложение с использованием Java-сервлетов - 10성공! 시작 페이지가 시작되었습니다. 이제 "데이터베이스 작업 시작"버튼을 클릭하십시오. JSP 페이지 index.jsp는 서버에서 처리할 GET 요청을 생성합니다. 서버는 응답을 생성하고 이를 모든 기존 사용자 목록 형식으로 우리에게 반환합니다(물론 해당 사용자가 데이터베이스에 있는 경우). 그리고 여기 있습니다! Ваше первое приложение с использованием Java-сервлетов - 12사용자 중 한 명을 삭제해 보겠습니다. Ваше первое приложение с использованием Java-сервлетов - 13그것도 작동합니다! 그래서 우리는 서블릿을 사용하여 첫 번째 애플리케이션을 작성했습니다. 보시다시피 모든 것이 그리 어렵지 않은 것으로 나타났습니다. :) 숙제로 예를 들어 이전 기사의 자동차 작업 기능을 응용 프로그램에 반환할 수 있습니다. 저것들. 자동차에 대한 별도의 서블릿과 JSP 페이지를 만들고 애플리케이션에 사용자의 자동차 목록을 표시하고 새 자동차를 추가하고 편집 및 삭제하도록 지시합니다. PS 서블릿과 JSP는 아주 오래된 기술이며, 인터넷에서 "누가 이 정크를 필요로 하는가?"라는 정신으로 댓글을 자주 찾을 수 있습니다. 대답은 매우 간단합니다. 실제 프로젝트에서 작업하는 사람들에게 주로 필요하며, 이를 사용하여 작성된 코드가 많이 있을 가능성이 높습니다. 그리고 그것이 어떻게 작동하는지 이해하지 못한 채 "오래된 것"을 새로운 것으로 만드는 것은 여전히 ​​​​즐거운 일입니다 :) JSP와 서블릿 주제에 대한 더 철저한 연구를 위해서는 "Head First Servlets and JSP"라는 책을 사용할 수 있습니다 . 영어로만 제공). 이 글은 유명한 슈퍼북 "Head First Java"와 동일한 작가가 쓴 것으로 많은 사람들에게 품질을 보장할 수 있습니다. :) 이 글이 독자들에게 도움이 되었기를 바랍니다! 새로운 글을 보고 싶으시다면, 공모전에서 작가에게 "좋아요"를 눌러 응원해 주시는 것도 잊지 마세요. 또는 더 나은 방법은 – “매우 마음에 듭니다” :) 관심을 가져주셔서 감사하고 학업에 행운이 있기를 바랍니다!
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION