モーグルとカバとパウダーの日記 このページをアンテナに追加 RSSフィード Twitter

モーグルやカバ(EXカービングスキー)、山スキー(BC)の山行記録などがメインの日記です。
いろんな条件のいろんなところを、その時々の条件にあった滑り方で楽しむ、フリースキーをして遊んでいます。

検索で来られた方は、上の検索窓から再度検索していただくか、右サイドバーのカテゴリーやトピックスの項目で絞り込んでみてください。
仕事柄、コンピュータ系のネタも多いので、スキー関連ネタだけ読みたい方は[ski]、コンピュータ関連ネタは[pc]、スパム関連ネタは[spam]で絞り込んでください。

2015-10-26 (Mon)

[]Selenium IDEJavaScriptのエラーが出た時はSelenium再起動する Selenium IDEでJavaScriptのエラーが出た時はSeleniumを再起動するを含むブックマーク Selenium IDEでJavaScriptのエラーが出た時はSeleniumを再起動するのブックマークコメント

Jenkins + Selenium IDEで自動実行させたいものがあり、SeleniumからjQueryを使ってフォームのチェックを選択するようにしていました。


Seleniumは「getEval」コマンドを使うことでJavascriptを実行でき、一旦下記のようにして「$」を設定してやれば、その後は普通にjQueryを使うようにgetEval内でjQueryコマンドを発行できます。

$ = this.page().getCurrentWindow().jQuery

この辺のことは

SeleniumJavaScriptを使う方法いろいろ(変数関数などの利用) - colori

https://colo-ri.jp/develop/2008/04/seleniumjavascript.html

が大変参考になります。


で、これでjQueryを使ってフォームの該当チェックボックスの選択をしたりしていたのですが、ちょっと条件を変えたいことがあり、変更していたところ突然動かなくなってしまいました。

getEval内のJavaScriptにエラーがあったのですが、それを修正しても動かないのです。

それで条件を単純に変えてみたり、元の条件に戻したりやってみたのですが、なかなかエラーが解消されず…

で、他のPCで同じようなことをテストで試してみたところ、さっくりと通ることがわかりました。


もしやと思い、一旦Selenium IDEを落として、再度同じテストケースを読み込んで試したところ、なんの問題もなく通りました。

どうもgetEval使ってJavaScriptのエラーが一旦起きると、再度テストケースを走らせても内部の状況がクリアされずに走るため、テストケースの修正をしてもまたエラーが起きてしまうようです。

なので、Selenium IDEでgetEval使ってJavaScriptを動かしているとき、JavaScriptでエラーが出た場合、テストケースを修正したら、一旦Selenium再起動して試す必要があるようです。

トラックバック - http://d.hatena.ne.jp/stealthinu/20151026

2015-09-28 (Mon)

[]CentOS6にGitBucketをインストールするときの注意点 CentOS6にGitBucketをインストールするときの注意点を含むブックマーク CentOS6にGitBucketをインストールするときの注意点のブックマークコメント

2年くらい前にCentOS5にGitLab5を入れようとしてすごく大変だった思い出があり、githubクローンインストールは僕の中で非常に大変な作業という印象があったのですが…

GitBucketがあまりにも簡単にインストールできてもうびっくりで感動でした。

ただ、一箇所だけハマったところがあったので、その注意点を書くためにこのエントリを書いてます。


GitBucketはScalaで書かれたgithubクローンで、Scalaなのでjavaで動きます。

今回はCentOS6に入れたのですが、Tomcat7以上で動くとのことで、Java7とTomcat7のインストールを行います。

これは下記エントリのようにjpackageのリポジトリを使ってインストールすると簡単です。


GitBucketを5分で導入する方法 | りぐん怪獣じゃないもん!


ただ、そのままだとGPGの署名チェックで失敗するので、下記エントリのように /etc/yum.repos.d/jpackage.repo の「gpgcheck=0」に修正してやります。

CentOS6にJDK8・Tomcat7の環境を構築した時に詰まった話 | Hack


なんとこれだけでインストール終わりです。

あとはブラウザでアクセスするだけ… GitLabであんなに苦労したのは何だったのかと。


しかし、自分の環境ではこれだけではうまく動いてくれませんでした。

上のエントリーで

GitBucketの管理ディレクトリtomcatのホームディレクトリに作られるんだけどホームディレクトリがないとエラーになる。

と書いてあるように、GitBucketの管理ディレクトリ .gitbucket がtomcatのホームディレクトリに作られます。

普通にyumインストールすると、tomcatユーザのホームディレクトリは /usr/share/tomcat7 になりますが、ownerはrootになっているため、tomcatの権限で .gitbucket を作るときに失敗してしまいます。


そこで、chownでownerを変更してやります。

$ sudo chown -R tomcat.tomcat /usr/share/tomcat7

tomcatのページは表示されて、GitBucketのwarファイルの自動展開も行われているのに、ページの表示が行われない場合、ここをチェックしてみると良いと思います。


まとめると

yum install java-1.7.0-openjdk-devel
yum install yum-plugin-priorities
rpm -Uvh http://mirrors.dotsrc.org/jpackage/6.0/generic/free/RPMS/jpackage-release-6-3.jpp6.noarch.rpm

/etc/yum.repos.d/jpackage.repo 修正

gpgcheck=0

yum install tomcat7-webapps
wget https://github.com/takezoe/gitbucket/releases/download/2.0/gitbucket.war
mv gitbucket.war /var/lib/tomcat7/webapps/
chown -R tomcat.tomcat /var/share/tomcat7
service tomcat7 start
トラックバック - http://d.hatena.ne.jp/stealthinu/20150928

2015-09-01 (Tue)

[]DNSのTXTレコードを複数書く場合 DNSのTXTレコードを複数書く場合を含むブックマーク DNSのTXTレコードを複数書く場合のブックマークコメント

自社のメールがGmailでどれだけスパム判定されてるか、グーグルのPostmaster Toolsで調べてみた | 編集長ブログ―安田英久 | Web担当者Forum

を見て、これは試してみねば、と思い、早速試してみようとしたのですが、メールアドレスドメインを登録するのに、DNSのTXTレコードgoogleの認証を設定する必要がでました。


しかし、すでにSPFレコードの設定が書いている場合、2つ目のTXTレコード設定を追加するにはどうするんだっけ?となりました。


SPFレコードに複数のIPを指定する場合や、複数行での記述をしたい場合、山井先生の書かれたこのページの説明がとても参考になります。

間違いから学ぶSPFレコードの正しい書き方 : 迷惑メール対策委員会


ですが今回の場合、SPFレコードとは別にgoogleの認証コードも書きたい、というもので、これまでTXTレコードを複数行書いたことがなかったので自信なくて…


結局、単純に複数行併記すれば良いようです。

例では1行目にSPFレコードを、2行目にgoogleの認証コードを指定しています。

example.jp.   IN   TXT   "v=spf1 +mx ~all"
example.jp.   IN   TXT   "google-site-verification=xxxxxxxxxxxxxxxxxxxxxxxxxx"

こっちの記述のほうが正しい(良い)というのがあればご指摘ください。

トラックバック - http://d.hatena.ne.jp/stealthinu/20150901

2015-08-31 (Mon)

[]vagrant上のCentOSyumがエラーになった件 vagrant上のCentOSでyumがエラーになった件を含むブックマーク vagrant上のCentOSでyumがエラーになった件のブックマークコメント

vagrant上でCentOS6.6を動かしていたのですが、ある時からyum installやupdateをしようとすると

[Errno 14] PYCURL ERROR 22 - "The requested URL returned error: 404 Not Found"

他のミラーを試します。

というエラーが出るようになりました。


これは /etc/yum.repos.d/CentOS-Base.repo の mirrorlist や baseurl で

baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/

のように設定されているところで $releasever が「6.6」になっているとうまくいかず、404になるURLを確認してみると

http://mirror.centos.org/centos/6.6/readme

This directory (and version of CentOS) is deprecated. For normal users,

you should use /6/ and not /6.6/ in your path. Please see this FAQ

のように書かれており「6.6」ではなく「6」でアクセスするようにせよ、と書いてあります。

これはググるとよくこの問題が出てきます。


なので、baseurlのコメントを外してmirrorlistのほうをコメントにしてやり、$releaseverを「6」に置換えてやることでとりあえず yum が動くようにはなりました。


なのですが、他のCentOS6環境だと何も設定変更しなくても yum update で6.7に上がっているのに、なぜここだけは6.6から自動的に上がらないのだろう?と不思議でした。


下記エントリでvagrant上でCentOS6動かしていると、IPv6が効いていると全く同じエラーが出る、と書かれていたためIPv6を切ってみたのですがやはりダメ。

vagrant環境下で [Errno 14] PYCURL ERROR 6 – “Couldn’t resolve host エラー | blog@human


そこで $releasever の値を「6」にするのはどこでやっているのかを調べると、

Red Hat Customer Portal

/etc/centos-release (/etc/redhat-release はここへのシンボリックリンク)のバージョンだ、ということだったので、ここのテキストを直接編集したのですが、自分の環境では変化がありませんでした。

ただ、通常はこれで変わってくれるようで、/etc/yum.repos.d/CentOS-Base.repo の中身を修正して回るより良いと思います。


さらにもう少し調べると

/etc/yum/vars/releasever ファイルでリリースバージョンを固定する | blog.hansode.org

というのがありました。

そこで /etc/yum/vars/releasever を確認すると、「6.6」となっていました。

デフォルトだとこのファイル自体が存在していません


実は vagrant の CentOS6.6 イメージを hansode さんが作られたもの(hansode/centos-6.6-x86_64)を使っていたので、もろにこの設定がされていたものを意識せずに使っていたため、この状況にハマってしまっていたのでした。


というわけで /etc/yum/vars/releasever を削除することで、普通に yum が使えるようになりました。

トラックバック - http://d.hatena.ne.jp/stealthinu/20150831

2015-08-11 (Tue)

[]スマホ用ページのデバッグを仮想Android端末を使ってホストPCのChromeから行う スマホ用ページのデバッグを仮想Android端末を使ってホストPCのChromeから行うを含むブックマーク スマホ用ページのデバッグを仮想Android端末を使ってホストPCのChromeから行うのブックマークコメント

スマホ用のWebサイトを作成しているとき、Androidでの表示をテストするのに、実機で行うか、eclipseに入れたAndroid仮想デバイスから行っていました。


しかしAndroid仮想デバイスは遅いし起動も時間が掛かるのでもうちょいマシなエミュレータがないか、と思っていたところ、Genymotionというエミュレータがあることがわかりました。

超高速なAndroidエミュレータ「Genymotion」を試す | TeraDas−テラダス


Genymotion

個人利用ならば無料で利用できます。

商用利用だと月24.99ユーロ(約3400円)なので結構高いかも。


Genymotionをインストールしたばかりだと仮想マシンがないため、「Add」からターゲットとなる端末、例えば「Google Nexus 5 - 5.1.0」などを選択して作成し、起動します。

最初は言語が標準で英語になっているため、「Settings」から「Language&input」を選択し「Language」で「日本語」を選択すると日本語表示になります。


GenymotionはそのままだとGoogle Playストアが入っていないため、ARM TranslationとGoogle Playストア本体(gapps)を入れることでGoogle Playも使えるようになります。

手順は上記サイトにも書いてあるのですが


1. [GUIDE] Genymotion | Installing ARM Translat… | Android Development and Hacking | XDA Forums より「ARM Translation Installer v1.1」をダウンロード

2. ダウンロードした「Genymotion-ARM-Translation_v1.1.zip」を、Genymotion上の仮想Android上にドラッグアンドドロップ

3. 仮想Andriodを再起動

4. Google Apps (Gapps) - Download Latest Gapps for Android などから、例えば仮想Androidのバージョンが5.1の場合「gapps-lp-20150314-signed.zip」をダウンロード

5. ダウンロードした「gapps-lp-20150314-signed.zip」を、Genymotion上の仮想Android上にドラッグアンドドロップ

6. 仮想Andriodを再起動

7. 途中開発者サービスが停止とか起こるが「OK」で進めて良い


これでPlayストアからChromeなどのブラウザを入れて、ページの確認ができるようになります。


このままでもページの確認は出来るのですが、リモートデバッグを使うとPCのChromeデベロッパーツールと同等のことが出来るようになるので、次は仮想Androidに対してリモートデバッグが出来るようにします。


1. PlayストアからChromeインストールする

2. 「Dev Settings」から「USBデバッグ」をチェックする

3. ホストPCでChromeを起動して「chrome://inspect」にアクセスする

4. Devicesの「Descover USB devices」にチェックが入っていると仮想Androidのリストが出てくる

5. 該当仮想Androidの「inspect」を開く


これでPCのChromeに仮想と同じページと開発用の情報が表示されるようになります。


リモートデバッグについては下記Chromeのページに詳細があります。

Remote Debugging on Android with Chrome - Google Chrome

ひろりんひろりん 2015/08/25 00:43 一時期ネットに接続していない状態で、その時に東芝Dynabook M200の某ファイルが必要という連絡をいただいておりました。

今でも必要でしょうか。
まだ該当PCは手元のありますので、提供は可能です。
Blogへのコメントでも構いませんので、ご連絡いただければと思います。

stealthinustealthinu 2015/08/25 13:40 ありがとうございます。
その後M200にはネットワークブートを使ってUbuntuを入れることで復活させたのですが、最近はほぼ起動していない状況です。
ペンが使えるマシンはうちではこれだけなので、またアップデートしてお絵かき専用機として復活させたいところです。

トラックバック - http://d.hatena.ne.jp/stealthinu/20150811

2015-08-03 (Mon)

[]vagrantなどで自動構築したテスト環境VMに複数ホスト名でアクセスする vagrantなどで自動構築したテスト環境VMに複数ホスト名でアクセスするを含むブックマーク vagrantなどで自動構築したテスト環境VMに複数ホスト名でアクセスするのブックマークコメント

vagrant+ansibleでCentOS6のテスト環境を自動構築するものを作っているのですが、その環境でvirtualホストの設定をしている場合に、複数のホスト名で接続できるようにしたい、と考えました。


テスト環境でやる場合、avahi(Bonjour)を使って名前解決をさせるのが一番お手軽で、Windowsからも「Bonjour Print Services」を入れれば利用できます。

WindowsからVMware上のLinuxへBonjour使ってサーバ名で接続する - モーグルとカバとパウダーの日記


しかし、avahi-daemonはそのままだと1つのホスト名しかサービスしてくれません。

ただ、avahi-daemonを複数ホスト名に対応できるようなスクリプトがあり、それを使うと複数名での接続が出来るようになります。


…と書いてますが、最初airtonix/avahi-aliasesを導入しようとしたもののなかなか出来ず、

からの一連のリプライでやっと出来るようになったわけですが…


まず、avahi-daemonを動かすように設定します。

avahi-daemonはmessagebus(dbus)というものが必要で、先にこちらのデーモンを動かしておく必要があります。実は複数ホスト名に対応する機能を後付するためにもこの機能が利用されているようです。

$ sudo yum install avahi
$ sudo service messagebus start
$ sudo service avahi-daemon start

複数ホスト名を使えるようにするために下記スクリプトを利用しました。

Register a mDNS/DNS-SD alias name for your computer using the Avahi daemon

またこのスクリプトを使うためにpython-avahiというライブラリが必要になるのですが、それはavahi-ui-toolsに含まれているため、それも入れてやります。

$ sudo yum install avahi-ui-tools
$ git clone https://gist.github.com/3168336.git
$ chmod +x 3168336/avahi-alias.py
$ sudo cp 3168336/avahi-alias.py /usr/local/bin/

設定と起動はシンプルに「/etc/rc.local」に下記行を追加して行いました。

/usr/local/bin/avahi-alias.py hoge1.local hoge2.local &

この例だと、サーバ名の他に「hoge1.local」「hoge2.local」もaliasとして使えるようになります。


Macの場合は最初からBonjourが入っているため、なにもしなくても使えます。


WindowsからBonjourを使えるようにするには、Appleの提供しているBonjourのサービスをインストールします。

Bonjour Print Services for Windows v2.0.2

Bonjour Print Servicesとなっていますが、Printだけでなく普通にBonjourのサービス情報取得が行えます。

Petit Tech: Linuxでのmdns(avahi/Bonjour)による名前解決。」によるとiTunesをインストールすることでも利用できるようになるそうです。


これでホスト名が「hoge」で、alias設定が上記の例だと「hoge.local」と「hoge1.local」「hoge2.local」の名前でアクセスできるようになります。

トラックバック - http://d.hatena.ne.jp/stealthinu/20150803

2015-07-31 (Fri)

[]ansibleの動作条件と確認方法 ansibleの動作条件と確認方法を含むブックマーク ansibleの動作条件と確認方法のブックマークコメント

ansibleの良い所は、動作するのにクライアント環境にsshで繋がってpythonが動けば良いだけ、というところです。


が、なんか環境によって動かなかったりすることがあります。

確認すべき点をまとめてみました。


まず基本ですが、sshで接続できるか確認します。

接続できるなら、リモート環境のコマンドが実行出来るかを確認します。


$ ssh foo@example.com hostname
www.example.com

自分は、sshで接続できるのにリモートのコマンドが実行できず、調べてみたらログインシェルが /etc/shells に書かれていなかったため、それでエラーになって実行できなくなっていました。


コマンドが実行できてもダメな場合があります。

実は ansible はデフォルトの設定だと sftp の接続も出来ないといけないようです。



CentOS5や6ではデフォルトで sftp が使えないようになっているため、問題がなければ


/etc/ssh/sshd_conf

Subsystem       sftp    /usr/libexec/openssh/sftp-server

にコメントを外してsshd再起動してやれば良いです。


ただ、なにかの理由で sftp は使わないようにしたい場合、下記のエントリーを参考に


「SFTP disableなCentOS環境でansibleを使う」

http://tagomoris.hatenablog.com/entry/20140318/1395118495


ansibleを動かすディレクトリ


ansible.cfg

[defaults]
transport=ssh

[ssh_connection]
ssh_args=
scp_if_ssh=True

と設定すれば動きました。

トラックバック - http://d.hatena.ne.jp/stealthinu/20150731

2015-07-28 (Tue)

[]vagrant+ansibleなどでテスト環境の構築自動化する場合のsshキーペアの扱い vagrant+ansibleなどでテスト環境の構築自動化する場合のsshキーペアの扱いを含むブックマーク vagrant+ansibleなどでテスト環境の構築自動化する場合のsshキーペアの扱いのブックマークコメント

について、リプライいただいたことをまとめました。


CMSで動いているproduction環境に、機能追加やテスト等を行うために、vagrant+ansibleで開発環境を構築する設定を書いていました。

ホストPC上にvagrantでVMが生成され、ansibleでapachetomcatCMS等の組み込みと設定を行い、production環境から現在のデータやファイルをコピーしてきて、ほとんどミラーに近い環境を構築します。


このとき、データベースや追加されたファイルなどを取ってくる処理を、production環境上でダンプやtarしたものをfetchで一度ホストPCに持ってきて、それをVM上に展開するという処理にしていました。

しかし、転送が二度手間になっていて時間もかかるため、例えばファイルについてはsynchronize(rsync)など使ってVM上から直接productionサーバの内容を最新のものに合わせたいと思いました。

ただそうするには、VMからproduction環境に接続するためのsshキーペアの設定が必要になります。

そこでVMにホストPCの秘密鍵をansibleで突っ込んでやればいいだろう、と思ったのですが、それはセキュリティ的にはやっぱ良くないよな…と思って書いたのが冒頭のツイートでした。


それでこの件に対し @_hito_ さんから色々アドバイスをいただきました。

で、後から見直すと下記2ツイートにまとまっちゃうのですが、最初はイマイチピンと理解できず…

何件か質問して噛み砕いて説明していただきました _o_


元々自分が考えていたのは、ホストPCとproduction環境の間で通常使うための鍵ペアをそのまま使い、VM秘密鍵を送り込んで接続するイメージでした。

しかしこれだと、その開発環境のVMが侵害された場合、ホストの秘密鍵が漏れてしまいます。


そこで、データコピー専用の鍵ペアを作って、それの公開鍵をproduction環境に入れておきます。

vagrantで生成したVMには、そのデータコピー専用の秘密鍵を入れてやります。

この下記ペアはデータコピー専用のものなので、もしどこかのVMが侵害されて秘密鍵が漏れても、入れる場所は結局コピー元のところだけなので、それは使いまわしても良いわけです。

トラックバック - http://d.hatena.ne.jp/stealthinu/20150728

2015-07-02 (Thu)

[]MSYS2のgitgithubからcloneしようとしてSSL証明書の問題でエラーになる MSYS2のgitでgithubからcloneしようとしてSSL証明書の問題でエラーになるを含むブックマーク MSYS2のgitでgithubからcloneしようとしてSSL証明書の問題でエラーになるのブックマークコメント

とある原稿を共同で書くために、githubのプライベートリポジトリを使って、そこにcommitしてこうということになりました。

んで、作ってもらった場所からやっとこさcloneしようとしたのですが。

fatal: unable to access 'https://github.com/…': error setting certificate verify locations:

CAfile: /usr/ssl/certs/ca-bundle.crt

CApath: none

とか言われまして。


自分はWindows8.1でSourceTreeを利用していますが、内蔵のgitではなくMSYS2を入れてそのgitを使っています。

この問題は結構よくある話しらしく、色々と出てくるのですがこちらが参考になりました。


Githubの証明書問題をまっとうに解決する - Limitの日記

http://d.hatena.ne.jp/limitusus/20120529/1338306372


自分の場合、MSYS2のgitの証明書を新しくすればよいので、MSYS2のターミナルから

% cd /usr/ssl/certs
% curl http://curl.haxx.se/ca/cacert.pem -o ca-bundle.crt

として新しいCA証明書を入れてやることで解決しました。

トラックバック - http://d.hatena.ne.jp/stealthinu/20150702

2015-06-02 (Tue)

[]JavaでWebフォームに入力された内容を文字化けせずにメールで送る JavaでWebフォームに入力された内容を文字化けせずにメールで送るを含むブックマーク JavaでWebフォームに入力された内容を文字化けせずにメールで送るのブックマークコメント

Webでフォームに入力された内容をメールでどこかに送る、というのはすごくありふれた内容だと思います。

が、Javaで普通に書くと、いろんな理由で文字化けが発生してしまいます。

一番よくあるのがUTF-8→JIS(ISO-2022-JP)に変換するときに、変換できなくて「?」になってしまうというやつです。


そこで、文字化けが起きないように事前にいくつかフィルタを掛けてやる必要があるのですが、あまりまとまった情報がなくて困ったのでまとめてみました。


大きく下記3種のフィルタを掛けることで対応しました。

  • 波ダッシュやハイフン
  • IBM-UnicodeMS-Unicodeの違い(「¢」や「£」など)
  • HTMLエンティティ(「<」のようなもの)

波ダッシュ問題はとても有名ですが、その上UTF-8には色んな波ダッシュやハイフンがあり、一つに対応してあっても他ので化けたりします。

どうしたもんかと思っていたら、下記ページに波ダッシュやハイフンの各文字コードでの対応状況がまとめられており、大変に参考になりました。

また、変換コードもありましたので、そこに追加する形で他の化ける文字の対応をおこないました。

Unicodeの似た文字を整理してみた - y-kawazの日記


他にもIBM-UnicodeMS-Unicodeの違いにより化けてしまうという問題があります。

これで化けるものは、波ダッシュの他に「¢」や「£」などがあります。下記のページを参考にしました。

UTF-8での文字化け - mokkouyou2001の日記

perlでメール送信時の いわゆる波ダッシュ「〜」問題 | clicktx::Tech::Memo


また、接続環境なのかクライアントによってなのか、フォームに入力された記号のいくつかが、例えば「-」が「−」のように、HTMLエンティティに変換されて送られてくる場合があるようです。

これはどういった場合に、どの記号が変換されるのかということが調べきれなかったため、全てのHTMLエンティティを変換することにしました。

これには StringEscapeUtils クラスの unescapeHtml4 を利用しました。


これらをまとめたものが以下のコードです。

/**
 * HTMLエスケープ文字、UTF8→JISへの変換で化ける文字、を変換する
 * @param str
 * @return 変換された文字列を全て戻した文字列
 */
public String unescapeForMail(String str) {
  String result = str;
  result = StringEscapeUtils.unescapeHtml4(result);
  result = normalizeSimilarCharacter(result, "iso-2022-jp");
  return result;
}

/**
 * 文字化けの原因になる文字を、文字化けない文字に置換します。
 * http://d.hatena.ne.jp/y-kawaz/20101112/1289554290
 * http://perl.no-tubo.net/2011/01/12/perl%E3%81%A7%E3%83%A1%E3%83%BC%E3%83%AB%E9%80%81%E4%BF%A1%E6%99%82%E3%81%AE-%E3%81%84%E3%82%8F%E3%82%86%E3%82%8B%E6%B3%A2%E3%83%80%E3%83%83%E3%82%B7%E3%83%A5%E3%80%8C%E3%80%9C%E3%80%8D%E5%95%8F/
 * @param str
 * @param encoding 外部出力予定の文字コード(この値により置換テーブルが代わります)
 * @return
 */
public static String normalizeSimilarCharacter(String str, String encoding) {
    if(str == null || encoding == null) {
        return str;
    }
    encoding = encoding.toLowerCase();
    if("windows-31j".equals(encoding)) {
        return StringUtils.replaceEach(str, SIMILAR_CHARS_W31J_FROM, SIMILAR_CHARS_W31J_TO);
    } else if("shift_jis".equals(encoding)) {
        return StringUtils.replaceEach(str, SIMILAR_CHARS_SJIS_FROM, SIMILAR_CHARS_SJIS_TO);
    } else if("euc-jp".equals(encoding)) {
        return StringUtils.replaceEach(str, SIMILAR_CHARS_EUCJP_FROM, SIMILAR_CHARS_EUCJP_TO);
    } else if("iso-2022-jp".equals(encoding)) {
        return StringUtils.replaceEach(str, SIMILAR_CHARS_ISO2022JP_FROM, SIMILAR_CHARS_ISO2022JP_TO);
    }
    return str;
}

//共通置換テーブル
private static final String[] SIMILAR_CHARS_COMMON_FROM = new String[]{
    "\u00AD", "\u2011", "\u2012", "\u2013", "\u2043", "\uFE63", //半角ハイフン
    "\u223C", "\u223E", //半角波線→半角チルダ
    "\u22EF", //3点
    "\u00B7", "\u2022", "\u2219", "\u22C5", //半角中点
    "\u2225", "\uffe0", "\uffe1", "\uffe2"  // ‖ ¢ £ ¬
};
private static final String[] SIMILAR_CHARS_COMMON_TO = new String[]{
    "\u002D", "\u002D", "\u002D", "\u002D", "\u002D", "\u002D", //半角ハイフン
    "\u007E", "\u007E", //半角波線→半角チルダ
    "\u2026", //3点
    "\uFF65", "\uFF65", "\uFF65", "\uFF65", //半角中点
    "\u2016", "\u00a2", "\u00a3", "\u00ac"  // ‖ ¢ £ ¬
};
//エンコーディング別置換テーブル
private static final String[] SIMILAR_CHARS_SJIS_FROM;
private static final String[] SIMILAR_CHARS_SJIS_TO;
private static final String[] SIMILAR_CHARS_W31J_FROM;
private static final String[] SIMILAR_CHARS_W31J_TO;
private static final String[] SIMILAR_CHARS_EUCJP_FROM;
private static final String[] SIMILAR_CHARS_EUCJP_TO;
private static final String[] SIMILAR_CHARS_ISO2022JP_FROM;
private static final String[] SIMILAR_CHARS_ISO2022JP_TO;
static {
    SIMILAR_CHARS_SJIS_FROM = (String[]) ArrayUtils.addAll(SIMILAR_CHARS_COMMON_FROM, new String[]{
        "\uFF0D"/*全角マイナス*/, "\u00AF"/*長音符号*/, "\u2015"/*強調引用*/, "\u3030", "\uFF5E"/*波線*/
    });
    SIMILAR_CHARS_SJIS_TO = (String[]) ArrayUtils.addAll(SIMILAR_CHARS_COMMON_TO, new String[]{
        "\u2212"/*全角マイナス*/, "\uFFE3"/*長音符号*/, "\u2014"/*強調引用*/, "\u301C", "\u301C"/*波線*/
    });
    SIMILAR_CHARS_W31J_FROM = (String[]) ArrayUtils.addAll(SIMILAR_CHARS_COMMON_FROM, new String[]{
        "\u2212"/*全角マイナス*/, "\u2014"/*強調引用*/, "\u3030", "\u301C"/*波線*/
    });
    SIMILAR_CHARS_W31J_TO = (String[]) ArrayUtils.addAll(SIMILAR_CHARS_COMMON_TO, new String[]{
        "\uFF0D"/*全角マイナス*/, "\u2015"/*強調引用*/, "\uFF5E", "\uFF5E"/*波線*/
    });
    SIMILAR_CHARS_EUCJP_FROM = (String[]) ArrayUtils.addAll(SIMILAR_CHARS_COMMON_FROM, new String[]{
        "\uFF0D"/*全角マイナス*/, "\u2015"/*強調引用*/, "\u3030"/*波線*/
    });
    SIMILAR_CHARS_EUCJP_TO = (String[]) ArrayUtils.addAll(SIMILAR_CHARS_COMMON_TO, new String[]{
        "\u2212"/*全角マイナス*/, "\u2014"/*強調引用*/, "\uFF5E"/*波線*/
    });
    SIMILAR_CHARS_ISO2022JP_FROM = (String[]) ArrayUtils.addAll(SIMILAR_CHARS_COMMON_FROM, new String[]{
        "\uFF0D"/*全角マイナス*/, "\u00AF"/*長音符号*/, "\u2015"/*強調引用*/, "\u3030", "\uFF5E"/*波線*/
    });
    SIMILAR_CHARS_ISO2022JP_TO = (String[]) ArrayUtils.addAll(SIMILAR_CHARS_COMMON_TO, new String[]{
        "\u2212"/*全角マイナス*/, "\uFFE3"/*長音符号*/, "\u2014"/*強調引用*/, "\u301C", "\u301C"/*波線*/
    });
}
トラックバック - http://d.hatena.ne.jp/stealthinu/20150602