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

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

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

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

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

Q&A

解決済

1回答

4708閲覧

Javaの並列処理でセッションスコープの値を取得したい

gnuuu_07

総合スコア10

Java

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

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

0グッド

1クリップ

投稿2020/07/23 13:20

編集2020/07/24 01:33

前提・実現したいこと

Springフレームワークを使って、JavaのThreadクラスを使った並列処理を書いており、その中でセッションスコープに格納されている値を取得したいです。

発生している問題・エラーメッセージ

Exception in thread "Thread-6" java.lang.IllegalStateException: No thread-bound request found というエラーメッセージが出力され、調べたりしたのですが解決に至りませんでした。

該当のソースコード

サービスクラス

java

1@Service 2public class SendMailService extends Thread{ 3 public void run() { 4 Integer userId = (Integer)session.getAttribute("userId"); 5     List<Order> order = orderService.getLatestOrderList(userId); 6 SimpleMailMessage msg = new SimpleMailMessage(); 7     //以下処理が続きますが、ここでは割愛します 8 } 9}

コントローラクラス

Java

1@Controller 2public String order(@Validated OrderForm form, BindingResult result, Model model) { 3   4 //ここより上はその他の処理を記述しているので割愛します 5 sendMailService.start(); 6 return "redirect:/orderFinished"; 7}

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

mainのクラスでThreadクラスのstartメソッドを使って呼び出すと、sessionスコープの値を取得する処理の部分で止まり、前述のメッセージが出力されます。
並列処理についての学習を始めたばかりなので、まだ理解が浅いと思われますが、よろしくお願いします。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2020/07/23 14:38 編集

回答に書くほどの自信がなかったのでこちらに記載します。 最近はbootばかり触っているのでわからないですが、 https://www.codeflow.site/ja/article/spring__spring-request-scope-error-no-thread-bound-request-found こちらは試して見られましたか? あと、「mainのクラスでThreadクラスのstartメソッドを使って呼び出すと」と書かれていることについて、 今の実行の方法はどのように行なっているのでしょうか? springということですが、サーバーにデプロイしてブラウザからリクエストしているわけではなさそうですよね? 実行方法も記載すると、回答が得られやすくなると思います。
gnuuu_07

2020/07/24 01:35

記載いただき、ありがとうございます。 そちらのurlの内容に関しては、プロジェクトにweb.xmlファイルが存在していないため、試せておりません。 実行に関しては、デプロイなどはしておらず、ローカル環境でビルドして実行しております。 startメソッドでの呼び出しに関しては、コードを追記しておきました。
退会済みユーザー

退会済みユーザー

2020/07/24 01:50

ビルド後に実行するのはJavaアプリケーションでしょうか? サーバー等にデプロイせずに、コマンドラインからメインを実行しているのですか? 実際の実行手順を記入して頂けると幸いです。
gnuuu_07

2020/07/24 02:49

すいません。少し勘違いしていました。実行手順は以下の通りです。 実行手順としては、プロジェクトがspring starterプロジェクトでして、spring boot アプリケーションで実行しております。 ビルドやデプロイはspringで自動でやってくれています。
退会済みユーザー

退会済みユーザー

2020/07/24 02:53

やはりそうでしたか。 実際に実行手順としては以下となっていると思いますが、合っておりますでしょうか? ・実行の構成→Javaアプリケーションでspringbootのメインクラス(Application何とかだったような)を指定。 ・実行→springbootがサーバーのデプロイから起動まで行ってくれる。 ・ブラウザ等でlocalhost:8080にアクセス(おそらくtomcat使用していると思うので)
退会済みユーザー

退会済みユーザー

2020/07/24 02:54

ブラウザからサーバーにアクセスしているのでしょうか?
gnuuu_07

2020/07/24 02:56

そうですね 今記述してくださった手順で、ブラウザからlocalhost:8080にアクセスしています。
退会済みユーザー

退会済みユーザー

2020/07/24 03:20

回答ありがとうございます。 回答ありがとうございます。 適宜質問は修正していただくと回答が得られやすいと思います。 SendMailServiceクラスでThreadを継承(おそらくjava.jang.Threadだと思います)していますが、SpringBootでマルチスレッド処理を行う際は@Asyncなどのアノテーションを使用するのが一般的だと思います。 こちらを使用しなかった理由としてはなんでしょうか? SpringBootが用意しているもの以外で処理を行おうとすると、SpringBootの管理外になったりなどの不具合が発生する可能性があります。 もしかしたら、それが原因かもしれないですね。
gnuuu_07

2020/07/24 04:08

@Asyncというアノテーションの存在を今初めて知りました。 こちらはマルチスレッド処理を行う際に使う、JavaのThreadと似た役割を持つものと考えてよろしいのでしょうか?
退会済みユーザー

退会済みユーザー

2020/07/27 17:02

すみません。コメント気づきませんでした。 直接の解決策ではありませんが、回答に記載します。
guest

回答1

0

ベストアンサー

java.lang.Threadを調べました。
Theadは、自身のサブクラス(ここでいうSendMailService)のインスタンスが生成されることでスレッドを作成するようです。

Controller内で

sendMailService.start();

を行なっておりますが、おそらく上の方で

@Autowired SendMailService sendMailService;

と記述されているのではないかと想定します。

springのAutowiredは、ソース内からnewを消すことができると思われがちですが、
新しいインスタンスを生成しているわけではなく、その実態はシングルトンです。

java.lang.Threadが新規インスタンス生成時にスレッドを作成するため、スレッドのセッションスコープを取得出来ないのかと思われます。
(もしかしたらSendMailServiceをコントローラー内でnewすることで取得可能かもしれませんが、springのDIの概念がおかしくなってくるのでお勧めしません。)

当方質問者様のような実装を試みたことがありませんので解決方法がわかりませんが、spring上でセッションスコープの管理や非同期を行うのでしたら、springの用意しているspringsessionや@Asyncアノテーションで実装することをお勧めいたします。

投稿2020/07/27 17:18

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

gnuuu_07

2020/07/30 09:47

ご回答ありがとうございます。 @Asyncアノテーションの使用などにより、並列処理の実装を行えました。 新たな知識得ることができ、感謝しております。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問