【java】カバラ数表示プログラム

#1.javaのwebアプリを再勉強した経緯

`(1)paizaの問題を解きながら、PHP,python,rubyの文法を習得。`
`(2)色々なサイトを見ると、まだまだjavaの求人は多い`
`(3)他の言語のwebアプリ関連のフレームワークを見るとmvcモデルになっている`

昔入れたことのある__eclipseが激重__だったり、__MVCについて苦手意識__があったが改めてjava再入門する決意を固めた。


#2.MVCモデルとは

アプリケーションの機能を下記の３つの要素で実装していくこと。

__`Model(モデル)`__

機能に必要なデータや、処理(計算や加工)などを定義する。

__`View(ビュー)`__

ユーザー側に表示される画面のデザインを定義する。

__`Controller(サーブレット)`__

フォームなどから渡された入力データを受け取って、ロジック(Model)に
渡して加工したデータを出力画面に渡す。

__`【最大の利点は、データや処理の定義、画面間の制御、画面のデザインが、異なるファイルで定義されている】ので、概念になれると分業ができる所でしょう。`__


#3.カバラ数とは
生年月日の数字を並べて合計をして出てきた数値で性格や適職を占うもので、
数字は13種類あるそう。
足した合計が一桁になるまで合計をすることがポイント。
ただし生年月日の合計値が11,22,33,44のゾロ目になる時は、計算をストップする。

例1)2000年1月1日生まれ
=2+0+0+0+1+1=4

例2)1980年3月1日生まれ
=1+9+8+0+3+1=22

例3)1990年11月11日生まれ
=1+9+9+0+1+1+1+1=23
->2+3=5

#4.アプリケーション実行イメージ
## 4.1　存在する年月日を入力したとき
### 4.1.1 入力画面

![kabara_in.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689780/d37bcd22-91b5-bcb5-6b44-910bb4d36a8c.jpeg)

### 4.1.2 計算結果画面
![kabara_print.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689780/7e8c4c25-6c80-53d0-bc7d-27b15975428a.jpeg)

## 4.2 存在しない年月日を入力したとき
### 4.2.1 入力画面

![kabara_in2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689780/7bdbf27a-35eb-a3d8-2388-94f040ef2972.jpeg)

### 4.2.2 エラー画面

![kabara_err.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689780/431a0bae-c338-6e28-d141-94bffca82c53.jpeg)

## 4.3 ファイル構成

![kabara_project.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689780/8fbb7521-6bf4-c314-f62c-cadb43c35134.jpeg)


#5.ソース
##5.1モデル

###5.1.1 kabaraBean.java

`『入力年、入力月、入力日、カバラ数をまとめたデータ』`

```java:kabaraBean.java
package model;
public class kabaraBean {
  int yy;
  int mm;
  int dd;
  int kabara_num;
  public int getYy() {
    return yy;
  }
  public void setYy(int yy) {
    this.yy = yy;
  }
  public int getMm() {
    return mm;
  }
  public void setMm(int mm) {
    this.mm = mm;
  }
  public int getDd() {
    return dd;
  }
  public void setDd(int dd) {
    this.dd = dd;
  }
  public int getKabara_num() {
    return kabara_num;
  }
  public void setKabara_num(int kabara_num) {
    this.kabara_num = kabara_num;
  }
}
```


###5.1.2 KabaraCalc.java

`『カバラ数の計算ロジック』`

```java:KabaraCalc.java
package model;

public class KabaraCalc{
  public void execute(kabaraBean kabara_in){
    int yy0=kabara_in.getYy();
    int mm0=kabara_in.getMm();
    int dd0=kabara_in.getDd();
    int kabara_retnum=calc_kabara1(yy0,mm0,dd0);

    kabara_in.setKabara_num(kabara_retnum);
  }

  private int calc_kabaranum2(int num1) {
    int ret1=num1/10 +num1%10;
    int retint=0;
    if(ret1==11){
      retint=ret1;
    //10未満
    }else if(ret1<10){
      retint=ret1;
      //11より大きいまたは10
    }else{
      ret1=ret1/10+ret1%10;
      if(ret1==11){
        retint=ret1;
      }else if(ret1<10){
        retint=ret1;
      }else{
        ret1=ret1/10+ret1%10;
        retint=ret1;
      }
    }
    return retint;
  }

  private int calc_kabara1(int y0, int m0, int d0) {

    String tmpstr=""+y0+""+m0+""+d0;
    int len1=tmpstr.length();
    int total=0;
    int kabaranum=0;

    for(int i=0;i<len1;i++){
      total=total+Integer.parseInt(tmpstr.substring(i,i+1));
    }
    if(total<10){
      kabaranum=total;
    }else if(total==11 || total==22 || total == 33 || total==44){
      kabaranum=total;
    }else{
      kabaranum=calc_kabaranum2(total);
    }
    return kabaranum;
  }
}

```

###5.1.3 kabaraError.java
`『入力画面から入力されたデータを判定するロジック』`

```java:kabaraError.java
package model;

import java.text.DateFormat;
import java.text.SimpleDateFormat;

public class kabaraError {
  String msg;
  public String getMsg() {
    return msg;
  }
  public void setMsg(String msg) {
    this.msg = msg;
  }
  public boolean check(String str_yy,String str_mm,String str_dd){
    int ret;
    ret=0;
    String msg1="日付形式で入れてください"+str_yy+" "+str_mm+" "+str_dd;
    String msg2="";
    //str_yyが数値型か
    for(int i=0;i<str_yy.length();i++) {
      if(!Character.isDigit(str_yy.charAt(i))) {
        System.out.println(str_yy.charAt(i));
        ret=ret+1;
        setMsg(msg1);
        return false;
      }
    }
    //str_mmが数値型か
    for(int i=0;i<str_mm.length();i++) {
      if(!Character.isDigit(str_mm.charAt(i))) {
        System.out.println(str_mm.charAt(i));
        ret=ret+1;
        setMsg(msg1);
        return false;
      }
    }
    //str_ddが数値型か
    for(int i=0;i<str_dd.length();i++) {
      if(!Character.isDigit(str_dd.charAt(i))) {
        ret=ret+1;
        setMsg(msg1);
        return false;
      }
    }
    //数値型の場合
    if(ret == 0) {
      if(str_mm.length()==1) {
        str_mm="0"+str_mm;
      }
      if(str_dd.length()==1) {
        str_dd="0"+str_dd;
      }

      //日付の妥当性チェック
      String strdate=str_yy+str_mm+str_dd;

      try {
        DateFormat df = new SimpleDateFormat("yyyyMMdd");
        // 日付解析を厳密に行う設定にする
        df.setLenient(false);
        // 日付妥当性OK
        df.parse(strdate);

      } catch (Exception e) {
        // 日付妥当性NG時の処理を記述
        setMsg(msg1);
        return false;
      }
    }
    setMsg(msg2);
    return true;
  }

}

```
##5.2 Controller

`『入力画面から受け取ったデータに対し、データの種類を判定ロジックに渡し、判定結果によって、どの画面にどのデータを渡すか制御』`

```java:kabaraServlet.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.KabaraCalc;
import model.kabaraBean;
import model.kabaraError;

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


   /**
   * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
   */
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    //フォワード先パスは「WebContentから見た相対パス」
    RequestDispatcher dispatchar=request.getRequestDispatcher("kabara_input.jsp");
    dispatchar.forward(request, response);
  }

  /**
   * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
   */
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    //年
    String yy=request.getParameter("yy_birth");
    //月
    String mm=request.getParameter("mm_birth");
    //日
    String dd=request.getParameter("dd_birth");

    kabaraError kabaraerr=new kabaraError();
    //エラーでないとき
    if(kabaraerr.check(yy, mm, dd)==true) {
      //入力値をプロパティに設定
      kabaraBean kabara1=new kabaraBean();
      kabara1.setDd(Integer.parseInt(dd));
      kabara1.setMm(Integer.parseInt(mm));
      kabara1.setYy(Integer.parseInt(yy));

      //カバラ数計算ロジックを呼び、結果を設定
      KabaraCalc kcalc1=new KabaraCalc();
      kcalc1.execute(kabara1);
      //リクエストスコープに保存
      request.setAttribute("kabara", kabara1);

      //フォワード先パスは「WebContentから見た相対パス」
      RequestDispatcher dispatchar2=request.getRequestDispatcher("kabara_result.jsp");
      dispatchar2.forward(request, response);
    //エラーのとき
    }else {
      //リクエストスコープに保存
      request.setAttribute("kabaraerr2", kabaraerr);
      //フォワード先パスは「WebContentから見た相対パス」
      RequestDispatcher dispatchar2=request.getRequestDispatcher("kabara_error.jsp");
      dispatchar2.forward(request, response);
    }

  }
}
```
##5.3 View

###5.3.1 kabara_input.jsp(入力画面)

```jsp:kabara_input.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="/kabara/kabaraServlet" method="post">
年:<input type="text" name="yy_birth" maxlength=4 required><br>
月:<input type="text" name="mm_birth" maxlength=2 required><br>
日:<input type="text" name="dd_birth" maxlength=2 required><br>
<input type="submit" value="判定">
</form>
</body>
</html>
```
###5.3.2 カバラ数結果表示画面
`(1)<% %>内にはjavaプログラムを書くことができる。`
`(2)<%= %>内にはjavaプログラムから取得した結果を出力できる。`

```jsp:kabara_result.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%-- 下記でモデルを指定するとモデル内のデータを取得できるようになる --%>
<%@ page import ="model.kabaraBean" %>
<% kabaraBean kabara_r=(kabaraBean) request.getAttribute("kabara"); %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>カバラ数表示</title>
</head>
<body>
<h1>カバラ数表示</h1>
生年月日:<br>

<%= kabara_r.getYy() %>
<%= kabara_r.getMm() %>
<%= kabara_r.getDd() %><br>

結果<br>
<%= kabara_r.getKabara_num() %><br>
<a href="/kabara/kabara_input.jsp">戻る</a>
</body>
</html>
```
### 5.3.3 入力エラー画面
```jsp:kabara_error.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import ="model.kabaraError" %>
<% kabaraError kabara_er=(kabaraError) request.getAttribute("kabaraerr2"); %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>入力エラー</title>
</head>
<body>
<h1>入力エラー</h1><br>

<%= kabara_er.getMsg() %><br>

<a href="/kabara/kabara_input.jsp">戻る</a>
</body>
</html>
```

#6.参考書籍

__スッキリわかるサーブレット＆JSP入門　著者:国本大悟__