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

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

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

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

Java

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

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

検索

検索は、あるデータの集まりの中から 目的のデータを見つけ出すことです。

Spring Boot

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

Q&A

解決済

2回答

3316閲覧

検索ボックスに「%」「_」を入れて検索できない

engnao

総合スコア29

MySQL

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

Java

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

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

検索

検索は、あるデータの集まりの中から 目的のデータを見つけ出すことです。

Spring Boot

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

0グッド

1クリップ

投稿2020/08/26 13:07

【問題】
Springでページネーションを踏まえた検索機能を作成しています。
文字列「%」「」の記号を検索ボックスに入れた時、
「%」「
」で検索されず、全件検索結果が取得されてます。

恐らくエスケープ文字と識別されている事が原因だと思っていますが、
どのようにコードを訂正すれば良いかわかりません。
どなたかご教示をお願いいたします。

【進捗状況】
・JPAを使用してDBからデータ取得を行っており、問題のエスケープ文字以外は問題なく表示できます
・ページネーションのコーディングも終わっており、最終検証の段階で【問題】を発見いたしました

【使用言語/ツール】
・Java
・MYSQL
・Spring Boot
・STS(spring tools site)

【ソースコード】
参考コード
・TaskController(Controller)
・TaskRepository(Repository)
※参考コードは回答に応じて追加します

TaskController(Controller)

java

1@Service 2@Transactional 3public class TaskService { 4 5 @Autowired 6 private TaskRepository taskrepository; 7 @Autowired 8 private TaskSpecification taskspecification; 9 10 public Page<TaskEntity> searchmaterial(String title, String titleKana,Pageable pageable) { 11 return (Page<TaskEntity>) taskrepository.findAll(Specification 12 .where(taskspecification.titleContains(title)) 13 .and(taskspecification.titleKanaContains(titleKana)) 14 ,pageable 15 ); 16 } 17}

TaskRepository(Repository)

java

1@Repository 2public interface TaskRepository extends JpaRepository<TaskEntity,Long>, JpaSpecificationExecutor<TaskEntity>{ 3 4 Page<TaskEntity> findByTitleAndTitleKana(String title, String titleKana, Pageable pageable); 5 6 7}

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

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

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

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

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

guest

回答2

0

★★★ 注意 ★★★

xebme さんのご指摘にある通り、ユーザー入力に「%」、「_」を許すことは、SQL インジェクションの危険性があります。以下のリンクが適切かどうか、精査できていませんが、参考になれば幸いです。

「とにかくプレイスホルダを使おう」では脆弱性は無くなりません。

以下、そういった危険性を承知の上、かつ、外部に公開しないような限定されたところで利用したいというニーズに対する回答とご理解ください。

【最初の回答】
メソッド名が LIKE 検索用になっていないような気が。

【Spring Data JPA】自動実装されるメソッドの命名ルール - Qiitaあたりとか、参考にならないでしょうか。

【追記】

TaskService が呼び出しているのが、taskrepository.findAll() なので TaskRepository で追加で定義したメソッドが使われるように修正する必要がありそうです。

【追記その2】

しかし、冒頭でアドバイスを頂いた「TaskRepository で追加で定義したメソッドが使われるように修正する必要がありそう」に関して、taskrepository.findAll() をどのように変更すれば良いかがわかりません。

以下、動作確認はしていませんが。以下のように直した場合の動作を確認してみてください。

java

1@Service 2@Transactional 3public class TaskService { 4 5 @Autowired 6 private TaskRepository taskrepository; 7 @Autowired 8 private TaskSpecification taskspecification; 9 10 public Page<TaskEntity> searchmaterial(String title, String titleKana,Pageable pageable) { 11 return taskrepository.findByTitleAndTitleKana(title, titleKana, pageable); 12 } 13}

 ただし、この修正だとこれまでの「%」、「_」を使わない入力における部分一致検索が使えません。
xebme さんが

さらに、検索条件を調べて、%_があればLIKE検索、なければ通常検索にしなければならず、ここにも設計不備があると思われます。

と書かれている通り、条件分岐が必要になると思います。

投稿2020/08/26 13:14

編集2020/08/27 19:19
Yasumichi

総合スコア1773

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

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

engnao

2020/08/26 16:30

Yasumichiさん 情報共有ありがとうございます。 頂きました資料を基にコードを書きましたが、変わらず「%」「_」の検索結果を取得できませんでした。ソースコードの訂正方法が間違っているのでしょうか? 【訂正前】 Page<TaskEntity> findByTitleAndTitleKana(String title, String titleKana, Pageable pageable); 【訂正後】 Page<TaskEntity> findByTitleAndTitleKanaNotLike(String title, String titleKana, Pageable pageable);
Yasumichi

2020/08/26 18:58

TaskService が呼び出しているのが、taskrepository.findAll() なので TaskRepository で追加で定義したメソッドが使われるように修正する必要がありそうです。 以下、それが、修正されていると仮定して。 細かい仕様が不明なので判断に悩むところですが、現在の訂正方法だと TitleKana フィールドで NOT LIKE (マッチしないものを探す)検索を行うように見えますが、意図したとおりでしょうか? 例えば、Title および TitleKana の両方で LIKE 検索(マッチするものを探す)のであれば、 findByTitleLikeAndTitleKanaLike になると思います。 あと、まだ検証できていないので可能性の推測ですが、TaskService に渡っている title または titleKana に含まれる % や _ がサニタイズ(無害化)されていないか、気になる所です。  一度、title や titleKana がどのような値になっているのか、デバッグやログ出力で確認してみてはいかがでしょうか?
xebme

2020/08/26 22:54

SQL構文の%_を入力できることはSQLインジェクションを可能にするので、セキュリティに問題があります。さらに、検索条件を調べて、%_があればLIKE検索、なければ通常検索にしなければならず、ここにも設計不備があると思われます。
engnao

2020/08/27 01:54

Yasumichiさん ご丁寧に回答ありがとうございます。 TaskRepository に追加するメソッドについて、Title および TitleKana の両方で LIKE 検索 を行いたいので、findByTitleLikeAndTitleKanaLike に変更しました。 また、TaskService に渡っている title 及び titleKana に含まれる % や _ をデバッグで確認した所、サニタイズされてなく値に% や _ が設定されている事を確認しました。 しかし、冒頭でアドバイスを頂いた「TaskRepository で追加で定義したメソッドが使われるように修正する必要がありそう」に関して、taskrepository.findAll() をどのように変更すれば良いかがわかりません。 初歩的な内容で大変恐縮ですが、変更方法を教えて頂きたいです。 よろしくお願いいたします。
engnao

2020/08/29 03:16

Yasumichiさん xebmeさん ご丁寧にご回答ありがとうございます。 頂いた内容通り訂正を試みましたが、org.apache.commons.lang3.StringUtils を使用して解決できるようでしたので、StringUtils でエスケープ文字「%」「_」をリプレースする事により、問題を解決いたしました。 本当にありがとうございました。
guest

0

自己解決

Yasumichiさん
xebmeさん
ご丁寧にご回答ありがとうございます。
頂いた内容通り訂正を試みましたが、org.apache.commons.lang3.StringUtils を使用して解決できるようでしたので、StringUtils でエスケープ文字「%」「_」をリプレースする事により、問題を解決いたしました。
本当にありがとうございました。

投稿2020/08/29 03:15

engnao

総合スコア29

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問