CodeGym /Java Blog /무작위의 /서블릿과 JSP를 사용하여 간단한 웹 애플리케이션 만들기(1부)
John Squirrels
레벨 41
San Francisco

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

무작위의 그룹에 게시되었습니다
기사를 이해하는 데 필요한 지식: Java Core에 대해 이미 어느 정도 이해했으며 JavaEE 기술웹 프로그래밍을 살펴보고자 합니다 . 현재 기사와 가까운 주제를 다루는 Java Collections 퀘스트를 공부하고 있는 것이 가장 합리적일 것입니다 .
서블릿과 JSP를 사용하여 간단한 웹 애플리케이션 만들기(1부) - 1
이 자료는 IntelliJ Idea Enterprise에서 가장 간단한 웹 프로젝트 만들기 기사의 논리적 연속입니다 . 이 기사에서 작동하는 웹 프로젝트 템플릿을 만드는 방법을 설명했습니다. 이번에는 Java Servlet APIJavaServer Pages API를 사용하여 간단하지만 완전히 매력적인 웹 애플리케이션을 만드는 방법을 보여 드리겠습니다 . 우리의 애플리케이션에는 두 개의 링크가 있는 홈페이지가 있습니다.
  • 사용자 추가 페이지 링크
  • 사용자 목록에 대한 링크.
이전과 마찬가지로 IntelliJ Idea Enterprise Edition , Apache Maven (일부 종속 항목만 연결) 및 Apache Tomcat을 사용합니다 . 결국 W3.CSS 프레임워크를 사용하여 애플리케이션을 "미화"할 것입니다. 이제 추가할 빈 프로젝트가 이미 있다고 가정합니다. 그렇지 않은 경우 첫 번째 기사를 실행하여 작성하십시오. 몇 분 밖에 걸리지 않습니다 :)

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

우리의 홈 페이지(/) 는 헤더와 두 개의 링크/버튼이 있는 가장 일반적인 정적 HTML 페이지 입니다 .
  • 새 사용자를 추가합니다( / 추가 로 이동 ).
  • 사용자 목록 보기( / 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>    <!-- button holder -->
            <button onclick="location.href='/list'">List users<//button>
            <button onclick="location.href='/add'">Add user<//button>
        </div>
    </div>
</body>
</html>
여기에는 복잡한 것이 없습니다. 제목 태그 에서 우리 페이지의 제목을 나타냅니다. 페이지 본문에는 headercontent 라는 두 개의 기본 div가 있습니다 . 콘텐츠 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.0JavaServer Pages 2.3 에 대한 사양을 구현합니다 . 그것이 Tomcat 9의 공식 문서의 첫 번째 단락의 두 번째 줄에 명시된 내용입니다. 이것은 당신이 나처럼 이 버전의 Tomcat을 사용한다면 당신이 작성하고 실행할 코드가 이 버전을 사용할 것임을 의미합니다. 그러나 우리는 프로젝트에 이러한 사양을 포함하여 이를 사용하는 코드가 최소한 성공적으로 컴파일되도록 하고 싶습니다. 이렇게 하려면 프로젝트에 로드해야 합니다. 이것은 Maven이 구조하러 오는 곳입니다.

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

  • Maven에서 저장소 웹사이트로 이동합니다.
  • 필요한 라이브러리의 필요한 버전을 찾습니다.
  • pom.xml에 붙여넣어야 하는 종속성 코드를 가져옵니다.
  • 반죽! :)
의 시작하자. 먼저 POM 파일을 준비합니다 . /version 항목 뒤, /project 앞 어딘가에 다음을 삽입합니다.

<dependencies>

</dependencies>
이렇게 하는 것은 이러한 태그 내에 필요한 종속성을 나열함을 나타내기 위한 것입니다. 이제 mvnrepository.com 으로 이동합니다 . 상단에 검색창이 있습니다. 시작하려면 ' servlet '을 검색하십시오. 7천 번 이상 사용된 첫 번째 결과가 우리에게 적합합니다. 버전 4.0이 필요하다는 것을 기억하십시오 ( Tomcat 9 의 경우).). 이전 구현에는 다른 버전이 적합할 수 있습니다. 이것은 상당히 최신 버전이므로 많은 용도가 없습니다. 그러나 우리는 그것이 필요합니다. 다양한 패키지 관리자에 대한 이 종속성에 대한 코드를 가져오거나 간단히 다운로드할 수 있는 페이지가 열립니다. 하지만 Maven을 사용하여 연결하고 싶기 때문에 Maven 탭에서 코드를 선택하겠습니다. POM 파일의 종속성 섹션에 복사하여 붙여넣습니다. IDEA 의 오른쪽 하단에 자동 가져오기를 활성화할지 묻는 알림이 표시되면 계속 진행하여 동의합니다. 실수로 거부한 경우 " Settings "로 이동하여 수동으로 자동 가져오기를 켭니다: Settings (Ctrl + Alt + S) -> Build, Execution, Deployment -> Maven -> Importing .이 프로젝트의 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>cc.codegym.info.fatfaggy</groupId>
    <artifactId>my-super-project</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compile.source>1.8</maven.compile.source>
        <maven.compile.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가 발생합니다. 이는 매핑이 작동하고 서블릿을 찾았지만 요청을 처리할 적절한 방법이 없음을 의미합니다.

짧은 여담: "내부적으로" 어떤 일이 발생합니까?

Tomcat에서 애플리케이션이 작동하는 방식에 대해 이미 생각해 보셨을 것입니다. 거기에서 무슨 일이 일어날까요? 그리고 main() 메서드는 어디에 있습니까? 브라우저에서 localhost:8080으로 이동하는 즉시 브라우저는 HTTP 프로토콜을 사용하여 이 주소로 요청을 보냅니다. 다양한 유형의 요청이 있으며 가장 많이 사용되는 요청은 GET 및 POST라는 사실을 이미 알고 계셨기를 바랍니다. 각 요청에 응답해야 합니다. GET 요청은 바로 사용할 수 있는 HTML 코드의 응답을 받고 브라우저로 반환됩니다. 그런 다음 브라우저는 코드를 모든 예쁜 문자, 버튼 및 양식으로 대체합니다. POST 요청은 일부 정보도 전달하기 때문에 조금 더 흥미롭습니다. 예를 들어 웹 사이트의 등록 또는 로그인 양식에 자격 증명을 입력하고 "보내기"를 클릭한다고 가정합니다. 이로 인해 개인 정보가 포함된 POST 요청이 서버로 전송됩니다. 서버는 이 정보를 수신하여 처리하고 일부 응답(예: 프로필이 있는 HTML 페이지)을 반환합니다. 주요 차이점은 GET 요청은 서버에서 데이터를 검색하는 데만 사용되는 반면 POST 요청은 일부 정보를 전달한다는 것입니다(서버의 데이터는 변경될 수 있음). 예를 들어 사진을 서버에 업로드하면 사진이 POST 요청으로 전달되고 서버는 사진을 데이터베이스에 추가합니다. 즉, 변경이 발생합니다. 이제 Tomcat으로 돌아갑니다. 클라이언트로부터 요청을 받으면 주소를 확인합니다. 해당 주소(또는 즉시 반환될 수 있는 사용 가능한 리소스)에 대한 요청을 처리하기에 적합한 서블릿이 있는지 확인합니다. 반환할 항목을 찾지 못하면 그런 다음 HTML 페이지가 아닌 404 오류로 응답합니다. 그러나 해당 주소에 "앉아 있는" 적합한 서블릿을 찾으면 요청 유형(GET, POST 또는 기타)을 살펴보고 이러한 유형의 쿼리를 처리할 수 있는 메서드가 있는지 서블릿에 묻습니다. 서블릿이 이 유형을 처리하는 방법을 모른다고 하면Tomcat은 405 코드를 반환합니다. 그리고 이것은 우리 프로젝트에서 일어난 일입니다. 그러나 적절한 서블릿이 발견되고 적절한 메서드가 있으면 Tomcat은 서블릿 객체를 생성하고 새 스레드 에서 시작합니다.(자체적으로 실행되도록 함) Tomcat은 자체 작업을 계속하여 요청을 수락하고 보냅니다. 또한 Tomcat은 HttpServletRequest(줄여서 "요청"이라고 함)와 HttpServletResponse("응답"이라고 함)라는 두 개의 개체를 더 만듭니다. 클라이언트의 요청에서 받은 모든 데이터를 첫 번째 개체에 넣기 때문에 모든 데이터를 추출할 수 있습니다. 그런 다음 이 두 개체를 별도의 스레드에서 시작된 서블릿의 적절한 메서드로 전달합니다. 서블릿이 작업을 마치고 클라이언트에 보낼 준비가 된 응답을 받자마자 Tomcat에서 플래그를 흔들며 "완료되었습니다. 모든 것이 준비되었습니다"라고 말합니다. Tomcat은 응답을 받아 클라이언트로 보냅니다. 이렇게 하면 Tomcat이 요청을 받고 응답을 보낼 수 있습니다. 주의가 산만해지지 않고 모든 작업이 별도의 스레드에서 실행되는 서블릿에 의해 수행됩니다. 즉, 서블릿 코드를 작성할 때 수행할 작업을 결정합니다. 그리고 main() 메서드가 Tomcat 자체 내부에 있다고 생각할 수 있습니다(예, Java로 작성되었습니다). Tomcat을 "시작"하면 main() 메서드가 시작됩니다. 서블릿과 JSP를 사용하여 간단한 웹 애플리케이션 만들기(1부) - 2

서블릿을 사용하여 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("GET method from AddServlet");
}
ListServlet에서 비슷한 작업을 수행한 다음 서버를 다시 시작합니다. 보시다시피 모든 것이 작동합니다! 버튼을 클릭하면 PrintWriter로 "작성"한 텍스트가 있는 페이지가 표시됩니다. 그러나 응답 페이지를 생성하기 위해 준비한 JSP 파일은 사용되지 않습니다. 그들은 결코 처형되지 않았기 때문입니다. 우리 서블릿은 응답 자체를 생성하고 실행을 완료하여 클라이언트에 응답할 준비가 되었음을 Tomcat에 알립니다. Tomcat은 응답을 받아 클라이언트로 다시 보냅니다. 서블릿에서 JSP 파일로 제어권을 넘겨봅시다. 다음과 같이 메서드 코드를 변경합니다.
  • 요청 객체에서 요청 디스패처 객체를 얻고 제어를 전송하려는 JSP 페이지의 주소를 전달합니다.
  • 이 개체를 사용하여 Tomcat에서 받은 요청 및 응답 개체를 전달하는 것을 잊지 않고 지정된 JSP 페이지로 제어를 전송합니다.

@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 페이지로 제어가 전달됩니다. 지금은 여기까지입니다. 이 문서의 다음 부분 에서는 응용 프로그램의 기능에 대해 작업합니다.
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION