JavaのWeb基礎、Servlet、JSP

## Web基礎
普段インターネットでWebページを見る時には二つのコンピューターが関連して動いている
①**Webブラウザ**：Webページを表示するソフトウェア
②**Webサーバー**：Webページの情報を提供出来るソフトウェア（コンピュータ）

WebブラウザとWebサーバーの間では二つのやり取りが行われている。
①**リクエスト**：Webページの情報をサーバーに要求すること
②**レスポンス**：リクエストに対してサーバーが情報を返すこと

・Web環境で動くプログラムをWebアプリケーションといい。**サーバーサイド（バックエンド）** と**クライアントサイド（フロントエンド）** に分かれる
サーバーサイドではJavaやPHP、Pythonなどが使用されクライアントサイドではJavaScriptが使用される事が多い
![スクリーンショット 2023-01-05 22.08.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2785154/a4fbe6cd-32a4-3cdf-f6ba-325a4d55974c.png)

## Servlet
Servlet(サーブレット)とは**Webサーバー側**で動くJavaプログラムの事

サーブレットは、クライアントサイドからリクエストを受け取ると、そのリクエストがGETメソッドかPOSTメソッドかを判断する。（GETメソッドは指定したURLの情報を探し出してきて送り返して欲しいというリクエストで、POSTメソッドは送ったデータを基に処理して返して欲しいというリクエスト。）

GETメソッドの場合にはサーブレットのdoGetメソッドを呼び出し、指定のURLから探し出した情報は後ほど紹介するJSPに送られ、そこからクライアントサイドに情報を届ける。
POSTメソッドの場合には、サーブレットのdoPostメソッドを呼び出し、必要なデータ処理を行い、サーブレットからクライアントサイドに返答する。

### Servletの作り方
**①４つのパッケージをインポートする**

**②マッピング名（アノテーション）を指定する**
アノテーションとは「＠」から始まる記述でプログラムに補足情報を加える事が出来き、アドレスと動くサーブレットの対応付けをアノテーションで指定する
@WebServlet()アノテーションでJavaファイルがServletであることを示している
@WebServlet()アノテーションで引数にURLパス（マッピング名）を記述する事でサーブレットを呼び出すためのURLパスを指定する
![スクリーンショット 2023-01-06 22.20.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2785154/7326bc71-ecfb-d51e-3db6-2ea3dd5d27ba.png)

**③HttpServletクラスを継承する**
HttpServletは、サーブレットに必要な機能を提供するクラス。クラス自体は抽象クラスになり各メソッドをオーバーライドをする前提となっていて、各メソッドをオーバーライドして独自の処理を書く

**④doGet（）／doPost（）メソッドをオーバーライドする**
HttpServletクラスにはdoGet（）／doPost（）メソッドが用意されていて、リクエストがあった場合に呼び出され、リクエストの内容を伝えるオブジェクトが渡されるようになっている。HttpServletクラスでは、このような仕組みを作っておいて、あとはサーブレットを作る側がクラスの機能を引継ぎながら、独自の機能を追加できるようにしている
| メソッド | 内容 |
| --- | --- |
| doGet（） | リクエストがHTTP GET（サーバに対してページの取得を要求）メソッドである場合。 |
| doPost（） | リクエストがHTTP POST（フォームに入力したデータをサーバに転送する）メソッドである場合。 |

引数に記述しているHttpServletRequestは、doGet()、doPost()などが受け取るクライアントからサーバに送られたリクエスト情報が格納されているオブジェクト。 言い換えると、HTTPリクエストに詰まっている情報をこのオブジェクトから取得することができる。
HttpServletResponseは、doGet()、doPost()などで受け取るサーバからクライアントへ応答するときに必要なレスポンス情報が格納されているオブジェクトになる。

HttpServletRequestとHttpServletResponseについての詳しくはこの記事へ

https://qiita.com/mrshouuge/items/aa8c02af562a35e547aa

```
// ①↓４つのパッケージをインポートする
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;

// ②マッピング名（アノテーション）を指定
@WebServlet("/first")     
// ③↓HttpServletクラスを継承する
public class FirstServlet extends HttpServlet {   

  // ④↓doGet（）／doPost（）メソッドをオーバーライドする
  public void doGet(HttpServletRequest req, HttpServletResponse res)
      throws IOException, ServletException {     
    res.setContentType("text/html;charset=utf-8");  // コンテンツタイプを指定
    PrintWriter out = res.getWriter();              // PrintWriterを取得
    out.println("<html>");                          // PrintWriterで出力
    out.println("<head>");
    out.println("<title>はじめてのサーブレット</title>");
    out.println("</head>");
    out.println("<body>");
    out.println("<h1>サーブレットを始めよう！</h1>");
    out.println("</body>");
    out.println("</html>");
  }
}
```

## JSP
JSPとはJavaServer Pageの略で、サーブレットと同じくサーバ上で動作させるもの
HTMLの中にJavaのコードを埋め込み、プログラムで処理が必要な部分だけを記述することで、動的なWebページを作る事が出来る。
**Servletとの違い**
![スクリーンショット 2023-01-07 14.02.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2785154/92d2fd2d-a622-1757-29ea-56237f50183f.png)
サーブレットはJavaの中にHTMLが含まれるがJSPではHTMLの中にJavaが含まれる

・JSP実行の動き
![スクリーンショット 2023-01-07 14.20.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2785154/57fc005f-5260-382c-3b3f-abdd81c0a2d1.png)


```:サンプル
// pageディレクティグの記述
<%@ page contentType="text/html;charset=UTF-8" %>
<html>
    <head>
        <title>Hello World!</title>
    </head>
    <body>
        // Javaの記述を埋め込んでいる
        <h1><% out.println("Hello World!"); %></h1>
    </body>
</html>
```
一番上に記述されているものは**ディレクティブタグ**と言われるもので「<%@」で始まり「%>」で終わります。この中にディレクティブ名(属性名)と属性値を指定している
```
<%@ ディレクティブ名 属性名1="属性値1" 属性名2="属性値2" ... %>
```
今回記述してあるのはpageディレクティブでJSPファイル全体の設定をし、コンテンツタイプと出力の文字エンコーディングを指定している。
```
<%@ page contentType="text/html;charset=UTF-8" %>
```
この記述をする事でサーブレットに変換された時に
```
res.setContentType("text/html;charset=utf-8");  
```
setContentTypeメソッドの引数に属性が入って処理が実行される

## ServletとJSPの連携
```:register3.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8"/>
  <title>登録画面</title>
</head>
<body>
  <h1>登録情報を入力してください</h1>
  <form action="/javaweb/register3" method="post">
  名前：<input type="text" name="name" size="10" /><br/>
  パスワード：<input type="password" name="pass" size="10" /><br/>
  年齢：<input type="radio" name="age" value="child" />18歳未満　
        <input type="radio" name="age" value="adult" />18歳以上<br/>
  開発経験：<input type="checkbox" name="lang" value="Java" />Java　
        <input type="checkbox" name="lang" value="Python" />Python　
        <input type="checkbox" name="lang" value="JavaScript" />JavaScript<br/>
  住所：<select name="address" size="1">
          <option value="北海道">北海道</option>
          <option value="東北">東北</option>
          <option value="関東">関東</option>
          <option value="中部">中部</option>
          <option value="近畿">近畿</option>
          <option value="中国">中国</option>
          <option value="四国">四国</option>
          <option value="九州">九州</option>
          <option value="沖縄">沖縄</option></select><br/>
  ご意見・お問い合わせ：<br/>
  <textarea name="msg" rows="5" cols="50">入力欄</textarea><br/>
  <input type="submit" value="送信" />　
  <input type="reset" value="取消" />
  </form>
</body>
</html>
```
formタグ内のaction属性にフォームに入力された情報の送信先を指定する。method属性をpostに指定すると、入力したフォーム内容はURIとは別の場所に保管されてデータが送信され、入力したフォーム内容のデータは外側からの表示では見ることができないので安全性が高くなる

サーブレット内の@WebServletアノテーションでマッピングに「"/register3"」を指定しているのでHTML内で入力された値がRegisterServlet3.javaに送られる

```:RegisterServlet3.java(サーブレット)
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;

@WebServlet("/register3")
public class RegisterServlet3 extends HttpServlet {
  public void doPost(HttpServletRequest req, HttpServletResponse res)
      throws IOException, ServletException {
    req.setCharacterEncoding("utf-8");

    // getParameterメソッドでname = "age"の情報（value）を取り出している
    String age = req.getParameter("age");
    if(age.equals("child")){
      age = "18歳未満";
    } else {
      age = "18以上";
    }

    // リクエストオブジェクトに上記のif分内の変数ageを属性名"age"に格納する
    req.setAttribute("age", age);

    String langs = "";
    String[] lang = req.getParameterValues("lang");
    for(int i = 0; i < lang.length; i++){
      langs = langs + lang[i] + " ";
    }
    // リクエストオブジェクトに変数langsを属性名"langs"に格納する
    req.setAttribute("langs", langs);
    

    RequestDispatcher rd = req.getRequestDispatcher("/register3.jsp");
    rd.forward(req, res);
  }
  public void doGet(HttpServletRequest req, HttpServletResponse res)
      throws IOException, ServletException {
    doPost(req, res);
  }
}
```
「   RequestDispatcher rd = req.getRequestDispatcher("/register3.jsp");
    rd.forward(req, res);」の記述でリクエストオブジェクト(req)に格納された値をregister3.jspに**ディスパッチ（転送）** している
ディスパッチとは、あるサーブレットの処理を、他のサーブレットや、JSPファイルなどに転送できる機能。

転送するにはRequestDispatcherのオブジェクトを取得する必要がある。
（RequestDispatcherはサーブレットからJSPを表示するためのインターフェイスの一つ）
getRequestDispatcherメソッドの引数に転送先を指定し、RequestDispatcherのオブジェクトにforward(req, res)メソッドを使う事で指定のJSPへ転送できる。

```:register3.jsp（JSP）
<%@page contentType="text/html;charset=utf-8" %>
<html>
  <head>
    <title>確認画面</title>
  </head>
<body>
  <h2>入力情報を確認して登録ボタンを押してください</h2>
  氏名：<strong><%= request.getParameter("name") %></strong><br/>
  パスワード：<strong><%= request.getParameter("pass") %></strong><br/>
  年齢：<strong><%= request.getAttribute("age") %></strong><br/>
  開発経験：<strong><%= request.getAttribute("langs") %></strong><br/>
  住所：<strong><%= request.getParameter("address") %></strong><br/>
  ご意見・お問い合わせ：<br/><strong><%= request.getParameter("msg") %></strong><br/><br/>
<input type="submit" value="登録" />
<input type="reset" value="戻る" /><br/><br/>
（この画面はフォワード先のJSPで出力しています）
</body>
</html>
```
register3.jspにはRegisterServlet3.java（サーブレット）から転送された情報（値）が表示される

**register3.htmlの画像**
![スクリーンショット 2023-01-07 16.56.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2785154/312fbd81-88ce-a36b-81e4-7d83664946f7.png)
register3.htmlのフォームで入力された値が「action="/javaweb/register3" method="post"」の記述でRegisterServlet3.java(サーブレット)に送られる。
サーブレット内のメソッド内の処理が実行されてregister3.jsp（JSP）に転送される
　　　　　↓
**register3.jspの画像**
![スクリーンショット 2023-01-07 17.00.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2785154/73a4d0ab-cc74-36cc-04d4-22107ce1c0e2.png)
register3.jspにRegisterServlet3.java（サーブレット）から転送された情報（値）が表示される


## 参考記事
http://web.javastudy.biz/?p=229

https://www.youtube.com/watch?v=LiI6OzQSoxs&t=65s

https://www.youtube.com/watch?v=dQG0wKePErM&t=0s

https://www.youtube.com/watch?v=0wXj5RCE28o&list=PLru8-xuz0YvycnjfIkn8_Sqpe-n2_5xPN&index=11