eclipse + Tomcat + MySQL + Javaを使用して動的Web作成してみた

# やりたいこと
・eclipse,サーブレット,JSPを使用した動的Webサービスの作成

今回は、軽く説明を加えながら誰でも好きな書籍名と好きなポイントを投稿できるサービスを作成していきます。

本投稿は、とりあえず作成して動かしてみようといったコンセプトで書いていますので各詳細につきましては、他サイトをご覧ください。
下記にサンプルコードあります。

# 実行環境
・eclipse2022(4.25.0)
・Java17
・tomcat9
・MySQL

# tomcatの準備
↓ ↓ ↓ 分かりやすかったのでこちらを参考にしてください。↓ ↓ ↓
[こちらを参考にしてください。](https://harusite.net/010-2/)

# データベースの準備
### データベースとは
コンピュータ上で集積・整理された情報群のことです。
データベースには階層型データベースやリレーショナルデータベースなどの種類があり、操作にはSQLというデータベース言語が必要となる場合があります。また、数多くの情報を扱うデータベースを管理し運用する場合は、データベース管理システム（DBMS）が必要です。


今回リレーショナルデータベースであるMySQLを使用していきます。


テーブル構成はこんな感じです。
```テーブルの作成
CREATE TABLE books(id INT PRIMARY KEY AUTO_INCREMENT,
 name VARCHAR(50), favorite_book VARCHAR(50), detail VARCHAR(150));
```
カラムは、id, name, favorite_book, detailになります。


# 動的Webプロジェクトの作成
新規作成からその他を選択し、Webの項目を選択後動的Webプロジェクトを選択
![スクリーンショット 2023-03-08 212521.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2701052/99446ce6-fda3-a93c-ae48-38af12cf6bb0.png)
この時点で、完了を押さずに次へを二回押してください。

そうすると、この画面になると思います。
![スクリーンショット 2023-03-08 212507.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2701052/e90c9213-4cf1-a507-9a25-51220fda0276.png)

web.xmlデプロイメント記述子の生成(G)にチェックしてから完了を押してください。

# ファイル作成(表示部分JSPファイルの作成)
今回プロジェクト名は**sampleProject**とします。
ファイル作成の際には、必ずプロジェクトファイル(ルートディレクトリ)で右クリックを押してください。
その後、新規→その他→Web→JSPファイルを選択。
その後、次へ

![スクリーンショット 2023-03-03 185346.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2701052/96d215f5-bd55-14cf-dcd9-604c1e4c071f.png)


上記ファイル名に``view/index.jsp``と入力して完了。

同じように``view/edit.jsp`` , ``view/favoriteBook.jsp``を作成してください。

今作成しているのが、いわゆるHtmlファイルだと思ってください。

## JSPファイルの中身を記入していこう！

```index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ page import="java.util.List"%>
<%@ page import="java.util.ArrayList"%>
<%@ page import="pack.User"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ユーザー別おすすめ書籍</title>
<link rel='stylesheet' href='css/style.css'>
</head>
<body>
	<h1 class="content">おすすめの書籍を登録してみよう!</h1>
	<h2>登録者一覧</h2>
	<div>
		<table>
			<tr>
				<th>NO</th>
				<th>お名前</th>
				<th>詳細</th>
				<th>編集</th>
				<th>削除</th>
			</tr>
			<%
			for (User u : (List<User>) request.getAttribute("bookList")) {
			%>
			<tr>
				<td><%=u.getId()%></td>
				<td><%=u.getName()%></td>
				<td><a href="/sampleProject/ShowBookDetail?id=<%=u.getId()%>">詳細</a></td>
				<td><a href="/sampleProject/view/edit.jsp?id=<%=u.getId()%>">編集</a></td>
				<td><a href="/sampleProject/DeleteBook?id=<%=u.getId()%>">削除</a></td>
			</tr>
			<%
			}
			%>
		</table>
		<br>
	</div>
	<p class="content">新規おすすめ書籍登録</p>
	<form action="/sampleProject/CreateBook" method='POST'>
		投稿者名<br> <input type='text' name='name'
			placeholder='お名前を入力してください'><br> <br> お気に入り書籍<br>
		<input type='text' name='favoriteBook' placeholder='書籍名を入力してください'><br>
		<br> どういった所が気に入ったポイントですか？<br>
		<textarea type="text" name='detail' cols="35" rows="2"
			placeholder='お気に入りポイントを入力してください'></textarea>
		<br> <input class='btn' type='submit' value='新規登録'>
	</form>
</body>
</html>
```

```edit.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ page import="pack.User"%>
<%@ page import="pack.BookDAO"%>

<%
BookDAO book = new BookDAO();
book.connect();
User user = book.showUser(Integer.parseInt(request.getParameter("id")));
%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>編集</title>
<link rel='stylesheet' href='css/style.css'>
</head>
<body>
	<h2 class='content'>編集</h2>
	<form action="/sampleProject/UpdateBook?id=<%=user.getId()%>" method='POST'>
		<h3>
			NO:
			<%=user.getId()%></h3>
		投稿者名<br> <input type='text' name='name' value=<%=user.getName()%>><br>
		<br> お気に入り書籍<br> <input type='text' name='favoriteBook'
			value=<%=user.getFavoriteBook()%>><br> <br>
		お気に入りポイント<br>
		<textarea type="text" name='detail' cols="35" rows="2"><%=user.getDetail()%></textarea>
		<br> <input class='btn' type='submit' value='更新'>
	</form>
	<a href="/sampleProject/ReadUsers">戻る</a>
</body>
</html>
```

```favoriteBook.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ page import="java.util.List"%>
<%@ page import="java.util.ArrayList"%>
<%@ page import="pack.User"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel='stylesheet' href='css/style.css'>
</head>
<body>
	<h2>お気に入り詳細</h2>
	<%
	for (User u : (List<User>) request.getAttribute("bookList")) {
	%>
	<p class="content">No:</p><%=u.getId()%>
	<p class='content'>登録者:</p><%=u.getName()%>
	<hr>
	<p class='content'>おすすめ書籍:</p><%=u.getFavoriteBook()%>
	<p class='content'>お気に入りポイント</p><%=u.getDetail()%>
	<%
	}
	%>
	<p>
		<a href="/sampleProject/ReadUsers">戻る</a>
	</p>

</body>
</html>
```

## ファイルの作成(サーブレットファイル)

次にサーブレットファイル(ロジック部分の作成)
先ほどと同じように、ファイル作成の際は必ずプロジェクトファイル(ルートディレクトリ)で右クリックを押してください。
その後、新規→その他→Web→サーブレットを選択。

![スクリーンショット 2023-03-08 214112.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2701052/c932d4e9-b743-b34a-9143-b4ca03f2eda0.png)



今回パッケージ名は``pack`` , クラス名が``ReadUsers``と入力後完了を押してください。
そうすると``pack/ReadUser.java``といった感じで作成されていると思います。

同じ要領で、パッケージ名はすべて``pack``にして``CreateBook.java``, ``DeleteBook.java`` , ``ShowBookDetail.java`` , ``UpdateBook.java``
ファイルの作成をしてください。

## サーブレットファイルの中身を記入していこう！
```CreateBook.java
package pack;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class CreateBook
 */
@WebServlet("/CreateBook")
public class CreateBook extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public CreateBook() {
		super();
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		doPost(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 受け取る文字設定
		request.setCharacterEncoding("utf-8");
		// 送る文字設定(html文字;文字コード)
		response.setContentType("text/html;charset=utf-8");

		// オブジェクト指定して表示
		String name = request.getParameter("name");
		String favoriteBook = request.getParameter("favoriteBook");
		String detail = request.getParameter("detail");
		ArrayList<String> errMessage = new ArrayList<String>();
		if (name.isEmpty()) {
			errMessage.add("名前入力をしてください");
		}
		if (favoriteBook.isEmpty()) {
			errMessage.add("お気に入り書籍を入力してください");
		}
		if (detail.isEmpty()) {
			errMessage.add("詳細を入力してください");
		}

		if (name.isEmpty() || favoriteBook.isEmpty() || detail.isEmpty()) {
			PrintWriter out = response.getWriter();
			out.println("<html>");
			out.println("<head>");
			out.println("<title>確認画面</title>");
			for (String errw : errMessage) {
				out.println(errw);
			}
			out.println("</body>");
			out.println("</html>");
		} else {
			BookDAO book = new BookDAO();
			book.connect();
			book.createFavoriteBook(name, favoriteBook, detail);
			response.sendRedirect("/sampleProject/ReadUsers");
		}
	}

}
```

```DeleteBook.java
package pack;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/DeleteBook")
public class DeleteBook extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public DeleteBook() {
		super();
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 受け取る文字設定
		request.setCharacterEncoding("utf-8");
		// 送る文字設定(html文字;文字コード)
		response.setContentType("text/html;charset=utf-8");

		BookDAO book = new BookDAO();
		book.connect();
		book.deleteUser(Integer.parseInt(request.getParameter("id")));

		response.sendRedirect("/sampleProject/ReadUsers");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}
```

```ReadUser.java
package pack;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class ReadUsers
 */
@WebServlet("/ReadUsers")
public class ReadUsers extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public ReadUsers() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 受け取る文字設定
		request.setCharacterEncoding("utf-8");
		// 送る文字設定(html文字;文字コード)
		response.setContentType("text/html;charset=utf-8");

		BookDAO book = new BookDAO();
		book.connect();

		request.setAttribute("bookList", book.readUsers());
		//JSPにフォワード
		RequestDispatcher rd = request.getRequestDispatcher("/view/index.jsp");
		rd.forward(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

```
```ShowBookDetail.java
package pack;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class ShowBookDetail
 */
@WebServlet("/ShowBookDetail")
public class ShowBookDetail extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public ShowBookDetail() {
		super();
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 受け取る文字設定
		request.setCharacterEncoding("utf-8");
		// 送る文字設定(html文字;文字コード)
		response.setContentType("text/html;charset=utf-8");

		String URL = "jdbc:mysql://localhost/データベース名";
		String USER = "データベースユーザー名";
		String PASS = "データベースパスワード";

		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;

		try {
			Class.forName("com.mysql.cj.jdbc.Driver");
			con = DriverManager.getConnection(URL, USER, PASS);
			pstmt = con.prepareStatement("select * from users where id = ?");
			int userId = Integer.parseInt(request.getParameter("id"));
			pstmt.setInt(1, userId);

			rs = pstmt.executeQuery();
			List<User> bookList = new ArrayList<User>();
			while (rs.next()) {
				User user = new User();
				user.setId(rs.getInt("id"));
				user.setName(rs.getString("name"));
				user.setFavoriteBook(rs.getString("favorite_book"));
				user.setDetail(rs.getString("detail"));
				bookList.add(user);
			}

			request.setAttribute("bookList", bookList);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (rs != null)
					rs.close();
				if (pstmt != null)
					pstmt.close();
				if (con != null)
					con.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		//JSPにフォワード
		RequestDispatcher rd = request.getRequestDispatcher("/view/favoriteBook.jsp");
		rd.forward(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

```
```UpdateBook.java
package pack;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class UpdateBook
 */
@WebServlet("/UpdateBook")
public class UpdateBook extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public UpdateBook() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 受け取る文字設定
		request.setCharacterEncoding("utf-8");
		// 送る文字設定(html文字;文字コード)
		response.setContentType("text/html;charset=utf-8");
		// オブジェクト指定して表示
		String name = request.getParameter("name");
		String favoriteBook = request.getParameter("favoriteBook");
		String detail = request.getParameter("detail");
		ArrayList<String> errMessage = new ArrayList<String>();
		if (name.isEmpty()) {
			errMessage.add("名前入力をしてください");
		}
		if (favoriteBook.isEmpty()) {
			errMessage.add("お気に入り書籍を入力してください");
		}
		if (detail.isEmpty()) {
			errMessage.add("詳細を入力してください");
		}

		if (name.isEmpty() || favoriteBook.isEmpty() || detail.isEmpty()) {
			PrintWriter out = response.getWriter();
			out.println("<html>");
			out.println("<head>");
			out.println("<title>確認画面</title>");
			for (String errw : errMessage) {
				out.println(errw);
			}
			out.println("</body>");
			out.println("</html>");
		} else {
			BookDAO book = new BookDAO();
			book.connect();
			book.updateUser(request.getParameter("name"), request.getParameter("favoriteBook"),
					request.getParameter("detail"),
					Integer.parseInt(request.getParameter("id")));
			response.sendRedirect("/sampleProject/ReadUsers");
		}
	}

}

```
ここまでが、サーブレットの作成になります。

# ファイルの作成(データベース操作クラス,個人情報を持たせるためのUserクラス)

次にクラスファイル(操作・情報を保持するクラスの作成)
先ほどと同じように、ファイル作成の際は必ずプロジェクトファイル(ルートディレクトリ)で右クリックを押してください。
その後、新規→その他→Java→クラスを選択。

![スクリーンショット 2023-03-08 214919.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2701052/c4dbdbdc-3e8e-7645-3883-d293c857a070.png)


こんな感じで、パッケージ名``pack`` , 名前``BookDAO``といった感じで入力後完了を押してください。

その後、同じ要領で``User``を作成してください。

``BookDAO.java``クラスはデータベースに接続して値を操作するためのクラスです。
``User.java``クラスはデータベースのカラムに対して保存したり、表示させるため値を持たせる際に使用します。


## クラス・DAOファイルの中身を記入していこう！
```User.java
package pack;

import java.io.Serializable;

public class User implements Serializable {
	private int id;
	private String name;
	private String favoriteBook;
	private String detail;

	public int getId() {
		return this.id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getFavoriteBook() {
		return this.favoriteBook;
	}

	public void setFavoriteBook(String favoriteBook) {
		this.favoriteBook = favoriteBook;
	}

	public String getDetail() {
		return this.detail;
	}

	public void setDetail(String detail) {
		this.detail = detail;
	}
}

```

```BookDAO.java
package pack;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

public class BookDAO {
	private String URL = "jdbc:mysql://localhost/データベース名";
	private String USER = "データベースユーザー名";
	private String PASS = "データベースパスワード";
	Connection con = null;

	/*
	 * DB接続
	 * */
	public void connect() {
		try {
			Class.forName("com.mysql.cj.jdbc.Driver");
			con = DriverManager.getConnection(URL, USER, PASS);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/*
	 * 新規投稿機能
	 * */
	public void createFavoriteBook(String name, String favoriteBook, String detail) {
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			Class.forName("com.mysql.cj.jdbc.Driver");
			con = DriverManager.getConnection(URL, USER, PASS);
			pstmt = con.prepareStatement("insert into users(name, favorite_book, detail) values(?, ?, ?)");

			pstmt.setString(1, name);
			pstmt.setString(2, favoriteBook);
			pstmt.setString(3, detail);

			pstmt.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (rs != null)
					rs.close();
				if (pstmt != null)
					pstmt.close();
				if (con != null)
					con.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/*
	 * DB情報(id, name)取得
	 * */
	public List<User> readUsers() {
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		List<User> bookList = new ArrayList<User>();
		try {
			Class.forName("com.mysql.cj.jdbc.Driver");
			con = DriverManager.getConnection(URL, USER, PASS);
			pstmt = con.prepareStatement("select id, name from users");

			rs = pstmt.executeQuery();

			while (rs.next()) {
				User user = new User();
				user.setId(rs.getInt("id"));
				user.setName(rs.getString("name"));
				bookList.add(user);
			}
			return bookList;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (rs != null)
					rs.close();
				if (pstmt != null)
					pstmt.close();
				if (con != null)
					con.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return bookList;
	}

	/*
	 * DB情報一件を指定して取得
	 * */
	public User showUser(int id) {
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		User user = new User();
		try {
			pstmt = con.prepareStatement("select * from users where id = ?");
			pstmt.setInt(1, id);

			rs = pstmt.executeQuery();
			while (rs.next()) {
				user.setId(rs.getInt("id"));
				user.setName(rs.getString("name"));
				user.setFavoriteBook(rs.getString("favorite_book"));
				user.setDetail(rs.getString("detail"));
			}
			return user;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (rs != null)
					rs.close();
				if (pstmt != null)
					pstmt.close();
				if (con != null)
					con.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return user;
	}

	/*
	 * 投稿情報の更新
	 * */
	public void updateUser(String name, String favoriteBook, String detail, int id) {
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			pstmt = con.prepareStatement("update users set name = ?, favorite_book = ?, detail = ? where id = ?");

			pstmt.setString(1, name);
			pstmt.setString(2, favoriteBook);
			pstmt.setString(3, detail);
			pstmt.setInt(4, id);

			pstmt.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (rs != null)
					rs.close();
				if (pstmt != null)
					pstmt.close();
				if (con != null)
					con.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/*
	 * 投稿情報削除
	 * */
	public void deleteUser(int id) {
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			pstmt = con.prepareStatement("delete from users where id = ?");
			pstmt.setInt(1, id);

			pstmt.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (rs != null)
					rs.close();
				if (pstmt != null)
					pstmt.close();
				if (con != null)
					con.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}

```
# 実行
ここまでこれば後は、実行のみです。
![スクリーンショット 2023-03-08 220025.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2701052/b516db45-dce8-d98c-c2cf-aa68cbcc3963.png)

画像通りにサーバー実行をReadUsers.javaから実行しましょう。

これで、ページが表示されれば完了です。

以上になりますお疲れ様でした。