JSP(+MVC Pattern)の使用


react、angular、vueなどのフロントエンドフレームワークは比較的発達しており、現在はあまり使われていないが、JSPはjavaサーバベースの動的ウェブページ開発技術である.JSPではHTMLでJavaを使用できます.内部では、サーブレットに変換した後に実行されます.
HTMLを送信する場合、以下のようにhtmlコードを出力します.印刷しました.
out.print("<!DOCTYPE html><html lang='en'><head><meta charset='UTF-8' /><meta http-equiv='X-UA-Compatible' content='IE=edge' /><meta name='viewport' content='width=device-width, initial-scale=1.0' /><title>도서 입력</title></head><body><h2>입력 내용</h2><div>");
			out.print(book.toString());
			out.print("</div></body></html>");
htmlを出力します.printに送信すると、複雑になると、作成や修正が難しくなります.だからJSPが現れた

🔖 スクリプト要素Script Element


JSPファイルでは、HTMLとJavaコードを同時に使用できます.
次の3つのラベルはjavaコードを使用するためのラベルです.

宣言<%!%>


メンバー変数またはメソッドを宣言する領域.
String name;

public void init() {
	name = "abc";
}

表現<%=%>


データ出力時に-outを使用します.print()のパラメータを使用して、適切なjavaコードをすべて記述できます.
안녕하세요, <%= name %>님!

안녕하세요, <% out.print(name); %>님!
以上の2つは同じことを示し、結果値は同じです.

スクリプトツリー<%>


すべてのjavaコードが使用できます
<table>
    <% for (String name : namelist) { %>
        <tr>
            <td><%=name %></td>
        </tr>
    <% } %>
</table>
コメントは「%---%」と書くことができます.

📑 指示者指導


page directive


ページインジケータはソースコードの一番前にあります.
コンテナでJSPページを処理するために必要な様々な属性を説明する部分には、言語(スクリプトの言語指定)、コンテンツタイプ(現在のページファイル形式指定)、ページエンコーディング(文字エンコーディング指定)、インポート(javaコードを直接使用する場合に必要なパッケージインポート)、errorPage(処理中にエラーが発生した場合にエラーページを設定)、セッション(デフォルトはtrueに設定され、セッションは有効になっていません)など.
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8" import="java.util.*" errorPage="error.jsp"%>

include directive


includeインジケータは、ページに他のjspファイルを含めるために使用されます.ヘッダーやフッターなどの複数のjspページで繰り返し使用される部分をjspファイルとして個別に作成すると、重複領域に含めることができ、重複コードを減らすことができます.
<%@ include file="header.jsp" %>

taglib directive


taglibインジケータは、カスタムタグを使用するためのインジケータです.prefixはタグを区別するためのプレフィックスであり、uriはタグライブラリuriでタグを定義するファイルの位置を表す.
主に後ろのJSTLを使用します.
 <%@ taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core” %>

📦 既定のオブジェクト


JSPは内部でjava servletファイルに変換されて実行されます.
このように変換すると、コンテナは基本オブジェクト(組み込みオブジェクト)と呼ばれるオブジェクトを自動的に作成します.既に作成されているのでjspで使用できます.上記の例<%out.print(name)%>もデフォルトオブジェクトoutを使用するコードです.
基本オブジェクトのタイプは次のとおりです.

request


クライアントのリクエスト情報の保存
HTMLフォーム要素選択値などのユーザー入力情報の取得に使用
リクエストごとにrequestオブジェクトを1つずつ

response


クライアント応答情報の保存

pageContext


JSPページ情報の保存
さまざまな基本オブジェクトの取得、順方向およびinclude機能の使用
要求に対してJSPページを呼び出す-pageオブジェクト

session


クライアントの処理に使用されるセッション情報
セッション=falseをpageインジケータに指定した場合、セッションオブジェクトは作成されません.
同じWebブラウザで同じセッションをオンデマンドで共有

application


Webアプリケーション情報の保存
Webアプリケーションごとに1つのアプリケーション・オブジェクト:同じWebアプリケーションのすべてのページに対して同じアプリケーション・オブジェクトの共有を要求します.

それ以外は

  • out:outフロー処理
  • config:JSP初期化環境処理
  • page:既存ページに関する参照変数
  • exception:渡されたエラーメッセージを含むオブジェクト
  • オブジェクト範囲


    page < request < session < application

    📚 開発方式—モデル1とモデル2


    jspを用いて構成できるWebアプリケーション構造Webアプリケーションアーキテクチャは,モデル1とモデル2に大別される.2つの方式の最大の違いは,モデル1がJSPで論理処理と応答ページ(ビュー)を同時に処理することである.モデル2は応答ページ(ビュー)のみを処理し、論理部分はservletによって個別に完了する.

    Model1


    画面構成(View)だけでなく論理部分もJSPで一緒に行う.例えば、JSPでは、データベースにデータをインポートしてデータベースにデータを入れる構造が簡単で符号化が容易であるが、コード自体が複雑になりメンテナンスが難しくなり、1つのファイルにBackendとFrontendが含まれているため、連携が困難である.

    Model2


    モデル2はMVCモード導入の構造である.
    モデル1のメンテナンスが困難な欠点を補うために、modelとview、controllerを分離し、modelでは論理処理(通常javaファイル)、view(jsp)ではスクリーン処理を行い、controller(servlet)は要求を受けて分析を行い、modelを呼び出して論理処理を行い、データを適切に処理し、jspページを出力する.

    モデル2の欠点は,構造が複雑で初期に入りにくく,開発時間が増加することである.しかし,コードがそれほど複雑ではなく,分業が容易で,拡張性が高く,メンテナンスが容易であるなどの利点があるため,JSPを用いた開発では主にmodel 2,MVCモードが用いられる.

    🔍 例


    モデル2を使用する例を見てみましょう.
    以前postingサーブレットの使用で作成したコードをModel 2に従ってhtmlを出力するのではなく、jspを使用してview部分を作成して変更します.
    モデル2では、まず論理処理を行い、転送またはリダイレクトを用いて結果ページ(jsp)に移動する.

    リダイレクトと転送の違い


    response.sendRedirect(location)


    redirectは、WebサーバからWebブラウザに300回の応答を送信し、Webブラウザに別のページへのアクセスを要求する.Webブラウザは応答を受信し、要求を新しいページのURLに再送信します.

    request.getRequestDispatcher(path).forward(request, response)


    forwardはWebコンテナ内でのみページ移動を行います.Webブラウザは、最初に呼び出されたURLのみを保持し、実際に移動したアドレスを特定できません.既存のリクエスト、応答オブジェクトが直接渡されます.
    サーバがデータを処理して画面に送信する必要がある場合は、requestオブジェクトにデータをロードするにはforwardを使用する必要がありますので、forwardを使用します.リダイレクトでデータを渡すには、セッションまたはクッキーを使用する必要があります.
    まず、プロジェクトの構造は次のとおりです.

    以前にパブリケーションで見た構造とほぼ同様に、サービスが追加され、controller(servlet)の内容が変更されました.
    サービス層は、ビジネスロジックの一部を処理し、データが必要な場合はdaoを介してデータを受信し、ロジックを処理し、コントローラで使用します.
    この例では、データベースからデータをインポートするだけで済むため、以下のように簡単に実現できます.
    // BookService
    package com.practice.backend.service;
    
    import java.sql.SQLException;
    import java.util.List;
    
    import com.practice.backend.dto.Book;
    
    public interface BookService {
    	
    	int insert(Book book) throws SQLException;
    	List<Book> select() throws SQLException;
    
    }
    リクエストのたびに新しいオブジェクトを作成し続けるのは非効率なため、daoと同様に単一の色調です.
    // BookServieImpl
    package com.practice.backend.service;
    
    import java.sql.SQLException;
    import java.util.List;
    
    import com.practice.backend.dao.BookDao;
    import com.practice.backend.dao.BookDaoImpl;
    import com.practice.backend.dto.Book;
    
    public class BookServiceImpl implements BookService {
    
    	private BookDao bookDao = BookDaoImpl.getBookDao();
    	private static BookService bookService = new BookServiceImpl();
    	
    	private BookServiceImpl() {}
    	
    	public BookService getBookService() {
    		return bookService;
    	}
    	
    	@Override
    	public int insert(Book book) throws SQLException {
    		return bookDao.insert(book);
    	}
    
    	@Override
    	public List<Book> select() throws SQLException {
    		return bookDao.select();
    	}
    	
    }
    コントローラのMainServicelet部分はoutです.bookオブジェクトをprintではなくプロパティに設定し、forward register resultを使用します.jspでページを移動しました.
    //MainServlet
    package com.practice.backend.controller;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.sql.SQLException;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.practice.backend.dao.BookDao;
    import com.practice.backend.dao.BookDaoImpl;
    import com.practice.backend.dto.Book;
    
    @WebServlet("/main")
    public class MainServlet extends HttpServlet {
    	private static final long serialVersionUID = 1L;
    	private static final BookDao bookDao = BookDaoImpl.getBookDao();
        
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		request.setCharacterEncoding("utf-8");
    		doGet(request, response);
    	}
    	
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		
    		String act = request.getParameter("action");
    		
    		if ("regist".equals(act)) {
    			doRegist(request, response);
    		}
    		
    	}
    
    	private void doRegist(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {	
    		String path = "";
    		
    		Book book = new Book();
    		
    		book.setIsbn(request.getParameter("isbn"));
    		book.setTitle(request.getParameter("title"));
    		book.setAuthor(request.getParameter("author"));
    		book.setPrice(Integer.parseInt(request.getParameter("price")));
    		book.setDesc(request.getParameter("desc"));
    		book.setImg(request.getParameter("img"));
    		
    		try {
    			bookDao.insert(book);
    			request.setAttribute("book", book);
    			
    			path = "register_result.jsp";
    			
    		} catch (SQLException e) {
    			e.printStackTrace();
    			path = "error.jsp";
    		}
    		
    		request.getRequestDispatcher(path).forward(request, response);
    	}
    
    }
    <!--register_result.jsp-->
    <%@page import="com.practice.backend.dto.Book"%>
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html lang='en'>
      <head>
        <meta charset='UTF-8' />
        <meta http-equiv='X-UA-Compatible' content='IE=edge' />
        <meta name='viewport' content='width=device-width, initial-scale=1.0' />
        <title>도서 입력</title>
      </head>
      <body>
        <h2>입력 내용</h2>
        <% Book book = (Book)request.getAttribute("book");
        if (book != null) {
        	out.print(book);
        } else {
        %>
        <div>입력 내용이 없습니다.</div>
        <% } %>
    </body>
    </html>

    📰 ELとJSTL


    EL (Expression Language)


    JSPスクリプト式(<%=>)の代わりに印刷しやすいように設計された言語.
    java.util.Mapオブジェクトのキーの値またはjava beanオブジェクトのbean属性値を出力できます.たとえば、(Book)request.getAttribute("book").getIsbn()では、以下のように簡単に記述できます.
    ${book.isbn}
    上のようにお願いしますbookではなくbookとしてのみ使用する場合は、pagesScope>RequestScope>SessionScope>ApplicationsScopeの順にオブジェクトを検索します.

    JSTL (JSP Standard Tag Library)


    データ処理、条件文および重複文の処理に使用されるJSPラベル・ライブラリ
    いろいろなライブラリがありますが、よく使われているcoreを見てみましょう.
    <%@ taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core“ %>
    上記のように、先に宣言してから書くことができます.
    特定の変数またはオブジェクトのpropertyに値を割り当てる場合は、タグを使用します.
    <c:set value="value" var="varName" [scope="{page|request|session|application}"]/>
    if文を書きたい場合はと書くことができます.
    <c:if test="${!empty book}">
    </c:if>
    for文を書きたいときはと書くことができます.
    <b>1) book 리스트(books)를 반복하면서 책 제목 출력하기</b><br/>
    <c:forEach var="book" items="${books}">
    ${book.title}<br/>
    </c:forEach>

    🔍 ELとJSTLの適用例


    およびELは、上記のregister resultに用いられる.簡単にjspを変えました.
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <!DOCTYPE html>
    <html lang='en'>
      <head>
        <meta charset='UTF-8' />
        <meta http-equiv='X-UA-Compatible' content='IE=edge' />
        <meta name='viewport' content='width=device-width, initial-scale=1.0' />
        <title>도서 입력</title>
      </head>
      <body>
        <h2>입력 내용</h2>
        <c:if test="${!empty book}">${book}</c:if>
        <c:if test="${empty book}">입력 내용이 없습니다.</c:if>
    </body>
    </html>