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

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

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

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Java

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

Eclipse

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

Thymeleaf

Thymeleaf(タイムリーフ)とは、Java用のテンプレートエンジンで、特定のフレームワークに依存せず使用することが可能です。

Spring Boot

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

Q&A

解決済

1回答

966閲覧

ユーザー登録機能を実施する際にエラーが発生する

shinnuko

総合スコア13

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Java

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

Eclipse

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

Thymeleaf

Thymeleaf(タイムリーフ)とは、Java用のテンプレートエンジンで、特定のフレームワークに依存せず使用することが可能です。

Spring Boot

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

0グッド

0クリップ

投稿2020/07/05 00:25

編集2020/07/05 11:58

前提・実現したいこと

現在Javaを使用して掲示板を作製しています。
ユーザー登録とログインを実施する機能を実装しようとした所、登録ボタンを押した際に登録情報がMYSQLのuserテーブルに反映されない状態になっています。

DBの内容は以下の記事を参考にしています。

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

パスワードとユーザーネームをフォームから入力し、登録ボタンを押してもユーザー登録が出来ないと言った状態です。
web上で表示されるエラー

Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback. Sun Jul 05 08:42:27 JST 2020 There was an unexpected error (type=Internal Server Error, status=500). No message available

コンソール上でのエラー表示はこちら

該当のソースコード

register.html

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="register.css"> <title>ユーザー登録画面はこちら</title> </head> <body> <header> <div class="header-logo"> <!-- ① --> <a href="/">フォーム画面へ</a> <a class="header-right" href="/login/">ログイン</a> </div> </header> <div> <form th:action="@{/register/}" action="/register/" th:object="${registerDto}" method="post"> <h1>ユーザー登録</h1> <div th:classappend="${#fields.hasErrors('name')}? 'has-error'"> <label for="name">アカウント名</label> <div> <input id="name" type="text" th:field="*{name}" name="name"/> <span th:if="${#fields.hasErrors('name')}" th:errors="*{name}">error!</span> </div> </div> <div th:classappend="${#fields.hasErrors('password')}? 'has-error'"> <label for="password">パスワード</label> <div> <input id="password" type="password" th:field="*{password}" name="password"/> <span th:if="${#fields.hasErrors('password')}" th:errors="*{password}">error!</span> </div> </div> <input type="submit" value="新規登録"/> </form> </div> </body> </html>

login.html

<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>ログイン</title> </head> <body> <form th:action="login" method="POST"> <table align="center"> <tr> <td> ユーザ名: </td> <td> <input type="text" id="user" name="user"/> </td> </tr> <tr> <td> パスワード: </td> <td> <input type="password" id="password" name="password"/> </td> </tr> <tr> <td> </td> <td align="right"> <button type="submit">ログイン</button> </td> </tr> <tr> <td> </td> <td align="right"> <a href="/register/">新規登録</a> </td> </tr> </table> </form> </body> </html>

WebSecurityConfig.java

package com.example.demo.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override public void configure(WebSecurity web) throws Exception { // セキュリティ設定を無視するリクエスト設定 // 静的リソースに対するアクセスはセキュリティ設定を無視する web.ignoring().antMatchers("/","/css/**", "/datepicker/**", "/img/**"); } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() // 認証が必要となるURLを設定します .antMatchers("/login/").permitAll() // /loginFormは認証不要 .antMatchers("/register/").permitAll() .antMatchers("/thread/").permitAll() // /threadURLも認証不要 .anyRequest().authenticated(); // それ以外はすべて認証された状態じゃなきゃダメ } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); //パスワードのハッシュ化でBCryptを使う } }

RegisterController.java

package com.example.demo.controller; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.example.demo.dto.RegisterDto; import com.example.demo.dto.RegisterprocessDto; import com.example.demo.service.RegisterService; @Controller public class RegisterController { @ModelAttribute public RegisterDto setupForm() { return new RegisterDto(); } @RequestMapping(value="register") public String registerDto() { return "register"; } @RequestMapping(value = "/register/", method = RequestMethod.POST) String create(@Validated RegisterDto form, BindingResult bindingResult) { if (bindingResult.hasErrors()) { return "/register/"; } RegisterprocessDto registerprocessDto = new RegisterprocessDto (); RegisterService registerService = new RegisterService (); registerprocessDto.setName(form.getName()); registerService.create(registerprocessDto, form.getPassword()); return "redirect:/complete"; }

RegisterDto.java

package com.example.demo.dto; import java.io.Serializable; import lombok.Data; @Data public class RegisterDto implements Serializable { private String name; private String password; }

RegisterprocessDto

package com.example.demo.dto; import java.io.Serializable; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; import lombok.Data; @Entity @Table(name = "users") @Data public class RegisterprocessDto implements Serializable { @Id @GeneratedValue private Integer user_id; @Column(nullable=false) private String name; @Column(nullable=false, length=20) private String password; @Column(nullable=false, updatable=false) private Date created_at; @Column(nullable=false) private Date updated_at;

RegisterRepositpry

package com.example.demo.dao; import org.springframework.data.jpa.repository.JpaRepository; import com.example.demo.dto.RegisterprocessDto; public interface RegisterRepository extends JpaRepository<RegisterprocessDto, Integer> { }

RegisterService.java

package com.example.demo.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.example.demo.dao.RegisterRepository; import com.example.demo.dto.RegisterprocessDto; @Service @Transactional public class RegisterService { @Autowired RegisterRepository registerRepository; @Autowired PasswordEncoder passwordEncoder; public RegisterprocessDto create(RegisterprocessDto registerprocessDto , String rawPassword) { String encodedPassword = passwordEncoder.encode(rawPassword); registerprocessDto.setPassword(encodedPassword); return registerRepository.save(registerprocessDto); } }

試したこと

参考記事を基に、自身のコード内容を確認し、間違いや異なる部分があるか確認していきましたが解決に至りませんでした。

気になる点としては、WebSecurityConfig.javaの部分にログインしていない場合はログインフォームに飛ばす機能を追加した際にエラーが警告文が発生し、追加できなかったことです。こちらが今出ているエラーにも影響しているか定かではありませんが、以下のコードには入っていません。

.and() .formLogin() // ログインページに飛ばすよ .loginProcessingUrl("/login") // ログイン処理をするURL .loginPage("/login"); // ログインページのURL

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

Java SE8
Eclips Version: 2020-03 (4.15.0)
SpringBoot
Mysql8.0

登録、ログイン機能参考記事
登録、ログイン機能参考記事

参考記事からの名称変更や設定部分

ユーザデータを登録する処理用のController作成
※RegisterControllerの名称に変更して作成しています。

Formの作成
※RegisterDto.javaの名称に変更して作成しています。

RegisterDto.javaに対応するhtmlの作成
※register.htmlの名称で作成。

submitした後の登録処理 Modelの作成
※RegisterprocessDtoの名称に変更して作成しています。
リポジトリの作成
※RegisterRepositpryの名称で作成。
サービスクラスの作成 
com.example.demo配下にserviceパッケージを作製し、その中にRegisterservice..javaの名称で作製しています。

自身の全体のGithub内容はこちらになります。
リンク内容

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

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

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

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

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

m.ts10806

2020/07/05 01:06

Whitelabel Error Page のほとんどはThymeleafの構文エラーです。 コンソールに具体的な記述や行数出てませんか?
shinnuko

2020/07/05 01:19

Orlofskyさん リンク先投稿の修正を行いました。アドバイスありがとうございました。
shinnuko

2020/07/05 01:23

m.ts10806さん コンソール上ではエラー文として下記の内容が表示されています。 Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause java.lang.NullPointerException: null 具体的な行数などは表示されていない状態です。
shinnuko

2020/07/05 08:51

asahina1979さん 前回のエラー内容は解決されましたが、次は同じ場所で異なるエラーが発生しているため今回また改めてエラー内容を変更し、こちらに投稿させて頂きました。
退会済みユーザー

退会済みユーザー

2020/07/05 08:54

タイトルが「ユーザー登録機能を実装する際にDBに反映されない。」 なのでそれは解決したとは言わない
m.ts10806

2020/07/05 08:57

NullPointerException なら原因は沢山ないですよ。 Javaでもっともよく起きるexceptionです。
shinnuko

2020/07/05 11:52

asahina1979 おっしゃる通りですね。この場合問題としては同じ内容になるのですが、エラー内容としては異なる種類が検出されていますので、質問としてはまた違った投稿として作成した方が良いのかなと思っていました。 不適切であった場合申し訳ありませんでした。
m.ts10806

2020/07/05 11:55

今からでもタイトル変更された方が良いかと。
shinnuko

2020/07/05 11:55

m.ts10806 アドバイスありがとうございます。先程問題解決に至りましたので報告させていただきます。
m.ts10806

2020/07/05 11:56

>Javaで掲示板を作製し、ユーザー登録機能を実装する際に という長い前置きを毎回入れるのではなく、もっとストレートにエラーのことだけ書くとか
m.ts10806

2020/07/05 12:00

いえ、「NullPointerException」と書かないと、別のエラーが起きた時に同じタイトルになります。 私なら「○○という操作をしたときにNullPointerExceptionが発生する原因について」とか、具体的に「どういう操作をしたときに起きたか」を書きます。 「こういう機能を作ろうとしてて・・・」は質問内容で書いた方が良いでしょうし。
shinnuko

2020/07/05 12:01

m.ts10806 確かに今のタイトルでは違いや問題が分かりにくい気がしました。 次回からはエラー文の内容や行っている内容を短くまとめて投稿させて頂きます。
shinnuko

2020/07/05 12:06

m.ts10806 タイトルと質問内容の使い方についても確認しました。 併せて適切な投稿を心掛けて行きますのでよろしくお願い致します。
m.ts10806

2020/07/05 12:07

細かいところで気にし過ぎかもしれませんが途中から「~さん」がなくなったのはどういう意図でしょうか。
shinnuko

2020/07/05 14:07

m.ts10806さん 大変失礼しました。こちらについては意図的ではなく、付け忘れていたのが理由となります。 こちらとしても投稿方法のノウハウなどもやり取りしている中で教えて頂いていますので、とても感謝しています。 気分を悪くされていましたら大変申し訳ありませんでした。 今後ともよろしくお願い致します。
m.ts10806

2020/07/05 14:08

なるほど。コメントも一応修正できるので、気づいたときに適宜調整すると良いかと思います。 何か気に障ることでも言ったかなと、気になっていました。
shinnuko

2020/07/05 14:18

m.ts10806さん タイトル、内容共に他の方が投稿を見て分かりやすい質問になるように心掛けて行きたいと思いますので随時改善して行きたいと思います。 今回のやり取りの中でも適切なアドバイスを頂いていますので、気に障る部分は何もありません。 気になる部分を伝えて下さるのでこちらとしても大変勉強になっております。 重ねてお礼申し上げます。
guest

回答1

0

ベストアンサー

エラーメッセージから以下の場所(RegisterService.create)でNullPointerExceptionが起きていることが分かります。

java.lang.NullPointerException: null at com.example.demo.service.RegisterService.create(RegisterService.java:22) ~[classes/:na] at com.example.demo.controller.RegisterController.create(RegisterController.java:39) ~[classes/:na]

この例外の直接的な原因はRegisterController.createメソッド内でサービスクラスを直接newしていることにあります。

java

1@RequestMapping(value = "/register/", method = RequestMethod.POST) 2String create(@Validated RegisterDto form, BindingResult bindingResult) { 3 4 //省略 5 6 // これが原因 7 RegisterService registerService = new RegisterService (); 8 9 //省略 10 11}

このサービスクラスのインスタンスの生成をプログラマー自身が行うと、何が問題になるかというとこのサービスクラス内で利用しようとしているRegisterRepositoryおよびPasswordEncoderのインスタンスのセットがSpring Frameworkによって行われなくなることです。

java

1@Service 2@Transactional 3public class RegisterService { 4 @Autowired 5 RegisterRepository registerRepository; 6 @Autowired 7 PasswordEncoder passwordEncoder; 8 9 public RegisterprocessDto create(RegisterprocessDto registerprocessDto , String rawPassword) { 10 // passwordEncoderがnullなのでここでNullPointerExceptionが起きる 11 String encodedPassword = passwordEncoder.encode(rawPassword); 12 registerprocessDto.setPassword(encodedPassword); 13 return registerRepository.save(registerprocessDto); 14 } 15 16}

なので、RegisterServiceもSpring Frameworkによってセットされるようにコントローラークラスを以下のように修正する必要があります。

java

1@Controller 2public class RegisterController { 3 // 追加 4 @Autowired 5 RegisterService registerService; 6 7 //省略 8 9 @RequestMapping(value = "/register/", method = RequestMethod.POST) 10 String create(@Validated RegisterDto form, BindingResult bindingResult) { 11 //省略 12 13 // インスタンス化は自分で行わない 14 // RegisterService registerService = new RegisterService (); 15 16 //省略 17 } 18 19}

Spring Framework (Spring Bootも)では、@Controller@Service@Conmponetといったアノテーションを付けたクラスは自分自身ではインスタンス化やフィールドへのセットは行わず、フレームワークに任せる必要があります。(テストコードは例外)

投稿2020/07/05 01:31

rubytomato

総合スコア1752

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

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

shinnuko

2020/07/05 11:47

丁寧な解説ありがとうございます。 おかげさまでエラーも解決し、原因も理解できました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問