JSP/サーブレットでドーナツショップのサイトを作ろう2

JSP&Servlet

前回無事にデータベースに接続することができたので今回は実際にドーナツショップオーナーである友人が操作することになる管理画面を作成していく。

今回の目標

まずは以下の状態を目指す。上に登録フォームがあり、下に現在登録されている一覧が表示される。見た目がひどいが見た目は仕組みができてから調整しよう。

準備

まずは今回のドーナツショップのサンプルデータを以下からダウンロードする。

上の素材にはドーナツ画像7枚と以下のようなドーナツデータcsvが入っている。
データ入力の際に利用してもらいたい。

商品名,価格,画像ファイル名
ポン・デ・リング,110,dn1.jpg
ポン・デ・黒糖,110,dn2.jpg
ポン・デ・ストロベリー,130,dn3.jpg
オールドファッション,110,dn4.jpg
オールドファッションハニー,130,dn5.jpg
フレンチクルーラー,110,dn6.jpg
ストロベリー カスタードフレンチ,140,dn7.jpg

作成

uploadフォルダ

最初にアップロードされた画像を保存する場所を作っておこう。WebContentの直下にuploadフォルダを作成する。

model

実際の作成はmodelを作成するところから始まる。データベースの構造を見ながら以下のようなmodelを作成する。新規クラスからDonut.java(modelパッケージ)を以下のように作成する。

○model.Donut.java

package model;

import java.io.Serializable;

public class Donut implements Serializable{
	private int id;
	private String name;
	private int price;
	private String imgname;

	public Donut() {}

	public Donut(String name, int price, String imgname) {
		this.name = name;
		this.price = price;
		this.imgname = imgname;
	}

	public Donut(int id, String name, int price, String imgname) {
		this(name,price,imgname);
		this.id = id;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}
	public String getImgname() {
		return imgname;
	}
	public void setImgname(String imgname) {
		this.imgname = imgname;
	}
}

説明不要だろう。javaBeansの仕様を満たすことに注意してDBのカラムを元にクラスを作成した。

dao

次にデータベース関連の処理を作成する。今回の目標を満たすためには
○フォームに入力された情報をもとに1件をテーブルに挿入
○テーブルに入っている全レコードの取得
の処理を作れば良さそうだ。
前回作成したDonutDAO.javaを以下ハイライト部分を追記する。

package dao;

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

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import model.Donut;

public class DonutDAO {
	private Connection db;
	private PreparedStatement ps;
	private ResultSet rs;

	private void connect() throws NamingException, SQLException {
		Context context = new InitialContext();
		DataSource ds = (DataSource) context.lookup("java:comp/env/donutapp");
		this.db = ds.getConnection();
	}

	private void disconnect() {
		try {
			if (rs != null) {
				rs.close();
			}
			if (ps != null) {
				ps.close();
			}
			if (db != null) {
				db.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public void ConnectCheck() {
		try {
			this.connect();
			System.out.println("OK");
		} catch (NamingException | SQLException e) {
			e.printStackTrace();
		} finally {
			this.disconnect();
		}
	}

	public void insertOne(Donut donut) {
		try {
			this.connect();
			ps = db.prepareStatement("INSERT INTO donuts(name,price,imgname) VALUES(?,?,?)");
			ps.setString(1, donut.getName());
			ps.setInt(2, donut.getPrice());
			ps.setString(3, donut.getImgname());
			ps.execute();
		} catch (NamingException | SQLException e) {
			e.printStackTrace();
		} finally {
			this.disconnect();
		}
	}

	public List<Donut> findAll() {
		List<Donut> list = new ArrayList<>();
		try {
			this.connect();
			ps = db.prepareStatement("SELECT * FROM donuts");
			rs = ps.executeQuery();
			while (rs.next()) {
				int id = rs.getInt("id");
				String name = rs.getString("name");
				int price = rs.getInt("price");
				String imgname = rs.getString("imgname");
				list.add(new Donut(id, name, price, imgname));
			}
		} catch (NamingException | SQLException e) {
			e.printStackTrace();
		} finally {
			this.disconnect();
		}
		return list;
	}
}

controller

コントローラーを作成する。新規サーブレットから
Admin.java(controllerパッケージ)を作成する。

○controller.Admin.java

package controller;

import java.io.IOException;
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;

import dao.DonutDAO;
import model.Donut;

@WebServlet("/Admin")
public class Admin extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		DonutDAO dao=new DonutDAO();
		List<Donut> list=dao.findAll();
		request.setAttribute("list", list);
		RequestDispatcher rd=request.getRequestDispatcher("/WEB-INF/admin/main.jsp");
		rd.forward(request, response);
	}

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

}

/AdminというGetリクエストがあったときの処理をdoGetに記述している。
データベースから登録済みのリストを取得し、リクエストスコープに格納し、viewにフォワードしている。

view

viewを作成していこう。WEB-INFの中にadminフォルダを作成し、その中にmain.jspを作成する。

○main.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*,model.*"%>
<%
	List<Donut> list=(List<Donut>)request.getAttribute("list");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="/donutshop/Admin" method="post" enctype="multipart/form-data">
商品名:<input type="text" name="name" required><br>
価格:<input type="number" name="price" step="10" required><br>
商品画像:<input type="file" name="imgname"><br>
<button type="submit">登録</button>
</form>

<% if(list != null && list.size()>0){ %>
<table border="1">
<%for(Donut d:list){ %>
<tr>
<td><img src="/donutshop/upload/<%=d.getImgname() %>"></td>
<td><%=d.getId() %></td>
<td><%=d.getName() %></td>
<td><%=d.getPrice() %></td>
</tr>
<%} %>
</table>
<%} %>
</body>
</html>

ファイル送信を含むフォームだ。詳しくはこちらの記事を参照してほしい。

実行

Admin.javaサーブレットを右クリックしてサーバー実行してみよう。まだDBにデータは無いので以下のようにフォームが表示されれば成功だ。

controller(doPost)

ではフォームに入力された情報を元に画像を保存し、データをDBに格納する処理を記述しよう。以下のハイライト部分をAdmin.javaに追記する。

○controller.Admin.java

package controller;

import java.io.File;
import java.io.IOException;
import java.util.List;

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

import dao.DonutDAO;
import model.Donut;

@WebServlet("/Admin")
@MultipartConfig
public class Admin extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		DonutDAO dao=new DonutDAO();
		List<Donut> list=dao.findAll();
		request.setAttribute("list", list);
		RequestDispatcher rd=request.getRequestDispatcher("/WEB-INF/admin/main.jsp");
		rd.forward(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		String name=request.getParameter("name");
		int price=Integer.parseInt(request.getParameter("price"));
		Part part=request.getPart("imgname");
		String imgname=part.getSubmittedFileName();
		String path=getServletContext().getRealPath("/upload");
		part.write(path+File.separator+imgname);
		DonutDAO dao=new DonutDAO();
		dao.insertOne(new Donut(name,price,imgname));
		doGet(request,response);
	}

}

ファイルアップロード時の処理を行い。DBに登録している。(ファイルアップロード処理の詳細はこちら)

*注)このときNull Pointerが出たらソースコード20行目の
@MultipartConfig
に追記を忘れていないか確認すること

実行

では、Admin.javaをサーバーで実行して実際に以下のように情報を入力して登録ボタンを押してみよう。

名前:ポン・デ・リング
値段:110
商品画像:(素材にあったdn1.jpgを選択)

以下のように下部に登録された情報が表示されれば成功だ。

残りのデータも追加

残りの6個のドーナツも登録しておこう。

第2回終了

以上で第2回終了だ。次回は公開ページでこの商品が表示されるようにしていく。

コメント

タイトルとURLをコピーしました