JavaRush /Java Blog /Random-KO /서블릿과 jsp를 사용하여 간단한 웹 애플리케이션 만들기(1부)
Стас Пасинков
레벨 26
Киев

서블릿과 jsp를 사용하여 간단한 웹 애플리케이션 만들기(1부)

Random-KO 그룹에 게시되었습니다
기사를 이해하는 데 필요한 지식 수준: 이미 Java Core를 어느 정도 이해했으며 JavaEE 기술 및 웹 프로그래밍을 살펴보고 싶습니다. 현재 기사와 가까운 주제를 다루는 Java 컬렉션 퀘스트를 연구하고 있다면 가장 적합합니다. 이 자료는 IntelliJ Idea Enterprise에서 간단한 웹 프로젝트 만들기서블릿과 jsp를 사용하여 간단한 웹 애플리케이션 만들기(1부) - 1 기사의 논리적 연속입니다 . 여기서는 작동하는 웹 프로젝트 템플릿을 만드는 방법을 보여주었습니다. 이번에는 Java Servlet API와 JavaServer Pages API 기술을 사용하여 간단하면서도 예쁜 웹 애플리케이션을 만드는 방법을 보여 드리겠습니다. 우리 애플리케이션에는 두 개의 링크가 있는 홈 페이지가 있습니다.
  • 사용자 추가 페이지로
  • 사용자 목록 보기 페이지로 이동합니다.
저는 IntelliJ Idea Enterprise Edition, Apache Maven(몇 가지 종속성만 포함) 및 Apache Tomcat을 계속 사용할 예정입니다. 마지막에는 W3.CSS 프레임워크를 사용하여 애플리케이션을 "장식"합니다 . 우리는 현재 여기에서 개발할 빈 프로젝트가 이미 있다고 가정합니다. 그렇지 않은 경우 첫 번째 기사를 읽고 작성하십시오. 몇 분 밖에 걸리지 않습니다 :)

향후 애플리케이션의 구조에 대해 조금

메인 페이지( / )는 헤더와 두 개의 링크/버튼이 있는 가장 일반적인 정적 HTML 페이지입니다.
  • 새 사용자를 추가합니다( /add 로 전송됩니다 ).
  • 사용자 목록을 봅니다( /list 로 보냅니다 ).
Tomcat은 이러한 주소에 대한 요청을 잡아서 우리가 만들 두 서블릿 중 하나로 보냅니다( web.xml 파일에서 매핑을 설명합니다 ). 그리고 서블릿은 요청을 처리하고, 데이터를 준비하고(또는 사용자가 추가된 경우 저장) 해당 jsp 파일로 제어권을 전송합니다. 그러면 이미 결과가 "렌더링"됩니다. 가장 일반적인 목록(List)에 데이터를 저장하겠습니다.

정적 홈페이지를 만들어보자

웹 폴더에 index.jsp가 있으면 삭제하세요. 대신 이 폴더에 index.html 이라는 간단한 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>
여기에는 복잡한 것이 없습니다. 제목에는 페이지 제목이 표시됩니다. 페이지 본문에는 헤더(header)와 콘텐츠(content)라는 두 개의 주요 div가 있습니다. 콘텐츠에는 버튼을 위한 홀더가 있고 실제로 클릭하면 해당 주소로 전송되는 두 개의 버튼이 있습니다. 프로젝트를 실행하고 이제 어떻게 보이는지 확인할 수 있습니다. 버튼을 클릭하면 아직 해당 버튼이 없기 때문에 404 오류가 있는 페이지가 열립니다. 그러나 이는 버튼이 작동한다는 것을 의미합니다. JavaScript를 갑자기 비활성화하면 브라우저에서 이 버튼이 더 이상 사용되지 않기 때문에 이것이 가장 보편적인 옵션은 아니라는 점에 유의하십시오. 하지만 JavaScript를 비활성화한 사람은 아무도 없다고 가정하겠습니다. :) 간단한 링크를 사용할 수 있다는 점은 분명하지만 저는 버튼을 선호합니다. 당신은 당신이 가장 좋아하는 일을 합니다. 그리고 내 예에는 div가 많이 있을 것이라는 사실을 보지 마십시오 . 그런 다음 스타일을 채워 넣으면 모든 것이 더 아름답게 보일 것입니다 :).

결과를 렌더링하기 위해 jsp 파일 만들기

동일한 웹 디렉토리에 jsp 파일을 저장할 폴더를 생성할 것입니다 . 나는 그것을 뷰라고 불렀고, 다시 즉흥적으로 만들 수 있습니다. 이 폴더에는 두 개의 jsp 파일이 생성됩니다.
  • add.jsp — 사용자 추가 페이지;
  • list.jsp - 사용자 목록을 표시하는 페이지입니다.
적절한 페이지 제목을 지정해 보겠습니다. "새 사용자 추가" 및 "사용자 목록"과 같은 항목이 있으며 지금은 그대로 두겠습니다.

두 개의 서블릿을 만들어 보겠습니다.

서블릿은 Tomcat이 전달하는 요청을 수락하고 처리합니다. src/main/java 폴더 에 소스를 포함할 패키지를 생성합니다. 거기에는 더 다양한 패키지가 있습니다. 따라서 이러한 패키지가 서로 내부에 생성되지 않도록 패키지에 일부 클래스를 생성한 후 삭제해 보겠습니다. 이제 앱 패키지에 세 가지 다른 패키지를 만들어 보겠습니다 .
  • 엔터티 - 엔터티가 위치할 위치입니다(사용자 개체를 설명하는 클래스 자체).
  • 모델 - 우리 모델이 여기에 있을 것입니다(이에 대해서는 나중에 자세히 설명합니다).
  • 서블릿 - 음, 여기에 서블릿이 있을 것입니다.
그런 다음 해당 클래스를 패키지에서 안전하게 제거할 수 있습니다 (물론 직접 만든 경우). 서블릿 패키지 에서 우리는 두 개의 클래스를 생성합니다:
  • AddServlet - /add 에서 수신된 요청을 처리합니다 .
  • ListServlet - /list 에서 수신된 요청을 처리합니다 .

Maven에서 종속성 연결

Tomcat 버전 9.*는 Servlet 버전 4.0 및 JavaServer Pages 버전 2.3 사양을 구현합니다. 이는 Tomcat 9 공식 문서의 두 번째 줄 첫 번째 문단에 적혀 있습니다. 이는 여러분이 저처럼 이 버전의 Tomcat을 사용하고 있다면 우리가 작성하고 실행하기 위해 보내는 코드가 정확히 지정된 버전을 사용한다는 것을 의미합니다. 그러나 우리는 프로젝트에 이러한 사양을 적용하여 이를 사용하는 코드가 최소한 성공적으로 컴파일되기를 원합니다. 이를 위해 프로젝트에 로드해야 합니다. 이것이 Maven이 구출되는 곳입니다.

일반적인 규칙은 다음과 같습니다. Maven을 사용하여 프로젝트에 무언가를 연결해야 하는 경우:

  • Maven 저장소 웹사이트로 이동하세요.
  • 필요한 라이브러리와 필요한 버전을 찾으십시오.
  • pom.xml에 삽입해야 하는 종속성 코드를 얻습니다.
  • 끼워 넣다! :)
그럼 시작해 보겠습니다. 먼저 pom 파일을 준비합시다 . /version 뒤, /project 앞 어딘가에 다음을 삽입합니다.
<dependencies>

</dependencies>
따라서 우리는 이러한 태그 내에 필요한 종속성을 나열할 것임을 표시했습니다. 이제 mvnrepository.com 으로 이동하면 상단에 검색 필드가 있습니다. 먼저 검색에 servlet을 입력하세요. 7,000개 이상의 용도가 있는 첫 번째 결과가 우리에게 적합합니다. 버전 4.0이 필요하다는 것을 기억합니다(Tomcat 9의 경우, 다른 버전의 경우 이전 구현이 적합할 수 있음). 이것은 상당히 최신 버전이므로 용도가 많지는 않지만 우리에게 필요한 버전입니다. 다양한 패키지 관리자에 대한 이 종속성에 대한 코드를 얻을 수 있는 페이지가 열리고 다운로드할 수도 있습니다. 하지만 우리는 Maven을 사용하여 연결하려고 하므로 Maven 탭에서 코드를 선택합니다. 종속성 섹션 내부의 pom 파일에 복사하여 붙여넣습니다. IDEA 오른쪽 하단에 자동 가져오기 활성화 여부를 묻는 알림이 나타나면 동의하는 것입니다. 실수로 거부한 경우 "설정"으로 이동하여 자동 가져오기를 수동으로 활성화하세요. 설정(Ctrl + Alt + S) -> 빌드, 실행, 배포 -> Maven -> 가져오기 이렇게 하면 이에 대한 pom 파일 과 IDEA 구성 파일이 유지됩니다. 프로젝트가 동기화되었습니다. 이제 동일한 원칙을 사용하여 JavaServer Pages 버전 2.3을 찾아 연결해 보겠습니다(검색에 jsp 입력). 그리고 우리는 이미 Maven을 다루었으므로 우리 소스가 Java 8 구문을 준수하며 동일한 버전의 바이트코드로 컴파일되어야 함을 즉시 알려드리겠습니다. 이러한 모든 조작이 끝나면 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>ru.javarush.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>

서블릿을 실제 서블릿으로 만들기

이 시점에서 우리가 만든 두 개의 서블릿은 실제로는 일반 클래스입니다. 아무런 기능도 없습니다. 하지만 이제 우리는 Servlet API를 프로젝트에 연결했으며, 그렇다면 거기에서 클래스를 사용할 수 있습니다. 우리의 서블릿을 "실제" 서블릿으로 만들려면 HttpServlet 클래스 에서 상속하면 됩니다 .

매핑 또는 파티셔닝

이제 /add 의 요청은 AddServlet 서블릿 에 의해 처리되고 , 따라서 /list 의 요청은 ListServlet 서블릿 에 의해 처리되도록 Tomcat에 알려주는 것이 좋을 것입니다 . 이 프로세스를 매핑이라고 합니다 . 이는 다음 원칙에 따라 web.xml 파일 에서 수행됩니다 .
  • 먼저 서블릿을 설명합니다(이름을 지정하고 클래스 자체에 대한 경로를 나타냅니다).
  • 그런 다음 이 서블릿을 특정 주소에 바인딩합니다(방금 제공한 서블릿의 이름을 나타내고 요청이 이 서블릿으로 전송되어야 하는 주소를 나타냅니다).
서블릿을 설명해보자:
<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>
보시 다시피 두 경우 모두 servlet-name이 동일합니다. 덕분에 Tomcat은 요청이 /add 주소로 오면 app.servlets.AddServlet 서블릿 으로 전달되어야 한다는 것을 알고 있습니다 . 두 번째 서블릿에서도 동일한 작업을 수행합니다. 결과적으로 web.xml 에는 대략 다음과 같은 내용이 포함됩니다.
<?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>
그런데 여기( / )의 메인 페이지에 대한 마크업을 생성하지 않았습니다. 사실 이 경우에는 필요하지 않습니다. 우리의 홈 페이지는 단순히 두 개의 버튼을 표시하는 간단한 HTML 파일 입니다 . 동적 콘텐츠가 없으므로 이를 위해 별도의 서블릿을 생성하는 것은 의미가 없습니다. 이 서블릿은 / 주소의 요청이 전송되고 실행을 일부 jsp 로 전송하는 것 외에는 아무 작업 도 수행하지 않습니다. 생성됨), 버튼이 두 개만 있다면 그려질 것입니다. 우리는 이것이 필요하지 않으며 정적 리소스에 만족합니다. Tomcat이 요청을 받으면 해당 주소에서 요청을 처리할 수 있는 단일 서블릿이 없는지 확인한 다음 이 주소에 실제로 준비된 html 파일이 있는지 확인하고 성공적으로 보냅니다. . 애플리케이션을 다시 실행하고(원하는 대로 서버를 다시 시작하거나 다시 배포) 메인 페이지가 렌더링되었는지, 아무 것도 깨지지 않았는지 확인할 수 있습니다. 버튼을 클릭하면 전환이 발생하지만 지금은 오류도 발생합니다. 쓴. 그런데 이전에 404 오류가 발생했다면 이제 405 오류가 발생합니다. 이는 매핑이 작동하고 서블릿을 찾았지만 요청을 처리하는 데 적합한 방법이 없었음을 의미합니다. 모든 것이 올바르게 수행되었음에도 불구하고 이 단계에서 여전히 404 오류가 발생하는 경우 아이디어의 배포 구성을 수정해야 할 수도 있습니다. 이렇게 하려면 구성 편집(시작 버튼 근처 상단)으로 이동하여 창 오른쪽의 배포 탭으로 이동하여 애플리케이션 컨텍스트에서 /로 간단히 표시되는지 확인해야 합니다.

짧은 서정적 여담: "내부"에서 무슨 일이 일어나고 있습니까?

우리 애플리케이션이 Tomcat에서 어떻게 작동하는지 이미 궁금하신가요? 거기 무슨 일 이죠? 그리고 main() 메소드는 어디에 있나요 ? 브라우저에 localhost:8080을 입력 하고 이 주소로 이동하자마자 브라우저는 http 프로토콜을 통해 이 주소로 요청을 보냅니다 . 요청은 다양한 “유형”이 될 수 있다는 점을 이미 알고 계셨기를 바랍니다. 가장 인기 있는 것은 GETPOST 입니다 . 모든 요청에는 응답이 있어야 합니다. GET 요청은 그에 대한 응답으로 기성 HTML 코드가 제공 되어 브라우저에 반환될 것으로 예상하며, 브라우저는 이 코드를 모든 종류의 문자, 버튼 및 양식으로 아름답게 대체합니다. POST 요청은 일부 정보도 함께 전달하므로 좀 더 흥미롭습니다. 예를 들어, 사용자 등록 또는 승인 양식에 데이터를 입력하고 "보내기"를 클릭했습니다. 이때 개인정보가 포함된 서버로 POST 요청이 전송되었습니다. 서버는 이 정보를 수락하고 처리한 후 일종의 응답(예: 프로필이 포함된 HTML 페이지 )을 반환했습니다. 이들 사이의 근본적인 차이점은 GET 요청은 서버에서 데이터를 수신하기 위한 용도로만 사용되는 반면 POST 요청은 일부 정보를 전달하며 서버의 데이터가 변경될 수 있다는 것입니다(예: 사진을 서버에 업로드하면 POST 요청이 전송되고 서버는 이를 데이터베이스에 추가합니다. 즉, 일부 변경이 발생합니다. 이제 Tomcat으로 돌아가 보겠습니다. 클라이언트로부터 요청을 받으면 주소를 확인합니다. 데이터를 검색하여 해당 주소(또는 즉시 반환될 수 있는 기성 리소스)에 대한 요청을 처리하는 적합한 서블릿이 있는지 확인하고, 반환할 항목을 찾지 못하면 html 페이지로 응답하지 않지만, 404 응답으로 이 주소에 "위치"하는 적합한 서블릿을 찾으면 수신된 요청 유형(GET, POST 또는 기타)을 살펴본 다음 서블릿에 다음과 같은 메소드가 있는지 묻습니다. 서블릿이 이 유형을 처리할 수 없다고 말하면 Tomcat은 코드 405로 클라이언트에 응답합니다. 그러나 적절한 서블릿이 발견되고 적절한 메소드가 있는 경우 Tomcat은 이 서블릿의 객체를 생성하고 이를 새 스레드( thread )에서 실행합니다. 이를 통해 서블릿이 별도의 스레드에서 작동할 수 있으며 Tomcat은 계속해서 추가 작업을 수행합니다. 자체적으로 요청을 받고 보냅니다. 또한 Tomcat은 두 개의 객체를 더 생성합니다. 하나는 HttpServletRequest 유형 (나중에 간단히 요청이라고 부르겠습니다)이고 두 번째 객체는 HttpServletResponse 유형입니다.(나는 그것을 대답이라고 부를 것이다). 첫 번째 개체에는 클라이언트의 요청에서 받은 모든 데이터를 배치하므로 이 개체에서 모든 데이터를 가져올 수 있습니다. 결국, 이 두 개체를 별도의 스레드에서 실행 중인 서블릿의 적절한 메서드에 전달합니다. 서블릿이 작업을 마치고 클라이언트에 보낼 응답을 준비하자마자 Tomcat에 "완료되었습니다. 모든 것이 준비되었습니다"라는 플래그를 표시합니다. Tomcat은 응답을 수락하고 클라이언트에 보냅니다. 이를 통해 Tomcat은 중단 없이 요청을 수락하고 응답을 보낼 수 있으며 모든 작업은 별도의 스레드에서 실행되는 서블릿에 의해 수행됩니다. 따라서 서블릿 코드를 작성할 때 수행할 작업을 정의합니다. 그리고 그렇습니다. main() 메서드가 Tomcat 자체에 있는 것으로 생각할 수 있으며(예, Java로 작성되었습니다) Tomcat을 "시작"하면 main().

서블릿으로 GET 메소드를 포착하고 간단한 응답을 보냅니다.

현재 우리 서블릿에는 적합한 메소드(GET)가 없으므로 Tomcat은 405 오류를 반환합니다. 서블릿을 상속받는 HttpServlet 클래스는 다양한 메소드를 정의 합니다 . 메소드에 대한 일부 코드를 설정하려면 해당 코드를 재정의하면 됩니다. 이 경우 두 서블릿 모두에서 doGet() 메서드를 재정의해야 합니다 .
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

}
보시다시피 이 메소드는 req (요청)과 resp (응답)라는 두 개의 개체를 허용합니다. 이것들은 Tomcat이 이 서블릿에서 적절한 메소드를 호출할 때 우리를 위해 생성하고 채울 바로 그 객체입니다. 먼저 가장 간단한 답변을 해보겠습니다. 이렇게 하려면 resp 개체를 가져와서 응답을 작성하는 데 사용할 수 있는 PrintWriter 개체를 가져옵니다 . 글쎄, 그것을 사용하여 간단한 문자열을 인쇄하겠습니다.
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    PrintWriter writer = resp.getWriter();
    writer.println("Method GET from AddServlet");
}
ListServlet 서블릿 에서 비슷한 작업을 수행 한 후 서버를 다시 시작하겠습니다. 보시다시피 모든 것이 작동합니다! 버튼을 클릭하면 PrintWriter 로 "기록"한 텍스트가 포함된 페이지가 열립니다 . 답변이 포함된 페이지를 생성하기 위해 준비한 jsp는 어떤 방식으로도 사용되지 않습니다. 이는 실행이 단순히 도달하지 않기 때문입니다. 이제 서버렛 자체가 응답을 생성하고 작업을 완료하여 Tomcat에 클라이언트에 대한 응답이 준비되었음을 알립니다. Tomcat은 단순히 이 응답을 받아 클라이언트에 다시 보냅니다. 서블릿에서 jsp로 제어권을 넘깁니다. 메소드 코드를 다음과 같이 변경해 보겠습니다.
  • 요청 객체에서 요청 관리자 객체를 얻습니다. 여기서 제어권을 이전하려는 페이지의 jsp 주소를 전달합니다.
  • 수신된 객체를 사용하여 지정된 jsp 페이지 로 제어를 전송 하고 Tomcat에서 받은 요청 및 응답 객체를 거기에 첨부하는 것을 잊지 마십시오.
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    RequestDispatcher requestDispatcher = req.getRequestDispatcher("views/add.jsp");
    requestDispatcher.forward(req, resp);
}
jsp 페이지 의 본문 (body 태그 내부)에서 어떤 페이지가 표시되고 있는지 명확하게 볼 수 있도록 무언가를 작성할 수 있습니다. 그 후 서버를 다시 시작하고 확인합니다. 메인 페이지의 버튼을 누르면 페이지가 열립니다. 이는 요청이 서블릿으로 전송되고 그 후에 제어가 이미 렌더링된 jsp 페이지로 전송됨을 의미합니다. 그게 다야. 기사의 다음 부분 에서는 애플리케이션의 기능을 다룰 것입니다.

그 밖에 읽을 내용:

IntelliJ Idea Enterprise에서 간단한 웹 프로젝트 만들기. 사진과 함께 차근차근


내 채팅
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION