［Java/Eclipse/Servlet/JSP/PostgreSQL］データの投稿・保存・編集・更新・削除機能を持つWEBアプリの骨組み

## この記事の内容
データの投稿・保存・編集・更新・削除機能を持つアプリをJavaで開発、その備忘録

## この記事を書いた人の特徴
・Railsでデータの投稿・保存・編集・更新・削除機能を持つWEBアプリを本番環境にUPさせた経験はある
・JavaでWEBアプリを開発した経験がない

## 開発環境

| 項目 |  | 
|-----|------|
| PC | MacBook Air |
| OS | MacOS Mojave |
| 言語 | Java |
| IDE | Eclipse |
| DB | PostgreSQL |
| DB管理 | pgAdmin |
| バージョン管理 | GitHub |
| ブラウザ | Chrome |


## 前提条件
###DB
① 実装する機能およびそれに対応するServlet・JSPは次の通り

| process | method | Servlet | JSP |
|-----|------|------|------|
| /list | GET | ListServlet.java | list.jsp |
| /show | GET | ShowServlet.java | list.jsp |
| /new | GET | NewServlet.java | new.jsp |
| /create | POST | CreateServlet.java | - |
| /edit | GET | EditServlet.java | edit.jsp |
| /update | POST | UpdateServlet.java | - |
| /delete | POST | DeleteServlet.java | - |


② MEMOデータベース上にPOSTSテーブルを準備し、そのテーブルとアプリを接続する

| 項目 | 値 | 
|-----|------|
| DBアドレス | http://localhost:5432/ | 
| DB | memo | 
| ユーザー名 | SAMPLEUSER |
| パスワード | SAMPLEPASSWORD|
 

```SQL:SQL
CREATE TABLE posts (
id SERIAL PRIMARY KEY,
title varchar,
content varchar
);
```

```SQL:SQL
SELECT * FROM posts;
```

```txt:SQL実行結果
id |     title     |             content              
----+---------------+----------------------------------
 14 | 2019/05/15    | memo app by Java Servlet and JSP
 15 | sample title  | sample content
 16 | memoapp       | made of Java Servlet and JSP
 17 | sample_edited | sample_edited
 21 | sample_edited | sample_edited
 22 | sample        | sample
(6 rows)
```

### Eclipse
① WEBアプリは「動的WEBプロジェクト（Dynamic WEB Project）」で作成


### その他
① 重複しているコードの共通化は、今回考慮しない
② CSS・JavaScriptでのフロントエンドデザインは、今回考慮しない


## コード例
### Servlet
#### ListServlet.java
```Java:ListServlet.java
package sample;

import java.io.IOException;
import javax.servlet.*;
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 java.util.*;
import java.sql.*;

/**
 * Servlet implementation class ListServlet
 */
@WebServlet("/list")
public class ListServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ListServlet() {
        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());
		
		//DB connection
		String url = "jdbc:postgresql://localhost:5432/memo";
		String user = "SAMPLEUSER";
		String password = "SAMPLEPASSWORD";
		
	    try{
            Class.forName("org.postgresql.Driver");
        } catch(Exception e) {
            e.printStackTrace();
        }
		
		try { 
			Connection connection = DriverManager.getConnection(url, user, password);
			connection.setAutoCommit(false);
			String sql = "SELECT * FROM posts;";
			PreparedStatement statement = connection.prepareStatement(sql);

			
			ResultSet results = statement.executeQuery();
			
			ArrayList<HashMap<String,String>> rows = new ArrayList<HashMap<String,String>>();
			
			while(results.next()) {
				HashMap<String,String> columns = new HashMap<String,String>();
				
				String id = results.getString("id");
				columns.put("id",id);
				
				String title = results.getString("title");
				columns.put("title", title);
				
				String content = results.getString("content");
				columns.put("content",content);
				
				rows.add(columns);
			}
			request.setAttribute("rows", rows);
			results.close();
			statement.close();
		
			
		} catch(Exception e) {
			e.printStackTrace();
		}
		
		RequestDispatcher dispatcher = request.getRequestDispatcher("WEB-INF/views/list.jsp");
		dispatcher.forward(request,response);
		System.out.println("-----表示中の画面-----");
		System.out.println("/list");
		System.out.println("");
	}

}

```

#### ShowServlet.java
```Java:ShowServlet.java
package sample;

import java.io.IOException;
import javax.servlet.*;
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 java.util.*;
import java.sql.*;

/**
 * Servlet implementation class ListServlet
 */
@WebServlet("/show")
public class ShowServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ShowServlet() {
        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());
		
		//DB connection
		String url = "jdbc:postgresql://localhost:5432/memo";
		String user = "SAMPLEUSER";
		String password = "SAMPLEPASSWORD";
		
	    try{
            Class.forName("org.postgresql.Driver");
        } catch(Exception e) {
            e.printStackTrace();
        }
		
		try { 
			Connection connection = DriverManager.getConnection(url, user, password);
			connection.setAutoCommit(false);
			String sql = "SELECT * FROM posts WHERE id = ?;";
			PreparedStatement statement = connection.prepareStatement(sql);
			statement.setInt(1, Integer.parseInt(request.getParameter("id")));
			
			ResultSet results = statement.executeQuery();
			
			ArrayList<HashMap<String,String>> rows = new ArrayList<HashMap<String,String>>();
			
			while(results.next()) {
				
				String id = results.getString("id");
				request.setAttribute("id", id);
				
				String title = results.getString("title");
				request.setAttribute("title", title);

				
				String content = results.getString("content");
				request.setAttribute("content", content);
				

			}
			request.setAttribute("rows", rows);
			System.out.println("-----格納されたデータ-----");
			System.out.println(rows);
			System.out.println("");
			results.close();
			statement.close();
		
			
		} catch(Exception e) {
			e.printStackTrace();
		}
		
		RequestDispatcher dispatcher = request.getRequestDispatcher("WEB-INF/views/show.jsp");
		dispatcher.forward(request,response);
		System.out.println("-----表示中の画面-----");
		System.out.println("/show?id=" + request.getParameter("id"));
		System.out.println("");
	}

}

```


#### NewServlet.java
```Java:NewServlet.java
package sample;

import java.io.IOException;
import javax.servlet.*;
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 java.util.*;
import java.sql.*;

/**
 * Servlet implementation class ListServlet
 */
@WebServlet("/new")
public class NewServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public NewServlet() {
        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());
		
		RequestDispatcher dispatcher = request.getRequestDispatcher("WEB-INF/views/new.jsp");
		dispatcher.forward(request,response);
		System.out.println("-----表示中の画面-----");
		System.out.println("/new");
		System.out.println("");
	}

}

```

#### CreateServlet.java
```Java:CreateServlet.java
package sample;

import java.io.IOException;
import javax.servlet.*;
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 java.util.*;
import java.sql.*;

/**
 * Servlet implementation class ListServlet
 */
@WebServlet("/create")
public class CreateServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public CreateServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("Served at: ").append(request.getContextPath());
		
				String title = request.getParameter("title");
				String content = request.getParameter("content");
		
		//DB connection
				String url = "jdbc:postgresql://localhost:5432/memo";
				String user = "SAMPLEUSER";
				String password = "SAMPLEPASSWORD";
				
			    try{
		            Class.forName("org.postgresql.Driver");
		        } catch(Exception e) {
		            e.printStackTrace();
		        }
				
				try { 
					Connection connection = DriverManager.getConnection(url, user, password);
					connection.setAutoCommit(false);
					String sql = "INSERT INTO posts (title,content) VALUES (?,?)" ;
					PreparedStatement statement = connection.prepareStatement(sql);
					statement.setString(1, title);
					statement.setString(2, content);
					int number = statement.executeUpdate();			
					connection.commit();
				} catch(Exception e) {
					e.printStackTrace();
				}
		
		
		
		String forward = "/memo/list";
		response.sendRedirect(forward);
		System.out.println("-----メモを投稿しました。-----");
		System.out.println("ID: " + request.getParameter("title") + " TITLE: " + request.getParameter("content"));
		System.out.println("");
	}
}


```

#### EditServlet.java
```Java:EditServlet.java
package sample;

import java.io.IOException;
import javax.servlet.*;
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 java.util.*;
import java.sql.*;

/**
 * Servlet implementation class ListServlet
 */
@WebServlet("/edit")
public class EditServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public EditServlet() {
        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());
		
		//DB connection
		String url = "jdbc:postgresql://localhost:5432/memo";
		String user = "SAMPLEUSER";
		String password = "SAMPLEPASSWORD";
		
	    try{
            Class.forName("org.postgresql.Driver");
        } catch(Exception e) {
            e.printStackTrace();
        }
		
		try { 
			Connection connection = DriverManager.getConnection(url, user, password);
			connection.setAutoCommit(false);
			String sql = "SELECT * FROM posts WHERE id = ?;";
			PreparedStatement statement = connection.prepareStatement(sql);
			statement.setInt(1, Integer.parseInt(request.getParameter("id")));
			
			ResultSet results = statement.executeQuery();
			
			ArrayList<HashMap<String,String>> rows = new ArrayList<HashMap<String,String>>();
			
			while(results.next()) {
				
				String id = results.getString("id");
				request.setAttribute("id", id);
				
				String title = results.getString("title");
				request.setAttribute("title", title);

				
				String content = results.getString("content");
				request.setAttribute("content", content);
				

			}
			request.setAttribute("rows", rows);
			System.out.println(rows);
			System.out.println("");
			results.close();
			statement.close();
		
			
		} catch(Exception e) {
			e.printStackTrace();
		}
		
		RequestDispatcher dispatcher = request.getRequestDispatcher("WEB-INF/views/edit.jsp");
		dispatcher.forward(request,response);
		System.out.println("-----表示中の画面-----");
		System.out.println("/edit?id=" + request.getParameter("id"));
		System.out.println("");
	}

}

```

#### UpdateServlet.java
```Java:UpdateServlet.java
package sample;

import java.io.IOException;
import javax.servlet.*;
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 java.util.*;
import java.sql.*;

/**
 * Servlet implementation class ListServlet
 */
@WebServlet("/update")
public class UpdateServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public UpdateServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("Served at: ").append(request.getContextPath());
		
				String title = request.getParameter("title");
				String content = request.getParameter("content");
				int id = Integer.parseInt(request.getParameter("id"));
		
		//DB connection
				String url = "jdbc:postgresql://localhost:5432/memo";
				String user = "SAMPLEUSER";
				String password = "SAMPLEPASSWORD";
				
			    try{
		            Class.forName("org.postgresql.Driver");
		        } catch(Exception e) {
		            e.printStackTrace();
		        }
				
				try { 
					Connection connection = DriverManager.getConnection(url, user, password);
					connection.setAutoCommit(false);
					String sql = "UPDATE posts SET title = ?, content = ? WHERE id = ?";
					PreparedStatement statement = connection.prepareStatement(sql);
					statement.setString(1, title);
					statement.setString(2, content);
					statement.setInt(3, id);
					int number = statement.executeUpdate();			
					connection.commit();
				} catch(Exception e) {
					e.printStackTrace();
				}
		
		
		
		String forward = "/memo/show?id=" + id;
		response.sendRedirect(forward);
		System.out.println("-----メモを更新しました。-----");
		System.out.println("ID: " + request.getParameter("id") + " TITLE: " + request.getParameter("title")  + " CONTENT: " + request.getParameter("content"));
		System.out.println("");
	}
}


```

#### DeleteServlet.java
```Java:DeleteServlet.java
package sample;

import java.io.IOException;
import javax.servlet.*;
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 java.util.*;
import java.sql.*;

/**
 * Servlet implementation class ListServlet
 */
@WebServlet("/delete")
public class DeleteServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public DeleteServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("Served at: ").append(request.getContextPath());
		
				int id = Integer.parseInt(request.getParameter("id"));
		
		//DB connection
				String url = "jdbc:postgresql://localhost:5432/memo";
				String user = "SAMPLEUSER";
				String password = "SAMPLEPASSWORD";
				
			    try{
		            Class.forName("org.postgresql.Driver");
		        } catch(Exception e) {
		            e.printStackTrace();
		        }
				
				try { 
					Connection connection = DriverManager.getConnection(url, user, password);
					String sql = "DELETE FROM posts WHERE id = ?";
					PreparedStatement statement = connection.prepareStatement(sql);
					statement.setInt(1, id);
					int number = statement.executeUpdate();			
				} catch(Exception e) {
					e.printStackTrace();
				}
		
		
		
		String forward = "/memo/list";
		response.sendRedirect(forward);
		System.out.println("-----メモを削除しました。-----");
		System.out.println("ID: " + request.getParameter("id"));
		System.out.println("");
	}
}


```

### JSP
#### list.jsp
```JSP:list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import = "java.util.*" %>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
 <h2>MEMO LIST</h2>
 <p>This app is made by Java Servlet and JSP.</p>



<table>
<tr><th>ID</th><th>TITLE</th></tr>
<% ArrayList<HashMap<String,String>> rows = (ArrayList<HashMap<String,String>>)request.getAttribute("rows"); %>

<% for(HashMap<String,String> columns: rows){ %>
<tr><td><%= columns.get("id") %></td><td><a href="show?id=<%= columns.get("id") %>"><%= columns.get("title") %></a></td></tr>
<% } %>
</table>
 
 <p></p>
 <a href="new">Create new memo</a>
</body>
</html>
```

#### show.jsp
```JSP:show.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import = "java.util.*" %>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
 <h2>MEMO DETAIL</h2>
 <p>This app is made by Java Servlet and JSP.</p>


<br>
<form action="delete?id=<%= request.getAttribute("id") %>" method="POST">
<p>ID: <%= request.getAttribute("id") %></p>
<p>TITLE: <%= request.getAttribute("title") %></p>
<p>CONTENT:</p>
<p><%= request.getAttribute("content") %></p>
<br>
 <a href="edit?id=<%= request.getAttribute("id") %>">Edit</a><br>
 <button>Delete</button><br>
 </form>
<br>
 <a href="list">Return list</a>
</body>
</html>
```


#### new.jsp
```JSP:new.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import = "java.util.*" %>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
 <h2>CREATE NEW MEMO</h2>
 <p>This app is made by Java Servlet and JSP.</p>
<p></p>

<form action="create" method="POST">
<p>TITLE:</p>
<input type=text name="title">
<p>CONTENT:</p>
<input type=text name="content">
<p></p>
 <button>Create</button><br>
 </form>
 
<p></p>
 <a href="list">Cancel</a>
</body>
</html>
```

#### edit.jsp
```JSP:edit.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import = "java.util.*" %>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
 <h2>EDIT MEMO</h2>
 <p>This app is made by Java Servlet and JSP.</p>
<p></p>

<form action="update" method="POST">
<p>ID: <%= request.getAttribute("id") %></p>
<input type='hidden' name='id' value='<%= request.getAttribute("id") %>'>
<p>TITLE:</p>
<input type="text" name="title" value="<%= request.getAttribute("title") %>">
<p>CONTENT:</p>
<input type="text" name="content" value="<%= request.getAttribute("content") %>">
<p></p>
 <button>Update</button><br>
 </form>
 
<p></p>
 <a href="list">Cancel</a>
</body>
</html>
```

## 今後やりたいこと
① ログイン・ログオフ機能の実装
② パスワードの暗号化
③ バリデーション（制約）の追加
④ 部品のテンプレート化
⑤ JavaでWEBアプリ開発（複式簿記でつける家計簿アプリ）を通じて、設計力を向上させる