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

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

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

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

MVC

MVC(Model View Controller)は、オブジェクト指向プログラミングにおけるモデル・ビュー・コントローラーの総称であり、ソフトフェア開発で使われている構築パターンとしても呼ばれます。

Java

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

Spring

Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

セッション

Sessionはクライアントがサーバに送ったすべてのリクエストのことを指します。

Q&A

1回答

1694閲覧

セッション管理について

icecleam

総合スコア46

JSP

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

MVC

MVC(Model View Controller)は、オブジェクト指向プログラミングにおけるモデル・ビュー・コントローラーの総称であり、ソフトフェア開発で使われている構築パターンとしても呼ばれます。

Java

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

Spring

Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

セッション

Sessionはクライアントがサーバに送ったすべてのリクエストのことを指します。

0グッド

1クリップ

投稿2020/09/20 16:21

以下のadd.jsp画面で商品をプルダウンから追加し、登録画面への遷移、リストからの削除などの動作を行なっていきます。
ですが、以下の実装ではセッションの管理ができておらず、
新規セッションで、明細操作(追加)をした時に、起動中の売上明細情報も一覧に表示されてしまい、2つ画面の明細操作(追加)が他の画面へ影響されています。

そこで、以下のソースを1つ目の画面で入力した内容が、2つ目の画面に反映されないようにしたいのですが、どうすれば良いのかわからないので教えていただきたいです。
よろしくお願いします

SalesSystemController.java

java

1package jp.practice.sales; 2 3import javax.servlet.http.HttpServlet; 4import javax.servlet.http.HttpServletRequest; 5 6import org.springframework.stereotype.Controller; 7import org.springframework.ui.Model; 8import org.springframework.validation.BindingResult; 9import org.springframework.web.bind.annotation.RequestMapping; 10import org.springframework.web.bind.annotation.SessionAttributes; 11 12/** 13 * Handles requests for the application home page. 14 */ 15@Controller 16@RequestMapping(value = "/system") 17@SessionAttributes(types = SalesForm.class) 18public class SalesSystemController extends HttpServlet { 19 private static final String ERRMSG = "点数には1以上100以下の整数を入力してください。"; 20 private static final String ADDMSG = "明細に追加しました。"; 21 private static final String FIXMSG = "以下のように売上登録しました。"; 22 private static final String DELETE = "選択された明細行を削除しました。"; 23 private static final String ERRMSG2 = "明細行を選択して下さい。"; 24 25 /** 26 * 起動時および登録完了時に呼ばれる。初期画面を表示する。 27 * @param form フォームオブジェクト 28 * @param model モデルオブジェクト 29 * @return Viewとしてinit.jspを指定 30 */ 31 @RequestMapping(value = "/start") 32 public String init(SalesForm form, Model model) { 33 34 model.addAttribute("nameList", RecordManager.makeNameList()); 35 //model.addAttribute("nameList", RecordManager.makeNameList()); 36 //form.setGoodsName(RecordManager.getFirstPersonName()); 37 return "init"; 38 } 39 40 /** 41 * 初期画面から呼ばれる。選択した商品の明細追加画面を表示する。 42 * @param form フォームオブジェクト 43 * @param model モデルオブジェクト 44 * @return Viewとしてadd.jspを指定 45 */ 46 @RequestMapping(params = "add") 47 public String add(SalesForm form,BindingResult result, Model model,HttpServletRequest request) { 48 Item item = RecordManager.findItem(form.getGoodsName()); 49 RecordManager.setNewItem(new Item(item.getId(), form.getGoodsName(), item.getPrice(), form.getQuantity(), item.getSubtotal())); 50 Item newItem = RecordManager.getNewItem(); 51 int sb = newItem.getPrice() * newItem.getQuantity(); 52 newItem.setSubtotal(sb); 53 model.addAttribute("nameList", RecordManager.makeNameList()); 54 model.addAttribute("allList", RecordManager.getallList()); 55 if (result.hasErrors() || 1 > form.getQuantity() || form.getQuantity() > 100) { 56 model.addAttribute("total", RecordManager.calTotal(RecordManager.getallList())); 57 model.addAttribute("message", ERRMSG); 58 return "add"; 59 60 } else { 61 RecordManager.addToAllList(newItem); 62 model.addAttribute("total", RecordManager.calTotal(RecordManager.getallList())); 63 model.addAttribute("message2", ADDMSG); 64 return "add"; 65 } 66 //model.removeAttribute("SalesForm"); 67 //HttpSession session = request.getSession(true); 68 } 69 70 /** 71 * 細追加画面から呼ばれる。選択した商品を削除し明細追加画面を表示する。 72 * @param form フォームオブジェクト 73 * @param model モデルオブジェクト 74 * @return Viewとしてadd.jspを指定 75 */ 76 @RequestMapping(params = "remove") 77 public String remove(SalesForm form, BindingResult result, Model model, HttpServletRequest request) { 78 String num = request.getParameter("radio"); 79 if (num == null) { 80 model.addAttribute("message5", ERRMSG2); 81 model.addAttribute("total", RecordManager.calTotal(RecordManager.getallList())); 82 model.addAttribute("nameList", RecordManager.makeNameList()); 83 model.addAttribute("allList", RecordManager.getallList()); 84 return "add"; 85 } 86 87 int number = Integer.parseInt(num); 88 RecordManager.removeToAllList(number); 89 model.addAttribute("message4", DELETE); 90 model.addAttribute("total", RecordManager.calTotal(RecordManager.getallList())); 91 model.addAttribute("nameList", RecordManager.makeNameList()); 92 model.addAttribute("allList", RecordManager.getallList()); 93 94 if(RecordManager.calTotal(RecordManager.getallList()) == 0){ 95 return "init"; 96 } 97 98 return "add"; 99 } 100 101 /** 102 * 確認画面で登録を押した時に呼ばれる。データを登録して初期画面表示へ遷移する。 103 * @param form フォームオブジェクト 104 * @param model モデルオブジェクト 105 * @return initメソッドへのリンクを指定 106 */ 107 @RequestMapping(params = "firm") 108 public String firm(SalesForm form, Model model) { 109 long value = System.currentTimeMillis(); 110 Item item = RecordManager.findItem(form.getGoodsName()); 111 RecordManager.setNewItem(new Item(item.getId(), form.getGoodsName(), item.getPrice(), form.getQuantity(), item.getSubtotal())); 112 Item newItem = RecordManager.getNewItem(); 113 int sb = newItem.getPrice() * newItem.getQuantity(); 114 newItem.setSubtotal(sb); 115 model.addAttribute("salesid", value); 116 model.addAttribute("message3", FIXMSG); 117 model.addAttribute("total", RecordManager.calTotal(RecordManager.getallList())); 118 model.addAttribute("nameList", RecordManager.makeNameList()); 119 model.addAttribute("allList", RecordManager.getallList()); 120 return "fix"; 121 } 122}

add.jsp

jsp

1<%@ page session="false" language="java" 2 contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> 3<%@page import="java.time.format.DateTimeFormatter"%> 4<%@ page import="java.time.LocalDate"%> 5<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> 6<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%> 7<%@ page import="java.util.*"%> 8<%@ page import="java.time.*"%> 9<!DOCTYPE html> 10<html> 11<head> 12<link rel="stylesheet" type="text/css" 13 href="/sales/resources/css/common.css" /> 14<title>明細追加画面</title> 15</head> 16<body> 17 <form:form modelAttribute="salesForm" action="/sales/system" var="list"> 18 <div class="header"> 19 <span class="titleName">オンラインショップ</span> 20 <% 21 DateTimeFormatter format = DateTimeFormatter.ofPattern("MM月dd日(E)"); 22 %> 23 <span class="date"><%=format.format(LocalDate.now())%></span> 24 </div> 25 <div class="main"></div> 26 <div>明細追加画面</div> 27 商品: 28 <form:select path="goodsName" items="${nameList}" /> 29 <div> 30 点数: 31 <form:input path="quantity" items="${allList}" /> 32 </div> 33 <div> 34 <input type="submit" name="add" value="明細追加" /> 35 </div> 36 <div class="message"> 37 <font color="#ff0000"> <c:out value="${message}" /></font> <font 38 color="#1e90ff"> <c:out value="${message2}" /> 39 </font> <font color="#1e90ff"> <c:out value="${message4}" /> 40 </font><font color="#1e90ff"> <c:out value="${message5}" /> 41 </font> 42 </div> 43 44 <table border="1"> 45 <tr> 46 <th>削除</th> 47 <th>商品ID</th> 48 <th>商品名</th> 49 <th>単価</th> 50 <th>点数</th> 51 <th>小計</th> 52 </tr> 53 <c:forEach items="${allList}" var="item" varStatus="status"> 54 <tr class="even"> 55 <form:hidden path="quantity" /> 56 <td><input type="radio" name="radio" value="${status.index}" /></td> 57 <td><c:out value="${item.id}" /></td> 58 <td><c:out value="${item.name}" /></td> 59 <td><c:out value="${item.price}" /></td> 60 <td><c:out value="${item.quantity}" /></td> 61 <td><c:out value="${item.subtotal}" /></td> 62 </tr> 63 </c:forEach> 64 </table> 65 <div> 66 合計: 67 <c:out value="${total}" /> 6869 </div> 70 <input type="submit" name="firm" value="確定" /> 71 <input type="submit" name="remove" value="削除" /> 72 </form:form> 73</body> 74</html>

init.jsp

jsp

1<%@ page session="false" language="java" 2 contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> 3<%@page import="java.time.format.DateTimeFormatter"%> 4<%@ page import="java.time.LocalDate"%> 5<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> 6<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%> 7<%@ page import="java.util.*"%> 8<%@ page import="java.time.*"%> 9<!DOCTYPE html> 10<html> 11<head> 12<link rel="stylesheet" type="text/css" 13 href="/sales/resources/css/common.css" /> 14<title>売上システム(初期画面)</title> 15</head> 16<body> 17 <form:form modelAttribute="salesForm" action="/sales/system" var="list"> 18 <div class="header"> 19 <span class="titleName">オンラインショップ</span> 20 <% 21 DateTimeFormatter format = DateTimeFormatter.ofPattern("MM月dd日(E)"); 22 %> 23 <span class="date"><%=format.format(LocalDate.now())%></span> 24 </div> 25 <div class="main"></div> 26 <div>初期画面</div> 27 商品: 28 <form:select path="goodsName" items="${nameList}" /> 29 <div> 30 点数: 31 <form:input path="quantity" items="${allList}" /> 32 </div> 33 <input type="submit" name="add" value="明細追加" /> 34 </form:form> 35</body> 36</html>

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

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

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

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

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

A-pZ

2020/09/21 04:08

複数のブラウザ(ないしは1つのブラウザで複数のタブ)を開いているときに、片方の画面で登録した内容を、もう一方の画面では表示したくない、で相違ないでしょうか。
icecleam

2020/09/21 04:10

はい、その認識で問題ありません。 ご確認いただきありがとうございます。
A-pZ

2020/09/21 04:18

その場合は既存のセッションだけでは実現できず、複数の画面をそれぞれ一意に特定するための仕組みが必要です。理由としては現在のブラウザでは1つのクライアントマシンに対してセッションクッキーを共有しますので、同一のブラウザを複数立ち上げても、複数タブにしてもセッション情報が共有されます。 ※Chromeのシークレットモードは、既存のクッキーを共有せず新規で管理するため、これは含みません。
icecleam

2020/09/21 04:38 編集

そうなのですか。。 調査をしていく中で、removeAttributeなどを使えば良いのではというものを見つけたのですが、そちらでも解決は難しいということでしょうか。 補足 「入力された売上明細情報をセッションごとに持ち、処理終了時にはそれをクリアする。」 実装したいのは上記になります。 すみません、まだまだ初心者なもので語弊があったかもしれません
A-pZ

2020/09/21 04:36

removeAttributeはリクエスト属性やセッション属性から値を削除するもので、セッション情報は端末ごとに1つ割り振られているものです。 実現したい内容をもう少し深堀すると、複数の利用者で情報を共有したくないのか、それとも一人の利用者の中で、複数画面を操作しているときに共有したくない、のどちらでしょうか? 「複数の利用者で情報を共有したくない」ならば既存のセッションを利用できます。後者の場合は仕組みが必要です。
icecleam

2020/09/21 04:41

>「複数の利用者で情報を共有したくない」ならば既存のセッションを利用でき> ます」 実現したいのはおそらくこちらに該当します。 言葉が足りず、分かりにくくなってしまい申し訳ありませんでした。
A-pZ

2020/09/21 04:50

なるほどありがとうございます~。
icecleam

2020/09/21 04:52

いえ、こちらこそわざわざご確認いただいてありがとうございます! それだけでもすごく勉強になります。
guest

回答1

0

セッションごとにデータの登録結果を分けたいのでしたら、@SessionAttriuteを利用すると実現できますが、1つ懸念があります。

RecordManagerはアプリケーション全体で共有せず、かつ、staticメソッドで呼び出さず、SpringのBean登録を行い、そのスコープを sessionにすることです。
推察するにRecordManagerはデータの取得や格納を行うクラスですので、以下のようにします。

java

1@Repository 2@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS) 3public class RecordManager { 4 5}

RecordManagerの実装次第なところもありますが、一番簡単なのは、この方法です。

投稿2020/09/21 05:02

編集2020/09/21 05:18
A-pZ

総合スコア12011

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

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

icecleam

2020/09/21 05:11

ご回答ありがとうございます。 上記の回答を反映したRecordManagerは以下になります。 以下のように反映したのですが、以下のエラーが出てしまいました。 この場合、SalesSystemController.javaの方でも何か修正が必要なのでしょうか。 初歩的な質問で申し訳ありませんが、ご確認いただければと思います。。 エラー内容 ----- - TARGET__CLASS は解決できないか、フィールドではありません - SCOPE__SESSION は解決できないか、フィールドではありません ----- package jp.practice.sales; import java.util.ArrayList; import java.util.List; import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.ScopedProxyMode; import org.springframework.stereotype.Repository; import org.springframework.web.context.WebApplicationContext; /** * 商品データ全体を保持するクラス */ @Repository @Scope(value = WebApplicationContext.SCOPE__SESSION, proxyMode = ScopedProxyMode.TARGET__CLASS) public final class RecordManager { /** 明細データ */ static List<Item> allList = new ArrayList<>(); /** 商品データ */ private static final List<Item> list = new ArrayList<Item>(); static { list.add(new Item("A00101", "油性ボールペン", 60, 0, 0)); list.add(new Item("A00201", "極細ボールペン", 120, 0, 0)); list.add(new Item("A00301", "蛍光ペン6色セット", 420, 0, 0)); list.add(new Item("A00401", "シャープペンシル", 100, 0, 0)); list.add(new Item("A00501", "鉛筆H(1ダース)", 400, 0, 0)); list.add(new Item("B00101", "無線綴ノートA4", 100, 0, 0)); list.add(new Item("B00201", "リングノートA4", 120, 0, 0)); list.add(new Item("B00301", "領収書", 350, 0, 0)); list.add(new Item("C00101", "はさみ(青)", 128, 0, 0)); list.add(new Item("C00201", "ステープラー", 338, 0, 0)); list.add(new Item("C00301", "2穴パンチ", 128, 0, 0)); list.add(new Item("C00401", "ゼムクリップ", 98, 0, 0)); list.add(new Item("C00501", "消しゴム", 58, 0, 0)); } /** * 更新した商品データ * 確認ボタンを押すとlistに書き込む。 */ private static Item newItem; /** * 引数で指定された商品名に一致する商品データを返却 * @param name 検索キーとなる商品名 * @return 検索結果の商品データ */ public static Item findItem(String goodsName) { int index = list.indexOf(new Item("", goodsName, 0,0,0)); return list.get(index); } /** * 商品データを返す。 * @return 商品データ */ public static List<Item> getNameist() { return list; } /** * 明細データを返す。 * @return 明細データ */ public static List<Item> getallList() { return allList; } /** * リストに商品情報を 1 件追加する */ public static void addToAllList(Item newItem) { Item item = new Item(newItem.getId(), newItem.getName(), newItem.getPrice(),newItem.getQuantity(),newItem.getSubtotal()); allList.add(item); } /** * リストに商品情報を 1 件削除する */ public static void removeToAllList(int number) { //Item item = new Item(newItem.getId(), newItem.getName(), newItem.getPrice(),newItem.getQuantity(),newItem.getSubtotal()); int i = 0; for (Item item : allList) { i += 1; if (i == number + 1) { allList.remove(item); return; } } } /** * リストに商品情報を クリアする */ public static void clearToAllList(Item newItem) { allList.clear(); } /** * newItemを商品データlistに書き込む。 */ public static void updateItem() { list.set(list.indexOf(newItem), newItem); } /** * newItemにデータを書き込む * @param ni セットする item */ public static void setNewItem(Item ni) { newItem = ni; } public static Item getNewItem() { return newItem; } /** * 全員の名前のリストを返す。 * @return 名前の配列 */ public static String[] makeNameList() { String[] nameList = new String[list.size()]; for (int i = 0; i < list.size(); i++) { nameList[i] = (list.get(i)).getName(); } return nameList; } /** * 名前で検索し、その商品のデータを返す。 * @param name 商品名 * @return 一商品データ */ public static Item selectItem(String name) { for(Item item:list) { if (item.getName().equals(name)) { return item; } } return null; } public static int calTotal(List<Item> list) { int total = 0; for(Item item: list) { total += item.getSubtotal(); } return total; } }
A-pZ

2020/09/21 05:17

失礼しました。アンダースコア2つではなく、1つです。
icecleam

2020/09/21 05:50 編集

アンダーコアを一つにしたらエラーは消えたのですが、以下のエラーが出て初期画面に遷移できなくなってしまいました。。。 エラー内容 ---- HTTPステータス 500 - Internal Server Error Type Exception Report メッセージ サーブレット [appServlet] のServlet.init()が例外を投げました 説明 The server encountered an unexpected condition that prevented it from fulfilling the request. 例外 javax.servlet.ServletException: サーブレット [appServlet] のServlet.init()が例外を投げました org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493) org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650) org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800) org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806) org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498) org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) java.lang.Thread.run(Thread.java:748) ----
A-pZ

2020/09/21 06:58

サーブレット [appServlet] が例外を投げているようです。SpringBootとは関係ないかと思いますが。
icecleam

2020/09/21 08:47

ですね、、すみません色々試して解決できないのですが この場合の解決策などございますでしょうか。。
A-pZ

2020/09/21 10:21

対象サーバに appServlet が含まれているWebアプリケーションないしはwarファイルがあるでしょうか? SpringBootをお使いの場合はSpringBoot内包のEmbedded Tomcatを利用していれば発生しない問題ですが…。
icecleam

2020/09/21 15:41

warファイルとappServlet が含まれているWebアプリケーションはありませんでした。 すみません、知識が少なくお手数をおかけします。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問