Seasarを使ってweb簡易電卓　加算乗算

#Seasarフレームワークを使って足し算掛け算だけのweb簡易電卓を作成

Seasarを使ってweb簡易電卓　掛け算のみ
（https://qiita.com/circular/items/eab303263b20591cf86d )
の少しだけ発展形になります。

##実現したいこと（イメージ図）

![スクリーンショット 2017-10-13 0.06.27.png](https://qiita-image-store.s3.amazonaws.com/0/180727/db6623f2-697a-0300-3324-4b8af5088f7c.png)

3つの数を入力して「計算方法」のボタンを押すと、結果表示。

##コード
ファイルは以下の6つです。
**・indexaddmulti.jsp（ページ外観）**
**・AddMultiAction.java（ここからスタート。メインとなるクラス）**
**・AddMultiForm.java**
**・Validate2.java（チェック）**
**・Constant2.java（メッセージ）**
**・Calculation.java**

Constant2とValidate2とFormは、
https://qiita.com/circular/items/eab303263b20591cf86d
のものと完全に同一（クラス名だけ違う）。

★入力された値を取得するためには、JSPファイルのname属性とFormの変数名が同一である必要があります。

indexaddmulti.jsp

```jsp
<%@page pageEncoding="UTF-8"%>
<html>
<head>
<title>Tutorial: Add and Multi</title>
</head>
<body>

<h1>Tutorial: Add or Multi</h1>
<bean:write name="message" />
<form action="/tutorial/addMulti/" method="get">
	<input type="text" name="arg1"/>+ or ×
	<input type="text" name="arg2"/>+ or ×
	<input type="text" name="arg3">=<bean:write name="result" />
	<br/>

<!-- type="submit" （送信ボタンを作成）  name="" （部品の名前を指定） -->
<!-- nameと同名のメソッドが呼び出される仕組み -->
	<input type="submit" name="submitPlus"  value="足し算する"/>
	<input type="submit" name="submitMulti" value="掛け算する"/>

</form>

</body>
</html>
```
AddMultiAction.java
Formのインスタンス化は、普通のnewで書いてしまうと、
JSPのname属性とFormの変数名が連動されません。

```java
package tutorial.action;

import javax.annotation.Resource;

import org.seasar.struts.annotation.ActionForm;
import org.seasar.struts.annotation.Execute;

import tutorial.common.constant.Constant2;
import tutorial.form.AddMultiForm;
import tutorial.logic.Calculation;
import tutorial.util.Validate2;

public class AddMultiAction {

    @ActionForm
    @Resource
   //インスタンス化 Seasarフレームワークの作法により、同名の変数名で書く必要がある。例えばamfなどではダメ。
    protected AddMultiForm addMultiForm;

    //バリデータを呼び出すか否か
    @Execute(validator = false)

    //URL叩くとindexからスタートする
    public String index() {
        addMultiForm.setMessage("3つの数字を入力して下さい");
        addMultiForm.setResult("答え");
        return "indexaddmulti.jsp";
    }

    @Execute(validator = false)
    //JSPのnameと同名のメソッドを定義する
    public String submitPlus() {
        Validate2 validate = new Validate2();
        String arg1 = addMultiForm.getArg1();
        String arg2 = addMultiForm.getArg2();
        String arg3 = addMultiForm.getArg3();

        //Validateクラスで検証する
        String message = validate.check(arg1, arg2, arg3);

        addMultiForm.setMessage(message);
        addMultiForm.setResult("");

        if (message.equals(Constant2.MESSAGE_SUCCESS)){
            //計算呼出
            Calculation calc = new Calculation();
            String result = calc.calculatePlus(arg1,arg2,arg3);
            addMultiForm.setResult(result);

            //桁数チェック
            if (addMultiForm.getResult().length() <= 10) {
                addMultiForm.setMessage("答えの桁数問題ありません");
            } else {
                addMultiForm.setMessage("答えの桁が11以上なので無効です");
            }
        }
        return "indexaddmulti.jsp";
    }

    @Execute(validator = false)
    //JSPのnameと同名のメソッドを定義する
    public String submitMulti() {
        Validate2 validate = new Validate2();
        String arg1 = addMultiForm.getArg1();
        String arg2 = addMultiForm.getArg2();
        String arg3 = addMultiForm.getArg3();

        //Validateクラスで検証する
        String message = validate.check(arg1, arg2, arg3);

        addMultiForm.setMessage(message);
        addMultiForm.setResult("");

        if (message.equals(Constant2.MESSAGE_SUCCESS)){
            //計算呼出
            Calculation calc = new Calculation();
            String result = calc.calculateMulti(arg1,arg2,arg3);
            addMultiForm.setResult(result);

            //桁数チェック
            if (addMultiForm.getResult().length() <= 10) {
                addMultiForm.setMessage("答えの桁数問題ありません");
            } else {
                addMultiForm.setMessage("答えの桁が11以上なので無効です");
            }
        }
        return "indexaddmulti.jsp";
    }
}
```

AddMultiForm.java

```java

package tutorial.form;

public class AddMultiForm {

    private String arg1;

    private String arg2;

    private String arg3;


    private String result;

    private String message;

    public String getArg1() {
        return arg1;
    }

    public void setArg1(String arg1) {
        this.arg1 = arg1;
    }

    public String getArg2() {
        return arg2;
    }

    public void setArg2(String arg2) {
        this.arg2 = arg2;
    }

    public String getArg3() {
        return arg3;
    }

    public void setArg3(String arg3) {
        this.arg3 = arg3;
    }

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}
```
Validate2.java（チェック）

```java

package tutorial.util;

import org.seasar.framework.util.StringUtil;
import tutorial.common.constant.Constant;

public class Validate2 {

    //3つの引数
    public String check(String args1, String args2 ,String args3){

        //桁数をここで一元管理
        int maxLength = 5;

        //空文字またはnullをはじく。null判定の意味がなくなるので、ここより上にnullになる可能性のある処理を書いてはならない。
        if (StringUtil.isEmpty(args1) || StringUtil.isEmpty(args2) || StringUtil.isEmpty(args3)){
            return Constant.MESSAGE_NULL;

        //数字以外をはじく。「0から9までの数字の連続」に完全一致しないのであれば、という条件式。
        } else if ( !args1.matches(Constant.MATCH_0_9) || !args2.matches(Constant.MATCH_0_9) || !args3.matches(Constant.MATCH_0_9)) {
            return Constant.MESSAGE_NOT_NUMBER;

        //一定の桁数以上をはじく
        } else if ( args1.length() > maxLength || args2.length() > maxLength || args3.length() > maxLength){
            return String.format(Constant.MESSAGE_DEGITS, maxLength);

        } else {
            return (Constant.MESSAGE_SUCCESS);
        }
    }
}
```

Calculation.java（計算）

```java
package tutorial.logic;

public class Calculation {
    public String calculatePlus( String ar1, String ar2 , String ar3 ){
        long a1 = Long.parseLong(ar1);
        long a2 = Long.parseLong(ar2);
        long a3 = Long.parseLong(ar3);

        long resultNumber;
        resultNumber = a1 + a2 + a3;
        return String.valueOf(resultNumber);
    }

    public String calculateMulti( String ar1, String ar2 , String ar3 ){
        long a1 = Long.parseLong(ar1);
        long a2 = Long.parseLong(ar2);
        long a3 = Long.parseLong(ar3);

        long resultNumber;
        resultNumber = a1 * a2 * a3;
        return String.valueOf(resultNumber);
    }
}
```
Constant2.java（メッセージ）
定数は全て大文字で書く慣習。

```java

package tutorial.common.constant;

public class Constant2 {
    public final static String MESSAGE_NULL = "空文字またはnullです";
    public final static String MESSAGE_NOT_NUMBER = "数字入力してください";
    public final static String MESSAGE_DEGITS = "桁数が %d を超えると計算できません";
    public final static String MATCH_0_9 = "[0-9]+";
    public final static String MESSAGE_SUCCESS = "正常に計算されました";
}
```
Tomcatを起動させて
ブラウザでhttp://IPアドレス:8080/tutorial/addMulti/
あるいは、
http://IPアドレス:8080/tutorial/addMulti/index
と叩くと、MultiActionのindexメソッドからスタートします。

入力動作テスト済みです。

##ラジオボタン、またはプルダウンで加算乗算を選択
さらに改変し、ボタンではなく、ラジオボタンまたはプルダウンで足し算掛け算を選択して計算する場合。

Formに、「private String sub;」　およびそのセッターゲッターを追加。
Actionとjspは以下の通り。

```java

package tutorial.action;

import javax.annotation.Resource;

import org.seasar.struts.annotation.ActionForm;
import org.seasar.struts.annotation.Execute;

import tutorial.common.constant.Constant2;
import tutorial.form.AddMultiForm;
import tutorial.logic.Calculation;
import tutorial.util.Validate2;

public class AddMultiAction {

    @ActionForm
    @Resource
   //インスタンス化 Seasarフレームワークの作法により、同名の変数名で書く必要がある
    protected AddMultiForm addMultiForm;

    //バリデータを呼び出すか否か
    @Execute(validator = false)
    //URL叩くとindexからスタートする
    public String index() {
        addMultiForm.setMessage("3つの数字を入力して下さい");
        addMultiForm.setResult("答え");
        return "indexaddmulti.jsp";
    }

    @Execute(validator = false)

    public String submit() {
        Validate2 validate = new Validate2();
        String arg1 = addMultiForm.getArg1();
        String arg2 = addMultiForm.getArg2();
        String arg3 = addMultiForm.getArg3();
        String operator = addMultiForm.getSub();

        //Validateクラスで検証する
        String message = validate.check(arg1, arg2, arg3);

        addMultiForm.setMessage(message);
        addMultiForm.setResult("");

        if (message.equals(Constant2.MESSAGE_SUCCESS)){
            plusOrMulti(operator);
        }

        return "indexaddmulti.jsp";
    }

    public void plusOrMulti(String operator){
        int intOpe  = Integer.parseInt(operator);
        if (intOpe == 2){
            //計算呼出
            Calculation calc = new Calculation();
            String result = calc.calculateMulti(addMultiForm.getArg1(),addMultiForm.getArg2(),addMultiForm.getArg3());

            //桁数チェック
            if (checkDigit(result)) {
                addMultiForm.setResult(result);
                addMultiForm.setMessage("答えの桁数問題ありません");
            } else {
                addMultiForm.setResult("");
                addMultiForm.setMessage("答えの桁が11以上なので無効です");
            }

        }
        else  if (intOpe == 1){
            //計算呼出
            Calculation calc = new Calculation();
            String result = calc.calculatePlus(addMultiForm.getArg1(),addMultiForm.getArg2(),addMultiForm.getArg3());

            //桁数チェック
            if (checkDigit(result)) {
                addMultiForm.setResult(result);
                addMultiForm.setMessage("答えの桁数問題ありません");
            } else {
                addMultiForm.setResult("");
                addMultiForm.setMessage("答えの桁が11以上なので無効です");
            }
        }else {
            addMultiForm.setResult("");
            addMultiForm.setMessage("何も計算できません");
        }
    }


    private Boolean checkDigit(String result) {
        if (result.length() <= 10) {
            return true;
        } else {
            return false;
        }
    }
}
```
ラジオボタンの場合のjspファイル。

```jsp

<%@page pageEncoding="UTF-8"%>
<html>
<head>
<title>Tutorial: Add and Multi</title>
</head>
<body>

<h1>Tutorial: Add or Multi</h1>
<bean:write name="message" />
<form action="/tutorial/addMulti/" method="get">
    <input type="text" name="arg1"/>+ or ×
    <input type="text" name="arg2"/>+ or ×
    <input type="text" name="arg3">=<bean:write name="result" />
    <br/>

<!-- type="submit" （送信ボタンを作成）  name="" （部品の名前を指定） -->
<!-- nameの部品が押されると、nameと同名のメソッドが呼び出される仕組み -->

<!--  ラジオボタンはひとつしか選択できないはずだが、nameが同一でないと、違うグループ扱いになり複数選択できてしまう -->
    <input type="radio" name="sub"  value="1" checked/>足し算
    <input type="radio" name="sub"  value="2"/>掛け算

    <input type="submit" name="submit" value="計算する"/>
</form>
</body>
</html>
```

プルダウンの場合のjspファイル。

```jsp

<%@page pageEncoding="UTF-8"%>
<html>
<head>
<title>Tutorial: Add and Multi</title>
</head>
<body>

<h1>Tutorial: Add or Multi</h1>
<bean:write name="message" />
<form action="/tutorial/addMulti/" method="get">
    <input type="text" name="arg1"/>
    <input type="text" name="arg2"/>
    <input type="text" name="arg3">=<bean:write name="result" />
    <br/>

<!-- type="submit" （送信ボタンを作成）  name="" （部品の名前を指定） -->
<!-- nameの部品が押されると、nameと同名のメソッドが呼び出される仕組み -->

<p>operatorを選択してください</p>
<select name="sub">
    <option value="1">足し算</option>
    <option value="2">掛け算</option>
</select>

    <input type="submit" name="submit" value="計算する"/>
</form>
</body>
</html>
```