前提・実現したいこと
SpringBoot + ThymeleafでWebアプリを開発中です。
機能としては
ブラウザに入力フォームを配置し
入力された値をDBに登録、そして
登録されたデータ達をブラウザ上で一覧表示させるというものです。
以下のような流れです。
・STSで開発したコード類を実行可能JARとしてビルドし、これをcloudfoundry(Pivotal)にデプロイ
・cloudfoundryではcleardbのサービス(MySQL)を利用。
・デプロイしたアプリとDBサービスをバインドし、アプリを起動
・無事に起動に成功したが、日本語データを入力・登録しようとすると全ての日本語(全角文字)データが「?」に置き換えられ、文字化けが発生
ちなみに文字化けしたのはフォーム入力を経由しているものだけで、
HTMLに直接打ち込んだ日本語や、
thymeleafの変数式に直接代入(フォーム入力値ではなく、事前にコードに書いておいた固定の文字列)した文字列(日本語)は
文字化けしていません。
現在文字化け解消に向けて試行錯誤中です。
発生している問題・エラーメッセージ
同じアプリをローカル環境(ローカルのMySQL)で起動した所、
日本語データも問題なく登録・表示されました(読み込んでいるpropertiesファイルはapprication.propertiesです)。
また、cleardbのサービスインスタンスに対して
ローカルと同じようにコマンドプロンプトからアクセスし、
以下の事を試しました。
手入力で日本語のデータを登録し、これをデプロイしたアプリ上から確認。
このデータは文字化けせずに日本語のまま表示されていました。
したがって、入力フォームに記入した値をDBに引き渡す過程で何か問題がある可能性があると考えています。
それがthymeleafの変数式によるものなのか、リポジトリによるものなのか分かりません。
文字化けに関して自分なりに色々調べ試してみましたが未だに解消には至っておりません。
ちなみに、
コマンドプロンプトにて確認したcleardbのMySQL文字コードは以下の通りです。
ローカル環境と違って設定ファイルをいじって文字コードを変える事ができなさそうなので悩んでいます。
+--------------------------+------------------------------+
| Variable_name | Value |
+--------------------------+------------------------------+
| character_set_client | cp932 |
| character_set_connection | cp932 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | cp932 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql56/charsets/ |
+--------------------------+------------------------------+
また、参考までにローカルDBの文字コードは以下の通りです。
+--------------------------+---------------------------------------------------------+
| Variable_name | Value |
+--------------------------+---------------------------------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | C:\Program Files\MySQL\MySQL Server 5.7\share\charsets\ |
+--------------------------+---------------------------------------------------------+
該当のソースコード
#以下の内容はapprication-cloud.propertiesのもの。
#springboot1.4からspring.datasource.connectionPropertiesは使えなくなった模様。
#代わりに↓を記述。
spring.datasource.tomcat.connection-properties=useUnicode=true;characterEncoding=UTF-8;
spring.datasource.tomcat.driver-class-name=com.mysql.cj.jdbc.Driver
#datasource系
spring.datasource.sql-script-encoding=UTF-8
#thymeleafの設定
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.mode: HTML
#EMBEDDED(埋め込み)tomcatの設定?
server.tomcat.uri-encoding=UTF-8
#これがCharacterEncodingFilterに相当する設定?
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true
試したこと
各ファイルのtext file encoding の確認(UTF-8)
application-cloud.properties内での設定の見直し(上記参照)
補足情報(言語/FW/ツール等のバージョンなど)
[OS]
win10
[開発言語]
Java
[開発環境]
STS3.9.0.
SpringBoot1.5.7.
Thymeleaf3.0.2.
[デプロイ先]
PivotalCloudFoundry(Pivotal Web Services)
[使用DB]
Cleardb MySQL(CloudFoundryのサービスインスタンス)
追記
clearDBのMySQLサービスインスタンス内の文字コード
(win10コマンドプロンプト経由で確認。)
【データベースの文字コード】
mysql> show create database データベース名 ;
+--------------------+-----------------------------------------------------------------------------+
| Database | Create Database |
+--------------------+-----------------------------------------------------------------------------+
| データベース名 | CREATE DATABASE `データベース名` /*!40100 DEFAULT CHARACTER SET utf8 */ |
+--------------------+-----------------------------------------------------------------------------+
1 row in set (0.19 sec)
【テーブルの文字コード】
mysql> show create table テーブル名;
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| テーブル名 | CREATE TABLE `テーブル名` (カラム定義) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.17 sec)
【ビューの文字コード】
mysql> show create view ビュー名;
+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
| View | Create View | character_set_client | collation_connection |
+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
| ビュー名 | ビューの生成規則 | utf8 | utf8_general_ci |
+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
1 row in set (0.20 sec)
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+1
mysql://hostname:port/database?useUnicode=true&characterEncoding=utf8
とかちゃんとしてる?
あと CREATE TABLE 実行時、CREATE DATABASE 時にDEFAULT CHARSET を UTF8にしてる?
追記
文字コード設定の優先順位
- カラム指定の文字コード
- テーブル指定の文字コード
- データベース指定の文字コード
- システム指定の文字コード
文字コード未設定の場合は
データベース作成時に未指定の場合はシステムの設定を引き継ぎ
テーブル作成時に未指定の場合はデーターベース(上記)の設定を引き継ぎ
カラム作成時に未指定の場合はテーブル(上記)の設定を引き継ぎ
多分以下のように取得したのをどこかで設定しているとおもうので
{
"jdbcUrl": "jdbc:mysql://us-cdbr-iron-east-05.cleardb.net/***********?user=***********&password=***********",
"uri": "mysql://***********:***********@us-cdbr-iron-east-05.cleardb.net:3306/***********?reconnect=true",
"name": "***********,
"hostname": "us-cdbr-iron-east-05.cleardb.net",
"port": "3306",
"username": "***********",
"password": "***********"
}
どこかで設定しているはずですよ
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.23%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2017/11/12 13:06
お礼遅くなり申し訳ございません。
頂いたアドバイス2点を踏まえ改めてコードを確認致しました。
まず1点目に関してお話させて頂きます。
SpringBootの場合、本来であればapplication.propertiesファイルに
(下記はローカル環境での場合)
spring.datasource.url=jdbc:mysql://localhost:3306/DB名
spring.datasource.username=ユーザー名
spring.datasource.password=パスワード
のような記述をすると思うのですが
cloudfoundryと組み合わせると、cleardbのサービスインスタンスとバインドした時点で自動的にDBが作成され、接続設定も自動で行われるようなので
上記のような明示的な指定をする所が無い気がします。
したがって
?useUnicode=true&characterEncoding=utf8
を記述ができませんでした。
ちなみに、ローカル環境において
DBの文字コードを
character_set_client
character_set_connection
character_set_results
の値をcp932に変更し
クラウドの文字コード環境(質問文参照)と条件を揃えた上で試した所
(違う点はcharacter_set_serverの値がutf8である所のみ)、
?useUnicode=true&characterEncoding=utf8
の記述を加えなくても問題なく日本語入力・表示が行えました。
character_set_client
character_set_connection
character_set_results
の値を変更したのでローカル環境でも文字化けするだろうと思っていたのですが、しませんでした。
次は2点目についてです。
cloudfoundryはサービスインスタンスを利用する場合、
DBは自動で作成されそれを割り当てられる形なので
create database を任意で行えないようです。
また、create table実行時に
create table if not exists テーブル名(カラム定義)default character set utf8;
としても変化はありませんでした。
尚、文字コードを指定した場合としなかった場合どちらも
テーブルの文字コードはutf-8でした(default character setの値がutf8なので指定しなくてもutf8でテーブルが作成されるという事でしょうか)。
また、データベース自体の文字コードも確認するとutf8でした。
質問文にこれらの詳細を追記させて頂きましたのでもしよろしければご覧下さい。
また、アプリ起動時に毎回読み込まれるschema.sqlの先頭に
set names utf8
を記述して試してみたのですが、変化無しでした。
set namesでutf8に指定すれば
character_set_client
character_set_connection
character_set_results
の値をデフォルトのcp932ではなくutf8に変更でき、
utf8としてクライアントで入力した値をサーバーに渡せるので
文字化け解消するだろう、と思ったのですが駄目でした。
ローカル環境をクラウド環境側に条件を揃えて試しても
ローカル環境とクラウド環境で挙動が一致しない部分もあったため
(character_set_client等をcp932に変更・反映させてして実行しても文字化けは起こらなかった)
、どうして良いものか頭を抱えております。
ちなみに使用されているMySQLのバージョンが違う(ローカルは5.7、cleardbは5.6)のがやや気になりますが、
これは流石に関係無いのでしょうか。
今回のようにローカルでは問題なく日本語が登録できるのに
クラウドでは文字化けするという場合、
他に点検すべき項目などはございますでしょうか。
ローカルでも同じように文字化けするならまだ分かるのですが…。
引き続き、改善に努め試行中です。
もしお時間ございましたらアドバイス頂けると幸いです。
宜しくお願い致します。
2017/11/12 13:09
正:
尚、文字コードを指定した場合としなかった場合どちらも
テーブルの文字コードはutf-8でした(character_set_databaseの値がutf8なので指定しなくてもutf8でテーブルが作成されるという事でしょうか)。
誤:
尚、文字コードを指定した場合としなかった場合どちらも
テーブルの文字コードはutf-8でした(default character setの値がutf8なので指定しなくてもutf8でテーブルが作成されるという事でしょうか)。
2017/11/12 13:29
情報を補足させて頂きます。
文字コード等の諸設定を変更して挙動を試すにあたり、
DBは毎回丸ごと削除して新たに作り直しています。
ローカルであればdropしてcreate
クラウドであればサービスインスタンスを削除し、新たにサービスインスタンスを生成してそれをバインド
という手続です。
なので設定変更したがDBの設定は旧いまま、という事はありません。
2017/11/12 20:26
各トランザクション開始時に SET NAMES 句で UTF8変換するしかないような最低なサービスじゃないとおもうが、海外サービスなのでそうとも言い切れないな。。。