今回の記事はこちらの記事の続きとなっております。
現在Java(サーブレット・jsp) x PostgreSQLを使ってTodoアプリを作成しています。現時点での機能は次のとおりです。
前回作成したログイン機能はとりあえずidとパスワードを使って認証するだけというものでした。そのためログインしていない状態でも、Todoの一覧閲覧や、新規作成を行えてしまうという状態でした。そこで今回の記事ではログインしていない状態では一覧の閲覧や新規作成を行えないようにします。
今回は以下のような流れで開発を進めていきます。
- 認証を行うBaseServletの作成
- BaseServletを各Servletに継承させる
その他の機能の作成記事はこちらの記事にまとめています。
GitHubにソースがあるので、参考にしてください!ご質問等あればTwitterまでお願いします。
挫折せずにプログラミングを学ぶために必要なこと
僕はプログラミングで挫折した経験があります。
それは周りに聞ける人がいなく、一人でエラーと戦っていたからです。
Freeksは月額10,780円という破格の値段で、現役エンジニアに質問する環境を手に入れることができるプログラミングスクールです。
次のような悩みを少しでも抱えていたら、まずは無料カウンセリングを受けてみてください。
申込みは1分でできます。学習する環境にお金を使うというのは良い自己投資になります。
>>Freeksの無料カウンセリングはこちら
BaseServletの作成
まずはBaseServletを作成します。BaseServletの役割はユーザーがログインしているかどうか判定します。判定方法は、セッションにユーザーIDが存在するかどうかで判定します。ログインしていた場合、各画面の処理をよび、ログインしていなかった場合ログイン画面に遷移します。
このBaseServletをログインしている時のみ行わせたいServletが継承することで、ログイン認証を常に行うようにします。
BaseServletは以下のようになります。まずBaseServlet自体は継承されることを前提としたした抽象クラスとします。その上でdoGet, doPostメソッドを用意します。doGetメソッドはdoPostメソッドを呼び出すだけにします。doPostメソッド内でセッションのログイン情報をチェックします。ログインしていた場合はexecメソッドを実行します。このexecメソッドはBaseServletでは抽象メソッドとしておきます。BaseServletを継承した各Servletではそれぞれの処理を記述します。
package servlet;
import java.io.IOException;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import constant.SessionInfo;
/**
* Servlet implementation class BaseServlet
*/
public abstract class BaseServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public BaseServlet() {
super();
}
/**
* doPostメソッドを呼び出す
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
/**
* ログイン済みかどうかを判定する
* ログイン済みの場合各処理を実行
* ログインしていない場合ログイン画面に遷移する
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// セッションからログイン中のユーザーIDを取得する
HttpSession session = request.getSession();
String loginUserId = (String)session.getAttribute(SessionInfo.LOGIN_USER_ID);
// セッションにログイン中のユーザーIDが存在する時
if (loginUserId != null) {
try {
exec(request, response);
} catch (SQLException | ClassNotFoundException e) {
e.printStackTrace();
}
} else {
request.getRequestDispatcher("WEB-INF/jsp/login.jsp").forward(request, response);;
}
}
/**
* 各サーブレットの処理を記述する
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
protected abstract void exec(
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException, SQLException, ClassNotFoundException;
}
BaseServletを継承
各Servletで先ほど作成したBaseServletを継承します。
ListServlet
まずはListServletで継承します。クラスの宣言部分でHttpServletを継承していましたが、これをBaseServletに変更します。
public class ListServlet extends BaseServlet
その上でexecメソッドを定義し、doGetに書かれていた処理をこちらに移します。移しおえたらdoGetメソッドは全て削除してしまって大丈夫です。
/**
* todoテーブルからtodoを取得し、一覧表示する
*/
@Override
protected void exec(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException, SQLException, ClassNotFoundException {
// todoの一覧を保持する変数を宣言
List<TodoDTO> todoList = new ArrayList<>();
// DAOを生成し、Todo一覧を取得する
TodoListDAO dao = new TodoListDAO();
// todo一覧を取得する
todoList = dao.getTodoList();
// todo一覧をリクエストスコープに設定する
request.setAttribute("todoList", todoList);
// todo一覧画面に遷移する
RequestDispatcher rd = request.getRequestDispatcher("WEB-INF/jsp/list.jsp");
rd.forward(request, response);
}
InsertServlet
ListServletとほとんど同じです。継承をHttpServletからBaseServletに変更し、execメソッド内に処理を記述します。
DeleteServlet
DeleteServletも同じです。継承をHttpServletからBaseServletに変更し、execメソッド内に処理を記述します。
updateServletは特別
UpdateServletだけ少し違います。UpdateServletではリクエストがGETかPOSTで処理を分けているので、execに一つの処理として記述することができません。いろいろ方法はありますが、今回は以下の様に対応します。
- UpdateServletでもBaseServletを継承します
- execメソッド内でGETリクエストなのかPOSTリクエストなのか判定する
- getGetRequestメソッドとgetPostRequestメソッドを作成し、リクエストの種類によって呼ぶ方を変える
結果的にUpdateServletは以下のようになります。またGETメソッドでリクエストを受けた時にTodoのidがint型に変換できなかった場合NumberFormatExceptionが発生してしまいますので、その時は一覧画面に遷移します。
package servlet;
import java.io.IOException;
import java.sql.Date;
import java.sql.SQLException;
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 constant.Parameters;
import model.dao.UpdateDAO;
import model.dao.dto.TodoDTO;
/**
* Servlet implementation class UpdateServlet
*/
@WebServlet("/update-servlet")
public class UpdateServlet extends BaseServlet {
/**
* @see HttpServlet#HttpServlet()
*/
public UpdateServlet() {
super();
}
@Override
protected void exec(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException, SQLException, ClassNotFoundException {
// メソッドの取得
String method = request.getMethod();
// リクエストメソッドの種類によって呼ぶ関数を変える
if (method.equals("GET")) {
getGetRequest(request, response);
} else if (method.equals("POST")) {
getPostRequest(request, response);
}
}
/**
* GETリクエストを受け取った時の処理
*/
protected void getGetRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException, SQLException,
ClassNotFoundException {
// リクエストパラメータからtodoIdを取得する
int todoId = 0;
try {
todoId = Integer.parseInt(request.getParameter(Parameters.TODO_ID));
} catch (NumberFormatException e) {
request.getRequestDispatcher("list-servlet").forward(request, response);
}
UpdateDAO dao = new UpdateDAO();
TodoDTO todo = new TodoDTO();
// todoの取得
todo = dao.getTodo(todoId);
request.setAttribute("todo", todo);
request.getRequestDispatcher("WEB-INF/jsp/update.jsp").forward(request, response);
}
/**
* POSTリクエストを受け取った時の処理
*/
protected void getPostRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException, SQLException, ClassNotFoundException {
// リクエストパラメータから値を取得する
request.setCharacterEncoding("UTF-8");
int id = Integer.parseInt(request.getParameter(Parameters.TODO_ID));
String todo = request.getParameter(Parameters.TODO);
Date timeLimit = Date.valueOf(request.getParameter(Parameters.TIME_LIMIT));
// DAOを生成し、Todoを更新する
UpdateDAO dao = new UpdateDAO();
// 受け取ったパラメータを元にデータベースを更新する
dao.updateTodo(id, todo, timeLimit);
response.sendRedirect("list-servlet");
}
}
まとめ・次回予告
次は流石にデザインをなんとかします。後ログアウト機能もつけときましょう。
GitHubにソースがあるので、参考にしてください!ご質問等あればこちらのTwitterアカウントまでお願いします。
プログラミング学習はUdemyがおすすめ
私はプログラミングの学習はUdemyで行うのが一番おすすめです。
Udemyでは動画講座でプログラミングなどのスキルを身につけることができます。
現役エンジニアがUdemyをオススメする理由は
・動画で好きなときに学べる
・一流の講師に学ぶことができる
・講師の方に質問ができる
・返金保証もある
・セールを頻繁に開催している
といったたくさんの理由があります。
現在Udemyではセールを開催しています!
通常時1万円から2万円前後の価格で講座が販売されていますが、セール時には1500円前後(ランチ代くらい)で一つの講座を購入することができます。
UdemyにはサーブレットでWebアプリ開発が学べる講座もあるので、JavaでWebアプリ開発する方法を学んでみたい!という方は今がチャンスです!