前回までで登録、表示までができるようになった。今回はコンテンツの更新ができるように変更していこう。
作成
view
まずはAdminのmain.jspに更新のリンクを追加しよう。以下のハイライト部分を3行を追記する。
<%@ 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>
<td>
<a href="/donutshop/Admin/Update?id=<%=d.getId() %>">更新</a>
</td>
</tr>
<%} %>
</table>
<%} %>
</body>
</html>
daoの変更
idをもとにフォームを復元しなければならない。idをもとにDonutインスタンスを返却するfindOneメソッドを以下のように追記する。
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 title = rs.getString("name");
int price = rs.getInt("price");
String imgname = rs.getString("imgname");
list.add(new Donut(id, title, price, imgname));
}
} catch (NamingException | SQLException e) {
e.printStackTrace();
} finally {
this.disconnect();
}
return list;
}
public Donut findOne(int id) {
Donut donut = null;
try {
this.connect();
ps=db.prepareStatement("SELECT * FROM donuts WHERE id=?");
ps.setInt(1, id);
rs=ps.executeQuery();
if(rs.next()) {
String name=rs.getString("name");
int price=rs.getInt("price");
String imgname=rs.getString("imgname");
donut=new Donut(id,name,price,imgname);
}
} catch (NamingException | SQLException e) {
e.printStackTrace();
} finally {
this.disconnect();
}
return donut;
}
}
Admin/Updateコントローラー
新規サーブレットからAdminUpdate.javaを以下のように作成する。
○controller.AdminUpdate.java
package controller;
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;
import dao.DonutDAO;
import model.Donut;
@WebServlet("/Admin/Update")
public class AdminUpdate extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String id=request.getParameter("id");
if(id == null) {
response.sendRedirect("/donutshop/Admin");
return;
}
DonutDAO dao=new DonutDAO();
Donut donut=dao.findOne(Integer.parseInt(id));
request.setAttribute("donut", donut);
RequestDispatcher rd=request.getRequestDispatcher("/WEB-INF/admin/update.jsp");
rd.forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
admin/update.jsp
WEB-INF/adminフォルダ内にupdate.jspを以下のように作成する。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="model.*"%>
<%
Donut donut=(Donut)request.getAttribute("donut");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="/donutshop/Admin/Update" method="post" enctype="multipart/form-data">
商品名:<input type="text" name="name" value="<%=donut.getName() %>" required><br>
価格:<input type="number" name="price" step="10" value="<%=donut.getPrice()%>" required><br>
<img src="/donutshop/upload/<%=donut.getImgname()%>" id="preview"><br>
商品画像:<input type="file" name="imgname" id="imgname"><br>
<input type="hidden" name="id" value="<%=donut.getId() %>">
<input type="hidden" name="orgname" value="<%=donut.getImgname() %>">
<button type="submit">更新</button>
</form>
</body>
</html>
現在の画像を表示し、hiddenで現在画像の名前を渡すようにしている。
これはもし画像選択がなかった場合に現在画像のまま設定を行うためだ。
hiddenでidを渡すのはこの場合の常套手段。
実行
実行してみよう。以下のように現在の状態が復元されれば成功だ。
daoの修正
再びdaoの修正行う。今度は更新ボタンが押された時にDBを更新するメソッドUpdateOneを以下のように追記する。
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 title = rs.getString("name");
int price = rs.getInt("price");
String imgname = rs.getString("imgname");
list.add(new Donut(id, title, price, imgname));
}
} catch (NamingException | SQLException e) {
e.printStackTrace();
} finally {
this.disconnect();
}
return list;
}
public Donut findOne(int id) {
Donut donut = null;
try {
this.connect();
ps=db.prepareStatement("SELECT * FROM donuts WHERE id=?");
ps.setInt(1, id);
rs=ps.executeQuery();
if(rs.next()) {
String name=rs.getString("name");
int price=rs.getInt("price");
String imgname=rs.getString("imgname");
donut=new Donut(id,name,price,imgname);
}
} catch (NamingException | SQLException e) {
e.printStackTrace();
} finally {
this.disconnect();
}
return donut;
}
public void updateOne(Donut donut) {
try {
this.connect();
ps=db.prepareStatement("UPDATE donuts SET name=?,price=?,imgname=? WHERE id =?");
ps.setString(1,donut.getName());
ps.setInt(2, donut.getPrice());
ps.setString(3, donut.getImgname());
ps.setInt(4, donut.getId());
ps.executeUpdate();
} catch (NamingException | SQLException e) {
e.printStackTrace();
}finally {
this.disconnect();
}
}
}
AdminUpdate.javaの修正
フォームからのポスト通信があったときの処理を以下のように追記する。
○controller.AdminUpdate.java
package controller;
import java.io.File;
import java.io.IOException;
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/Update")
@MultipartConfig
public class AdminUpdate extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String id=request.getParameter("id");
if(id == null) {
response.sendRedirect("/donutshop/Admin");
return;
}
DonutDAO dao=new DonutDAO();
Donut donut=dao.findOne(Integer.parseInt(id));
request.setAttribute("donut", donut);
RequestDispatcher rd=request.getRequestDispatcher("/WEB-INF/admin/update.jsp");
rd.forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String id=request.getParameter("id");
String name=request.getParameter("name");
String price=request.getParameter("price");
String orgname=request.getParameter("orgname");
Part part=request.getPart("imgname");
String imgname;
if(part.getSize()==0) {
imgname=orgname;
}else {
imgname=part.getSubmittedFileName();
String path=getServletContext().getRealPath("/upload");
part.write(path+File.separator+imgname);
}
DonutDAO dao=new DonutDAO();
dao.updateOne(new Donut(Integer.parseInt(id),name,Integer.parseInt(price),imgname));
response.sendRedirect("/donutshop/Admin");
}
}
ファイルの送信があったかなかったかで処理を分岐している。
実行
ポンデリングをポンデリング2に価格を1100円に画像をdn7.jpgに変更してみよう。
以下のように更新されれば成功だ。
*注)このときNull Pointerが出たらソースコード19行目の
@MultipartConfig
に追記を忘れていないか確認すること
応用
JavaScriptを使うと画像アップロードの際リアルタイムでプレビュー画像を変更できる。以下を追記する。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="model.*"%>
<%
Donut donut=(Donut)request.getAttribute("donut");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="/donutshop/Admin/Update" method="post" enctype="multipart/form-data">
商品名:<input type="text" name="name" value="<%=donut.getName() %>" required><br>
価格:<input type="number" name="price" step="10" value="<%=donut.getPrice()%>" required><br>
<img src="/donutshop/upload/<%=donut.getImgname()%>" id="preview"><br>
商品画像:<input type="file" name="imgname" id="imgname" ><br>
<input type="hidden" name="id" value="<%=donut.getId() %>">
<input type="hidden" name="orgname" value="<%=donut.getImgname() %>">
<button type="submit">更新</button>
</form>
<script>
window.onload=()=>{
const inputFile=document.getElementById("imgname");
const previewImg=document.getElementById("preview");
const reader=new FileReader();
reader.addEventListener("load",()=>{
previewImg.src=reader.result;
});
inputFile.addEventListener("change",()=>{
reader.readAsDataURL(inputFile.files[0]);
});
};
</script>
</body>
</html>
リンク追加
admin/main.jspを以下のように1行加えて、公開ページへのリンクを設定しよう。
○/WEB-INF/admin/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>
<a href="/donutshop/Main">公開ページを見る</a>
<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>
<td>
<a href="/donutshop/Admin/Update?id=<%=d.getId() %>">更新</a>
</td>
</tr>
<%} %>
</table>
<%} %>
</body>
</html>
実行
Admin.javaサーブレットから実行してリンクを踏んでみよう。以下のように更新された情報が表示されれば成功だ。
4回目終了
以上で4回目終了だ。先程変更したポンデリングはもとの状態に戻しておこう。続きはこちら
コメント