LoginSignup
27
27

More than 3 years have passed since last update.

MVCモデルの簡単な例

Last updated at Posted at 2019-06-02

基本的にスッキリわかる サーブレット&jsp入門 第7章のBMI計算プログラムに準じます。

MVCモデルとは

要素    役割    ファイル
Model アプリケーションの主たる処理やデータの格納などを行う 一般的なクラス
View ユーザーに対して画面の表示を行う       JSPファイル      
Controller ユーザーからの要求を受け取り、処理の実行をモデルに依頼し、その結果の表示をビューに依頼する     サーブレットクラス

javaBeams

インスタンスを保存できる領域の一つ。
以下のルールがある。
1. 直列化可能
2. クラスはpublicでパッケージに所属
3. publicで引数のないコンストラクタを持つ
4. フィールドはカプセル化されている
5. 命名規則に従ったgetter/setterを持つ

サンプルプログラム

コードごとに随時解説を入れます。

Model

アプリケーションの主たる処理やデータの格納などを行う
modelパッケージに保存。

Health.java
package model;

import java.io.Serializable;

public class Health implements Serializable {
  private double height, weight, bmi;
  private String bodyType;

  public double getHeight() {
    return height;
  }

  public void setHeight(Double height) {
    this.height = height;
  }

  public double getWeight() {
    return weight;
  }

  public void setWeight(Double weight) {
    this.weight = weight;
  }

  public void setBmi(Double bmi) {
    this.bmi = bmi;
  }

  public double getBmi() {
    return this.bmi;
  }

  public void setBodyType(String bodyType) {
    this.bodyType = bodyType;
  }

  public String getBodyType() {
    return this.bodyType;
  }
}

このコードがいわゆるJavaBeansである。

HealthCheckLogic.java
package model;

public class HealthCheckLogic {
  public void execute(Health health) {
    // BMIを算出して設定
    double weight = health.getWeight();
    double height = health.getHeight();
    double bmi = weight / (height / 100.0 * height / 100.0);
    health.setBmi(bmi);

    // BMI指数から体格を判定して設定
    String bodyType;
    if (bmi < 18.5) {
      bodyType = "痩せ型";
    } else if (bmi < 25) {
      bodyType = "普通";
    } else {
      bodyType = "肥満";
    }
    health.setBodyType(bodyType);
  }
}

特筆して書くことはなし.

Controller

ユーザーからの要求を受け取り、処理の実行をモデルに依頼し、その結果の表示をビューに依頼する。
servletパッケージに保存。

HealthCheck.java
package servlet;

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 model.Health;
import model.HealthCheckLogic;

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

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

    // フォワード
    RequestDispatcher dispatcher =
        request.getRequestDispatcher
            ("/WEB-INF/jsp/healthCheck.jsp");
    dispatcher.forward(request, response);
  }

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

    // リクエストパラメータを取得
    String weight = request.getParameter("weight"); // 身長
    String height = request.getParameter("height"); // 体重

    // 入力値をプロパティに設定
    Health health = new Health();
    health.setHeight(Double.parseDouble(height));
    health.setWeight(Double.parseDouble(weight));
    // 健康診断を実行し結果を設定
    HealthCheckLogic healthCheckLogic = new HealthCheckLogic();
    healthCheckLogic.execute(health);

    // リクエストスコープに保存
    request.setAttribute("health", health);

    // フォワード
    RequestDispatcher dispatcher =
        request.getRequestDispatcher
            ("/WEB-INF/jsp/healthCheckResult.jsp");
    dispatcher.forward(request, response);
  }
}

URLパターン

@WebServlet("/HealthCheck")に記述。

serialVersionUID

private static final long serialVersionUID = 1L;は一種のおまじないのようなものに感じるが違う。
直列化した時、つまりjava.io.Serializableをインポートしたときに必要。
Serializableクラスのバージョンコントロールとして使用される。

リクエストスコープ

リクエストごとに生成されるスコープ。フォワード先とフォワード元でインスタンスを共有することが可能になる。

request.setAttribute("属性名", インスタンス)

属性名にスコープに保存するインスタンスの管理用の名前を指定。
インスタンスに保存するインスタンスを指定

リクエストスコープからインスタンスを取得する場合は以下のように記載。今回はhealthCheckResult.jspでこの処理を行っている。

取得するインスタンスの型 名前 = (取得するインスタンスの型)request.getAttribute("属性名")

キャストが必要な点に注意

フォワード

フォワードを利用することで、処理を他のサーブレットクラスやJSPファイルに移すことが可能。

RequestDispatcher dispatcher =
request.getRequestDispatcher
    ("フォワード先");
dispatcher.forward(request, response);

フォワード先の指定方法
JSPファイル → /WebContentからのパス
サーブレットクラス → /URLパターン

View

ユーザーに対して画面の表示を行う。
ここでは/WebContent/Web-INF/jspに保存。

healthCheck.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>スッキリ健康診断</title>
</head>
<body>
<h1>スッキリ健康診断</h1>
<form action="/example/HealthCheck" method="post">
身長:<input type="text" name="height">(cm)<br>
体重:<input type="text" name="weight">(kg)<br>
<input type="submit" value="診断">
</form>
</body>
</html>

10行目<form action="/example/HealthCheck" method="post">action属性の指定は以下のようになる。
サーブレットクラスの場合 → /アプリケーション名/URLパターン
JSPファイルの場合 → /アプリケーション名/WebContentからのパス

healthCheckResult.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ page import="model.Health" %>
<%
// リクエストスコープに保存されたHealthを取得
Health health = (Health) request.getAttribute("health");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>スッキリ健康診断</title>
</head>
<body>
<h1>スッキリ健康診断の結果</h1>
<p>
身長:<%= health.getHeight() %><br>
体重:<%= health.getWeight() %><br>
BMI:<%= health.getBmi() %><br>
体格:<%= health.getBodyType() %>
</p>
<a href="/example/HealthCheck">戻る</a>
</body>
</html>

2行目の<%@ page import="model.Health" %>でmodelパッケージのHealth.classを呼び出している。
このコードがjavaBeansの使い方を理解するのに最適かも。

最後に

スッキリわかるサーブレット&JSP入門(国本大悟 著)を参照してください。
また本稿のソースコードの著作権は株式会社フレアリンクに帰属します。
Creative Commons BY-SA 4.0従い利用しています。

27
27
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
27