質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
JSP

JSP(Java Server Pages)とは、ウェブアプリケーションの表示レイヤーに使われるサーバーサイドの技術のことです。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

servlet

Servletとは、Webページの動的な生成やデータ処理などをサーバ上で実行するために、Javaで作成されたプログラムです。 ショッピングサイトやオンラインバンキングといった、動的なウェブサイトの構築に用いられています。

Tomcat

TomcatはApache Software Foundation (ASF)で開発されたオープンソースのWebコンテナです。

Q&A

解決済

1回答

424閲覧

javaのwebアプリケーションについて

YUUdesu

総合スコア5

JSP

JSP(Java Server Pages)とは、ウェブアプリケーションの表示レイヤーに使われるサーバーサイドの技術のことです。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

servlet

Servletとは、Webページの動的な生成やデータ処理などをサーバ上で実行するために、Javaで作成されたプログラムです。 ショッピングサイトやオンラインバンキングといった、動的なウェブサイトの構築に用いられています。

Tomcat

TomcatはApache Software Foundation (ASF)で開発されたオープンソースのWebコンテナです。

0グッド

0クリップ

投稿2024/11/14 13:19

編集2024/11/15 04:40

実現したいこと

ボタンをクリックするたびに一定の確率で成功と失敗を判定し、成功した連続回数を画面に表示したい。

前提

javaを独学で学んでおり、「Servlet」「jsp」「bean」について学習したため上記のようなものを試しに作ってみようと思ったのですがうまくいきません。

具体的にはエラーなどは起きないのですが、何度ボタンを押しても「2」とカウントされ、結果の数値も「1」になってしまいます。

該当のソースコード

index.html

1<!DOCTYPE html> 2<html> 3<head> 4<meta charset="UTF-8"> 5<title>連続チャレンジ</title> 6</head> 7<body> 8 9<h1>連続チャレンジ!</h1> 10<p>何回できるかな?</p> 11 12<form action="/javaweb/Servlet" method="get"> 13 <input type="submit" value="開始!"> 14</form> 15 16 17 18</body> 19</html>

Servlet.java

1package controller; 2 3import java.io.IOException; 4 5import javax.servlet.RequestDispatcher; 6import javax.servlet.ServletException; 7import javax.servlet.annotation.WebServlet; 8import javax.servlet.http.HttpServlet; 9import javax.servlet.http.HttpServletRequest; 10import javax.servlet.http.HttpServletResponse; 11import javax.servlet.http.HttpSession; 12import bean.CountBean; 13 14 15@WebServlet("/Servlet") 16public class Servlet extends HttpServlet { 17 private static final long serialVersionUID = 1L; 18 19 20 21 public Servlet() { 22 super(); 23 24 } 25 26 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 27 request.setCharacterEncoding("utf-8"); 28 response.setContentType("text/html;charset=utf-8"); 29 30 RandomNum random = new RandomNum();//ランダムな数を取得するためのインスタンス 31 CountBean count = new CountBean();//カウント数を格納するためのインスタンス 32 CountBean result = new CountBean();//最終的な結果を格納する為のインスタンス 33 34 HttpSession session = request.getSession(true);//セッションの取得 35 36 37 38 39 if(random.random() <7) { //乱数で7未満が出た場合 40 41 count.setCount(count.getCount());//countに格納された数+1をcountに格納 42 session.setAttribute("count", count);//sessionスコープに格納 43 44 RequestDispatcher rd = request.getRequestDispatcher("view/next.jsp"); 45 rd.forward(request, response); 46 47 }else{ //乱数で7より上の数が出た場合 48 49 result.setCount(count.ResultCount()); //最終的な成功回数をresultインスタンスへ格納 50 51 request.setAttribute("result", result);//リクエストスコープに格納 52 53 session.invalidate();//セッションの破棄 54 55 RequestDispatcher rd = request.getRequestDispatcher("view/end.jsp"); 56 rd.forward(request, response); 57 } 58 59 } 60 61 62 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 63 64 doGet(request, response); 65 } 66 67}

next.jsp

1<%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 4<jsp:useBean id = "count" scope = "session" class = "bean.CountBean"/> 5 6<!DOCTYPE html> 7<html> 8<head> 9<meta charset="UTF-8"> 10<title>連続チャレンジ</title> 11</head> 12 13<body> 14 15<jsp:getProperty name="count" property="count" />回目! 16続くよ!! 17 18<form action="/javaweb/Servlet" method="post"> 19 <input type="submit" value="もう一発?"> 20</form> 21 22</body> 23</html> 24

end.jsp

1<%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 4<jsp:useBean id="result" scope="request" class="bean.CountBean"/> 5 6<!DOCTYPE html> 7<html> 8<head> 9<meta charset="UTF-8"> 10<title>連続チャレンジ</title> 11</head> 12<body> 13終わり! 14 15<jsp:getProperty name="result" property="count" />回成功した 16 17</body> 18</html>

Random.java

1package controller; 2 3import java.util.Random; 4 5public class RandomNum { 6 7 public int random() { 8 Random rand = new Random(); 9 int num = rand.nextInt(10); 10 return num; 11} 12}

試したこと

色々いじってみると多少数値や挙動が変わりましたが上手くいかなかった為質問させて頂きました。
独学という事もあり見にくい部分などあるかもしれませんがご教授いただけるとありがたいです。
よろしくお願い致します。

補足情報(FW/ツールのバージョンなど)

eclipseを使いTomcatを起動して動作は確認しました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

doGet を実行する度に、 count も result も、ついでに random も作り直しているように見えますけども。
CountBean の初期値は 0 ですから、いくらやっても 2 以上にはならないのではないでしょうか。
セッションに該当オブジェクトがあったらそれを取り出して使うようにする必要があるでしょう。

セッションを利用してみよう
https://kanda-it-school-kensyu.com/java-jsp-servlet-contents/jjs_ch12/jjs_1202/

random の方は、内部で使っている Random クラスは疑似乱数で、適切なシードで初期化しないと毎回同じ値が出るかもしれません。(確認していません。)
間違ってました。デフォルトコンストラクタで Random インスタンスを生成するのが一番らしぃです。
http://javasampleokiba.blog.fc2.com/blog-entry-44.html

蛇足ながら…
CountBean の

java

1 public int getCount() { 2 count++; 3 return count; 4 } 5 public int ResultCount() { 6 return count; 7 }

の各々のメソッド名は、
getCount → incrementCount
ResultCount → getCount
が適切ではないでしょうか。


いつものことですがテキトウにやってみました。

doGet でまずセッションからカウンタを取り出しています。カウンタがまだ無いなら作ってセッションに入れます。
後は乱数に応じてカウンタを増やしたりフォワード先を決めたりセッションを破棄したり…。
フォワード先で参照できるようにリクエストにカウンタを入れてフォワード、で完。
next.jsp/end.jsp の useBean ではカウンタの生成は必要無いので class 属性で無く type 属性を使っています(余り意味は無い)。
(RandomNum は Random のラッパーでしか無いので直で Random を使っています。)

abc/Servlet.java

java

1package abc; 2 3import java.io.IOException; 4import java.util.Random; 5 6import javax.servlet.ServletException; 7import javax.servlet.annotation.WebServlet; 8import javax.servlet.http.*; 9 10@WebServlet("/Servlet") 11public class Servlet extends HttpServlet { 12 private static final String COUNTER = "counter"; 13 14 private Random random = new Random(); 15 16 @Override 17 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 18 HttpSession session = request.getSession(true); 19 20 Counter counter = (Counter)session.getAttribute(COUNTER); 21 if(counter == null) { 22 counter = new Counter(); 23 session.setAttribute(COUNTER, counter); 24 } 25 26 String next; 27 if(random.nextInt(10) < 7) { 28 counter.increment(); 29 next = "next.jsp"; 30 } else { 31 session.invalidate(); 32 next = "end.jsp"; 33 } 34 35 request.setAttribute(COUNTER, counter); 36 request.getRequestDispatcher(next).forward(request, response); 37 } 38 39 @Override 40 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 41 doGet(request, response); 42 } 43}

abc/Counter.java

java

1package abc; 2 3public class Counter { 4 private int value = 0; 5 void increment() { value ++; } 6 public int getValue() { return value; } 7}

index.jsp

html

1<%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3<!DOCTYPE html> 4<html> 5<head> 6<meta charset="UTF-8"> 7<title>Insert title here</title> 8</head> 9<body> 10<form action="Servlet" method="get"> 11 <input type="submit" value="開始!"> 12</form> 13</body> 14</html>

next.jsp

html

1<%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3<jsp:useBean scope="request" id="counter" type="abc.Counter"/> 4<!DOCTYPE html> 5<html> 6<head> 7<meta charset="UTF-8"> 8<title>Insert title here</title> 9</head> 10<body> 11<jsp:getProperty name="counter" property="value" />回目! 12続くよ!! 13<form action="Servlet" method="post"> 14 <input type="submit" value="もう一発?"> 15</form> 16</body> 17</html>

end.jsp

html

1<%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3<jsp:useBean scope="request" id="counter" type="abc.Counter"/> 4<!DOCTYPE html> 5<html> 6<head> 7<meta charset="UTF-8"> 8<title>Insert title here</title> 9</head> 10<body> 11終わり! 12<jsp:getProperty name="counter" property="value" />回成功した 13</body> 14</html>

投稿2024/11/15 03:14

編集2024/11/15 16:21
jimbe

総合スコア13168

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YUUdesu

2024/11/15 13:08

ご指摘いただいた点を踏まえ ```Servlet.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 javax.servlet.http.HttpSession; import bean.CountBean; @WebServlet("/Servlet") public class Servlet extends HttpServlet { private static final long serialVersionUID = 1L; RandomNum random = new RandomNum();//ランダムな数を取得するためのインスタンス CountBean count = new CountBean();//カウント数を格納するためのインスタンス CountBean result = new CountBean();//最終的な結果を格納する為のインスタンス public Servlet() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); HttpSession session = request.getSession(true);//セッションの取得 if(random.random() <7) { //乱数で7未満が出た場合 count.setCount(count.incrementCount());//countに格納された数+1をcountに格納 session.setAttribute("count", count);//sessionスコープに格納 RequestDispatcher rd = request.getRequestDispatcher("view/next.jsp"); rd.forward(request, response); }else{ //乱数で7より上の数が出た場合 result.setCount(count.getCount()); //最終的な成功回数をresultインスタンスへ格納 request.setAttribute("result", result);//リクエストスコープに格納 session.invalidate();//セッションの破棄 RequestDispatcher rd = request.getRequestDispatcher("view/end.jsp"); rd.forward(request, response); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } } ``` とインスタンスをdoGetメソッドの外側に記述しました。 しかし、それだけでは上手くいかなく、成功した際2づつ値が増えていき結果では最終的な数は成功数プラス1が結果として出力されました。 そこでさらにCountBean.javaのメソッド名も修正したところ数値は正しく表示されました。 しかし更なる問題として終了後再び遊べるように結果画面にindex.htmlのリンクを張ったところ次に遊ぶ際、数値が引き継がれてしまいます。 Servlet.java内でゲームが終了する際、結果をセッションスコープに入っていたオブジェクトをリクエストスコープに移し、セッションを破棄するという流れでやってみたのですが上手くいっていないようです。 そこで再び2点質問なのですが、 ①上記のセッション破棄が上手くいかない理由 ②メソッド名を変えたことで上手くいった理由 2点を知りたいです。 初学者という事で基礎的なことかもしれないのですが教えていただけるとありがたいです。 よろしくお願いします。
jimbe

2024/11/15 13:45

何か変更したことによってうまく行くようになられたようですが、コード的にはあまり宜しくない状態に見えます。 >インスタンスをdoGetメソッドの外側に記述しました。 というのは、ちょっと言い回しが妙になっていますが、要はCountBean と RandomNum の変数をサーブレットのフィールドにしたということですね。 ("インスタンス" はいわゆる "オブジェクト" のことで "変数" とは違います。"メソッドの外側" という表現はまず聞きません。) で、後から編集で追加したので読まれていないかもしれませんが、対応の大前提は「セッションに情報を保存したら次のリクエストでは保存した情報を取り出して使う」ことです。 現状ではセッションに情報を保存しているにも関わらず次のリクエストではそれを取り出さずに(また)新たに作成してるので、カウントが進まないのです。 セッションから取り出す等をせず変数をフィールドにした(り他も弄ったりし)ら動いた…ぽいのは、サーブレット自体のインスタンスが複数のリクエストで使い回された為に前の情報が残っていたからでしょう。 「んじゃセッションなんか使わなくても動いたからこの方法でいいんじゃ?」となるかもしれませんが、サーブレットの使い回しはサーバとして無駄にオブジェクトの生成/破棄を繰り替えさないためであって、情報の保存のためではありません。 検索して見つけたセッションを使った例のある記事へのリンクも付け足しましたので、回答のリンク先を読まれてみては如何でしょうか。
jimbe

2024/11/16 01:51 編集

前後しますが、メソッド名の変更で動きが変わったのは jsp:getProperty の仕様を理解されていなかったからではと思います。 getProperty の name に指定するのは Bean です。 Bean というは property へのアクセス時の命名規則が決まっていて、 "get"+プロパティ名 で値の取得、 "set"+プロパティ名 で値の設定、です。(詳しくはドキュメントを探してください。) 件の Bean である CountBean のプロパティ count のアクセスメソッド getCount が単に count の値を返すのではなく count に +1 した上で返していましたので、サーブレットで加算した上で jsp でも加算していたのではないでしょうか。
YUUdesu

2024/11/17 02:51 編集

おかげさまでようやく上手くいきました。 勉強したばかりの部分で理解できていないところがよく分かりました。 jsp:getPropertyについても書いてくださったコードを見てようやく分かりました。 とても勉強になりました。 本当にありがとうございました。
jimbe

2024/11/17 05:02

Web はいろいろなモノが絡み合うのであれこれ知識が必要でなかなか難しいですね。 お疲れさまでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問