2015年12月27日日曜日

備忘録 Java正規表現の否定後読みでエスケープ文字をパース

プロパティ的に文字列を解析し、キーとバリューに分けるとする。

区切り文字に、空白、=、:の連続を用いるが、それらをキーに含めたい場合は\でエスケープできることにする。

というルールで1行を2つに分けるためのパターン。 ↓

String[] en = ln.split("(?<!\\\\)[\\s=:]+", 2);

これでたぶん、平気かと思われる。

キーに含まれる\はエスケープ文字なので消したいが、\自体をキーに含めたい場合は\\とすればよいことにする。

en[0].replaceAll("(?<!\\\\)\\\\", "")

こんな。


「否定の後読み」 という用語が何とも気持ち悪いが、要は、検査していった進行方向に対して後ろ(つまり文字列の手前)に対してパターンで条件指定を追加し、かつそれを「不一致なら一致」とする、ということか。・・・よけいにわからない感じだな。

テスト↓
public class Main {
public static void main(String[] args) {
_test("aa bb");
_test("aa  bb cc");
_test("aa = bb cc");
_test("aa\\ \\=bb cc");
_test("\\\\100=$1");
}
static void _test(String in){
String[] en = in.split("(?<!\\\\)[\\s=:]+", 2);
System.out.println(en[0].replaceAll("(?<!\\\\)\\\\", ""));
System.out.println("--> " + en[1]);
}
}

結果↓
aa
--> bb
aa
--> bb cc
aa
--> bb cc
aa =bb
--> cc
\100
--> $1
 たぶん出来るよね?

2015年12月19日土曜日

Windows環境でのシンボリックリンク

c:/d/fooというディレクトリを参照するリンクFOOを作成したいとき。

コマンドプロンプトを管理者権限で起動し、

> mklink FOO c:/d/foo

これで、カレントディレクトリに、c:/d/fooを参照するFOOが出来る。


管理者権限がなくてもコマンドのヘルプなどは見えるが、実行するとエラーになる(リンクを作る権限がないっぽい。どこであれ。)


自分は、Eclipse+Java+Tomcatなので、設定的に参照したいファイルをアプリ本体とは別に管理しておきつつ、稼働させているローカル環境に配置するのに使っている。(設定ファイルを本体と一緒に管理したくないけど、管理はしたいので。本体と設定ファイルを別々のプロジェクト(Git的にも)にしておいて、動かすところではリンクでつなげている)

2015年12月17日木曜日

JavaScriptで、文字列に含まれる全角の数字を半角に変換する



こんな風にすれば、


"123".replace(/[0-9]/g,function(s){return String.fromCharCode(s.charCodeAt(0) - 65248)});


123になる。


「65248」は、Unicodeの文字の並びにおける全角数字と半角数字の位置の差で、


"1".charCodeAt(0) - "1".charCodeAt(0);

このようにして求めることが出来る。


同様のやり方で、英字やひらがな→カタカナなども可能だろう。

2015年8月5日水曜日

Webpage Screenshotとか言うとんだ食わせモノ

アドウェアにやられました・・・。

Web開発者を生業にしていて情けない気もしますが、先日開発に勤しんでいたら、とつぜんわけのわからない胡散臭いページ(※1)が表示されまして。開いていたタブは開発中のローカルPCでのサイトで、広告リンクなどもあるわけないので、うっかり何かクリックしたとしても外部のサイトが開くということはちょっと起こりにくく、これはおかしいと思ったところが始まり。

 ※1 killa4.com とかいう極めて詐欺臭いサイトです。英語と日本語が混じったサイトでしたが、中国のものらしいです。

それから注意してみると、わりと頻繁に「Jollywallet」という広告バーが表示されており、考えてみればこれもおかしいなと。

Jollywalletは悪質なアドウェアですが、そういったものをダウンロードした覚えもないし(たいがいの人はそうでしょうが、私も一応専門家?の端くれなので、注意しているつもりです)、今のところCromeでだけ問題が起きている、となると・・・と怪しいのが1つあるな、と思ったらビンゴでした。


これ↓

http://blogs.yahoo.co.jp/fireflyframer/33388558.html


このWebpage Screenshotというのを入れてました。
これが、Jollywalletはじめ各種の不正な機能を内蔵していたようです。


開発中の画面を客に少しだけ見せるため、スクロールキャプチャが必要だったときに、入れてしまったのですね。

わりと大手のサイトでも堂々と宣伝されてましたし、使ってる人も多いようだったので大丈夫だろうと思って入れたものの、思いがけずキャプチャがWebに公開されてしかも消せない機能があったりと、怪しい機能満載だったので、1枚撮ったきり使っていなかったのですが、削除はしてませんでした。


それでもずっと悪さはしていないようだった(してないというかうまく動作してなかったのか)のが、先日にChromeを64ビット版にアップデートしたのがもしかして良くなかったのかも知れません。かえってうまく動くようになってしまったとか。

Chrome自体を一度アンインストールしてから再度入れ直し、拡張機能も何もない状態になってからは、不審な挙動はないので、たぶん除去できたようです。

一応、ほかの情報も見て、C:\Program Files (x86)の中だとかレジストリとか、実行中のプロセスとかも見てましたが、異常のものは見合ってませんし。


Googleはセキュリティにうるさいことも言うくせにこういうところがたまに杜撰だからイマイチ信用できません・・・。(他所で作られたものだとしても、普通に配布してるという時点で)

私はこういうのが嫌なので、ブラウザの機能拡張なんかはほぼ入れませんが、キャプチャだけはどうしても必要になることがあり、いつも「うさんくせー」と思いながらアドオンを入れてたのですが、そういう人は少なくないと思うので、スクロールキャプチャ機能くらい最初からつけておいて欲しいものだと思います・・・。

もっとも、最近はキャプチャは諦めて、全体ならPDFで保存したり、部分なら普通の(ブラウザじゃない)キャプチャツールを使ったりしてます。

あーやだやだ。

インターネッツは怖ろしい・・・。

2015年7月16日木曜日

エアコンの冷房と除湿の機能的な違いについて誰も教えてくれない。

・・・まあ、少なくとも10分弱ネットを眺めた範囲では、誰も教えてくれない。

今日は梅雨も盛りの雨で、部屋の中はちょっと蒸し暑くかなりジメジメしている。こういう場合に冷房と除湿のどちらを使うべきか悩み、検索してみたのだが。

まっさきに出てきたダイキンのホームページ

http://www.daikin.co.jp/naze/html/a_4.html

ここでは、結露がどうとかそういう説明。要は飽和水蒸気量の話だろ?そんなことは義務教育で習ったから知っている。俺が知りたいのはそんな半端な原理説明ではなく、エアコンの機能としてどうなのかという話だ。

このダイキンの説明、丁寧なのだがひどいなと思ったがのが、さんざん原理の説明をしておいて、結局うるる君だっけ?のコメントは

  • 弱冷房(じゃくれいぼう)除湿は弱い冷房(れいぼう)と同じなんだね


あれ?普通にテキストをコピーしたのに。まあ、引用ということでいいや。

で、このコメントね、つまり、「同じなのかよ!?」っていうね。

いや、違うでしょ?わざわざボタンつけてるし、実際うちのエアコンだって冷房中に「除湿」ボタン押したら「ウイーーーーーン」って動作音があるし。除湿が空気を冷却していて、冷却する原理が冷房と弱冷房除湿で同じだというのは言われなくても誰でもわかると思うのだが、わざわざこうしてホームページまで調べに行くのだから、そういうことじゃなくてさ。エアコンは機能として冷房と除湿で何を切り替えているのかが知りたいのよ。


ところが、他にヒットした日立のページを見ても似たようなものだし、さらにアフィリサイトっぽい数々の情報ブログ?も結局はメーカーサイトの説明のコピペ切り貼りばかりなので、ちっとも知りたいことがわからない。


・・・俺の期待としては、冷房の場合の方が外気との交換が多くて、除湿の場合は室内で空気を循環させてるとかさ。センサーの働き方が変わるとか。なんかそういう仕組みでもあるのではないかと思ったのに。・・・ないのかね?本当に。ないってことは無いと思うんだけどなあ。

2015年7月9日木曜日

またWikipediaの募金週刊がはじまった・・・

オープンソースとかコミュニティとかのすばらしさを語り、ポジティブで意識が高く自己研鑽を欠かさず、謙虚さと少しの健康的傲慢さを兼ね備え、オシャレなカフェでオシャレなブログを更新できるようなステキなエンジニアに俺もなれたらなあ、と思いつつも、クローズドなのが大好きで新技術の追求が死ぬほど面倒くさく、新しいガジェットとか手法とか見るたび「勝手にやってろよ、どうせバズワードだろ?」と切り捨てる感じで根暗なエンジニアを続けている俺だけど、まあWikipediaは非常にお世話になってるから・・・700円だけ寄付しておいた。

これで俺もWeb2.0の人だな!

2015年7月7日火曜日

ApacheのVirtualHostでSSLを使う設定(なるべく簡単に)

そもそもVirtualHost自体、自分で設定したことは今に至るまでなかったのだが・・・(一応、20年ばかりエンジニアとして給料もらってるのだけどw)。

最近なんでも自分でやらないといけなくて、近々そういう設定も使いそうだしということで、少し前にお名前ドットコムで180円で買っておいたドメイン名を使い、VirtualHostと検索して出てきたApacheのページで設定し、しめしめと思ったらSSLのページが繋がらん。接続エラーだとか何だとか。

ということで、Proxy系で何とかしようとしたり、あれこれ考えたけど結局素直にググって、適当にやってみた。

まあ、わりといくつかのページがあったのだけど、自分としてはともかく肝だけ押さえたいので、メモっておく。

設定の手順

 NameVirtualHost *:80
 NameVirtualHost *:443

 <VirtualHost *:80>
  何か設定
 </VirtualHost>
 <VirtualHost *:443>
 SSLEngine on
 SSLCertificateFile /etc/httpd/ssl/server.crt
 SSLCertificateKeyFile /etc/httpd/ssl/server.key
 何か設定(80のと同じことを書いたり)
 </VirtualHost>

それでApache再起動。NameVirtualHostは、要素をかくためのおまじないなので、実際、SSLを使うからという点での特殊な記述は、"on"にすることと、鍵ファイルの指定のみということになるから、これ以上は減らせないと思う。試してないけど。


なお、その前にSSLを使っていたssl.conf側の記述とかはそのまま放置しても今のところ害になってる気配はないのでそのまま放置してみる。

80と443で本来の設定部分は同じことを書いてるのだが、これ何とかならんのだろうか・・・。まあ、何行かしかないのでたいしたことじゃないのだけど・・・。

VirtualHost要素が入れ子とかに出来たらいいのに。

2015年7月6日月曜日

BitBucketにローカルのGitから最初のソースをコミットする

GitHubは自分にはオシャレ過ぎるのでBitBucketを使っています。
そもそもGitに慣れていないせいもあり、最初にソースをコミットするのがいつも悩むのでメモです。


まず自分のPCにローカルリポジトリを作る


  1. (自分はJavaでEclipseなので)、プロジェクト右クリック→Team->Share Project
  2. 出来上がったリポジトリの中の.gitignoreをメモ帳で編集し、/.settings/とかその辺を追加
  3. ソース(先にIDEで何か作ってたとする)をコミット

BitBucketにリポジトリを作る

  1. ログインして、メニューから普通に作る。言語はJavaにしておく。

初プッシュ

  1. BitBucketで作ったプロジェクトが空だと、ソース見る画面などに手順が表示されている。これに従うといつもハマるのであまり信用しない。
  2. ローカル側のGit Bashで操作する(Git純正?のツールをWindowsに入れてある)
  3. git remote add origin https://USERNAME@bitbucket.org/USERNAME/PROJECTID.git
    1. USERNAMEはBitBucketのユーザー名。もともとログインしたURLにも含まれている文字列。
    2. BitBucketの画面だとgit@bitbucket.org.USERNAME/PROJECTID.gitになってる
    3. が、これだといつも認証がないと怒られる。HTTPSにしておくと、必要な時にはパスワード聞かれる。HTTPSじゃない場合は確かSSHで、BitBucketのどこかにそのための設定方法などもあった気がするが面倒だった気がするし何だか忘れた。
  4. git push -u origin --all
    1. オプションの意味はよく知らないがプッシュする。
    2. これ以降、EclipseのGitツールでもこのoriginにプッシュできる(最初からEclipseで設定することも出来たとは思う。)


後はEclipseの機能がたまにパスワードを忘れた時に聞きなおされるくらい。

2015年6月30日火曜日

大発見。仕事しながらハニーローストピーナッツを食う方法。

プログラムを書くなんてことを仕事にしている人は、たいがい夜型人間で、真夜中あたりに調子が出てきたりということも多々あると思います。

ちょっと小腹が空いたりして、でもやはりこういう場合、スカした健康食みたいなものではなくて、ジャンクな何かをつまみながら、安いコーヒーか、炭酸飲料、もし許される状況なら軽いアルコールなどを啜りながら無心にコーディングするのが乙なものです。

そんなわけで、私はしばしば「STRIKE EAGLE  ハニーローストピーナッツ」というのを食べながら仕事をすることがあります。これ自体は実はカルディなどのちょっと小洒落た食材店で売ってることが多いのですが、F15ストライクイーグルをパッケージにデザインしてしまう頭の悪そうな感じ(どうせ創業者が元パイロットとかなんではないかと想像)と、軽い蜂蜜風味に塩分控えめとかそういうくだらないことは一切考えない高濃度の塩が、なかなか美味いのです。

ただ、豆が調味料で非常に粉っぽくなっており、食べると指がベタベタになるのでタイピングに支障をきたすのが問題でした。ティッシュ片手に拭きながらやるのですが、粉というのはティッシュでは拭き取りにくく、始末が悪い。

ところが昨日、デスク上を見渡してはたと閃いて試した方法がこれです。

手に塩がつかない!

正方形のポストイットを使ってるのですが、こいつを1枚、半分に折るとちょうどいい感じのスプーンになりました。一度に豆が3〜4粒ほどすくえます。

口に入れる時は紙を舐めないように流し込みます。で、食べ終わったらポストイットは丸めて捨てます。非常に衛生的であり、使い捨て食器の中ではトップクラスに低コストだと思われます。

仕事中以外では、ポストイットが手元にないのでわざわざこうする必要はないのですが、仕事中ならポストイットはたいがいあるので、便利な方法となります。


みなさんも是非、お試しください。

2015年6月25日木曜日

数字を3桁で区切るのが愚かしいというバカバカしい話

金額を書くとき、1,000,000みたいに3桁ずつカンマを打つじゃないですか。

ちょっと作ってたプログラムにユーティリティ関数を用意してやろうと思って、文字列の"1000"を"1,000"に変換するのを作ったのです。で、名前をつけようとして、はて、こういうの何て言うんだろう?と思いまして。

tri-ナントカ、とか、気の利いた単語があるのではと思って検索したら、「日本語は4桁ずつ(万、億、兆・・・)で区切るのに、英語の表記に毒されて3桁で区切るのはわかりにくいし、英語にあこがれて思考停止する愚かな行為だ、的な雰囲気の話がいくつも見当たりました。

検索結果のプレビュー程度しか見てないのでいちいちどこのブログだとか言わないけど、わりと多くの人が思いつくネタのようでぱっと見ていくつもの記事が見当たったので、特定の誰かの意見というよりは、まあある程度一般的な意見(一部ではあるけど稀ではない)ということでいいかなと思います。書いてる本人は目から鱗の有難い話と思っているかどうかは別に知らないけど・・・。

で、思うに、すげえどうでもいいですね。こういう話。どうでもいいから気にしなきゃいいんだけど、あまりにバカバカしくてつい。

数字の書き方なんかでナショナリズムを主張するこたないと思うのです。つうか、そこまで言うなら「10,000ではなく1,0000とすべきだ」ではなく「一万とすべきだ」と言えばいいじゃない。

アラビア数字を使って発展した科学の成果の恩恵に生まれてから死ぬまで24時間365日もれなく与って暮らし、その最たるものであるインターネッツなどで言論人を気取りながら、「日本語がー」とかってのは・・・まあ、昔の酔っ払い頑固親父の薀蓄話みたいで何ともくだらないな、と思いました。ネットなんてやってないで自分の家族か飲み友達にでも語ってりゃいいのに。

だいたい、「実は3桁区切りは英語の表記(thousand, million, billion..)には良くなじむ」みたいな話も書いてあったりするのだけど、実はもクソもないというか、そんなことは並の勉強をした中学生以上なら誰でも知ってるけど当然過ぎるのでイチイチ何かの発見かのように言ったりはしない、という類のことであって・・・。まあ、どうでもいいのですかね。

ちなみに、3桁区切りはthousand separatorと言うとWeblioには出てたけど、それじゃ長いので関数は単に"digit"という名前にしました。あんまり処理内容を表してないのだけど、数字に使うということはわかるだろうし、まあ、ともかく利用場面を考えると短い名前であることが優先だったので。

2015年6月11日木曜日

AWS S3にAWS SDK (Java)でファイルを送る

表題の通り。

SDK自体は、Gradleのbuild.gradleに
 runtime 'com.amazonaws:aws-java-sdk-iam:1.9.39'
 runtime 'com.amazonaws:aws-java-sdk-s3:1.9.40'
と書いて取得。SDK全部なら1行で済むが、1行で済んで楽なのは書いてる人だけで、ほぼ使わない100MB以上のファイルをいちいち取得したりビルドさせたりというのはコンピュータが可哀想と感じます。

ファイル送るのはこんなで出来た。


public void store(File file){
final String accessKey = "XXXXXXXXXXXXXXXX";
final String secretKey = "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy";
AmazonS3 s3 = new AmazonS3Client(new BasicAWSCredentials(accessKey, secretKey));
s3.putObject("sampleBucketName", file.getName(), file);
}

ポイントとして、

  1. IAMでユーザーを作って、acceccKeyとsecretKeyを払い出しておく
  2. バケットのアクセス 権限(バケットポリシー)で、ユーザーにアクセス許可しておく(今回は特定バケットを特定ユーザーに許可したかった)
    1. バケットポリシーの編集は、手でやる場合にインデントに全角空白があったりするとJSONパースエラーになる(くだらないが、AWSの画面では空白見えないので一瞬はまった。エディタにコピーした方がいいな)
    2. Principalに、IAMのURIを指定する(複数の場合、{"AWS":["uri 1","uri2"]}。たぶん)

2015年6月4日木曜日

MacBook AirでSafariが起動しない件

数日前から、自分のMacBook AirのSafariがうんともすんとも言わない。

Safari 起動しない とかで検索すると、iOSの話がよく出てきて、設定アプリからリセットしろとか書いてあるが、何せ俺はYosemiteなので。そしてSafariは落ちるとかじゃなくて、そもそもアイコンをクリックしてもぴょんぴょんすらしないので、リセットも出来ない。

困ったなあ、なんて検索していたら

 ~/Library/Preferenecs/com.apple.Safari.plist
 ~/Library/Caches/com.apple.Safari

を削除すればいい的な話を見かけたので、ターミナルを開きrm -rfなんかしてガツっと削除してやった。

するとどうだろう!

やっぱり全然起動しない!

ちなみにゲストユーザでも起動しない。どうしたものか。

と、そこでふとOSを再起動してみたら、治りました。めでたしめでたし。

* ファイル削除前にも再起動はしたけど、それではダメだった。削除→再起動で治ったみたい。

2015年5月29日金曜日

Amazon SESのバウンスをSNSで受けてSQSに渡しアプリで拾うまで

Webアプリを作っていたら、メールサーバがないことに気付いた。以前の会社では誰ぞに「メールサーバはどれを使えばいいですか?」と聞いておけば出来てたのに。

頭来たので適当にSMTPサーバ?今もSedMailとかでいいの?を立てようかと思ったのは一瞬で、スパム対策が進んだ昨今、10年前のように適当にサーバを設置してパカパカ送ってたら問題になるというか止められるだろう、と。

そう思って、Amazon SESを使ってみようと思ったが、バウンスメールを出すと止められるから嫌だと上司に言われた・・・が、SESでなきゃISPに止められたりするのであって結局どこを使うのであってもバウンス対策は必要。

バウンス対策ごと丸投げできるメール配信サービスは、今回の自分のようにメールテンプレートに大量の変数を使うような場面ではキツい気がするし。

ということで、SESでバウンス対策だけはある程度やってみるという覚悟を決め、ある程度試してみた作業ログ。


※ 適当にググっていろいろ見た結果を適当に混ぜてやった感じなので、まともに調べてる方は他所を見た方が正確だと思われます。


準備

  1.  送り元になるアドレスを最初に登録して、Verifyしないといけない。(登録アドレスに送られてきたメールをクリックする)
  2.  これでとりあえず登録アドレスから登録アドレス向けにだけメールが送れる。
    1.  このアドレスでは不達のテストとかは不可能。なので、テストアドレスがある。 (ドキュメンテーション Eメール送信のテスト) http://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/mailbox-simulator.html

バウンス 


  1. バウンスはAmazon SNSで受け取る。
  2. SESのコンソールのEmail Addresses、アドレスを選択して上部からView Detailsを選ぶ。さらにNotrificationsを開き、さらにボタンを押すと通知の設定ができる
  3. Topicを作る的リンクが地味にあるのでそれを押してTopicを生成する→SESのリージョンでSNSのTopicが出来てる
    1.  AWSのダッシュボードで別途に作っておいたTopicは選択できなかった。なんぞ?→リージョンが違った。SESのリージョンに合わせないとダメ
  4.  Amazon SNSのダッシュボードに移動、Subscriptionsで、バウンス発生時のアクションを決める。仮にEメールにしてみた。設定したアドレスに購読Verifyメールが来るのでOKする。
  5. bounce@でテストメールを送る(SESコンソールから)
  6. バウンス情報がJSONになってメール来た



が、メールじゃバウンスを処理できない。・・・こともないが、やりにくい。こちらのシステムもずっと動いているわけじゃないので、IMAPで取ってきて「まだ見てないの」を開封してみて・・・というあたりが面倒になりそう。


そこで、Amazon SQSを使う。

Amazon SQSでSNSメッセージを受け取る設定


  1. Amazon SQSで、キューを作る。名前は"SESBounce"とか。
  2. SNSのサブスクリプションにエンドポイントをSQSにしたのを作り、さきほどのキューを指定。
  3. ところがバウンス来ない。
  4. キューのダッシュボードに戻り、作成済みのキューに「キュー操作」ボタンでSNSのサブスクリプションを設定
  5. SESからbounce@にテストメールを送ると、キューに1つタスクがたまった



キューからタスクを取り出さなくてはならない。これはバッチで良い気がする。

Amazon SDKを使う。

「gradle aws sdk」とかググってMavenリポジトリに行き、IDを取得、GradleでSDKをインポート。zipでも100MB超。デカい!

SDKでSQSに接続する


  1. まず、認証情報が必要。AWSコンソールのIAM(Identity and Access Management )を開き、左「ユーザー」メニューで新規ユーザー追加。名前だけ入れる。と生成され、アクセスキーとシークレットキーが出てくる。
  2.  このキーを使ってAPIで接続できるが、作ったユーザーには何の権限もないので接続拒否される。IAMのユーザー設定画面で「ポリシーのアタッチ」をして利用する機能を許可する。
  3. 次のようなコードを書いて実行する。


まあ、センスのないコードだが手順的なものとして・・・。

注意:なぜか、キー"Message"の値のJSONがわざわざエスケープして文字列にしてあるので、一度文字列として取り出してから再度JSONとしてパースしている。その中のJSONはそのままだったりするのに不思議だ。

static void testQue(){
final String accessKey = "XXXXXXXXXXXXXXX";
final String secretKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxx";
AmazonSQSClient sqsc = new AmazonSQSClient(new BasicAWSCredentials(accessKey, secretKey));
//ReceiveするとSQS上のメッセージがデフォルト30秒、他からロックされる
//SQSのコンソールで確認できるキューのURL
ReceiveMessageResult receiveMessage = sqsc.receiveMessage("https://sqs.us-east-1.amazonaws.com/yyyyyyyyyyyyy/SESBounce");
receiveMessage.getMessages().forEach((msg)->{
System.out.println("=======================================");
String body = msg.getBody();
JSON json = JSON.of(body);
System.out.println("Bounced:");
try{
JSON message = JSON.of(json.getPlainString("Message"));
for(JSON bnc : message.getJSON("bounce").getJSONs("bouncedRecipients")){
System.out.println("emailAddress : " + bnc.getString("emailAddress"));
System.out.println("status : " + bnc.getString("status"));
System.out.println("diagnosticCode : " + bnc.getString("diagnosticCode"));
}
//message.getJSONs("bouncedRecipients").forEach((bnc)->System.out.println(bnc.getString("emailAddress")));
}catch(Exception ig){
ig.printStackTrace();
}
System.out.println("=======================================");
});
}

実行したらコンソールにバウンスしたアドレスと理由が出た。ここまでくれば、後はこれをリストにしておいてメール送らないようにすればいいのだろう、と。


AWSってなんだか面白い気もしてきた。

Webアプリケーションからのメール送信につかうMTA

MTA?というかメール送信サービスというか。メルマガシステムが作りたい、というわけではないが、普通にメール送信もあるWebアプリケーションを作りたいので、何かが必要だし、いきなり送れなくなるとかは困る。かつ、メール送信自体が要件というわけでもないので手間も知恵もコストもかけたくない。

で、どうしたらいいのかと考えている。


サーバ立てる云々じゃなくGmailを使うというのはお手軽。だが、本来、普通に使うためのアカウントなので・・・

  • Gmailのアカウントは、 1アカウントで1日500件までしか送れないらしい
    • メッセージ数ではなく宛先数。CCに500件入れたりしたら1発でアウトということ
  • 年間6000円で、特定のアカウントに対して上限を2000件に引き上げ可能

ソースは↓
http://d.hatena.ne.jp/mitaina/20100205/1265366858



Amazon EC2にサーバを立てるという手がある。が、

  • ISPのスパム対策に引っかからないためには、ただSMTPサーバを置けばいいというものではない
    • おもにDNS関連を含む各種設定が必要(DNSにも)
    • バウンスメール対策をしておかないといけない
こういうことは、俺のようにコンピュータが苦手な人間にはつらい。


そこで、Amazon SESを使うという手がある。が、
  • DKIM設定をしないと、メールに「amazonses経由」 と出てくる
    • Amazon Route53を使っていれば簡単らしい
  • バウンスが多かったりすると、Amazonに止められる


メールが500件/日に達するほどでもないなら、Gmailでいい気がする。なにせ簡単。つうか開発的なことは何もない(送信処理を作る以外は)。

EC2はハードルが高い。なにせ俺はかつてネットワークスペシャリストの資格を受験して落ちたほどの男だ。DNSと聞いただけで震えがくる。

Amazon SESは、バウンスのせいで止められるのが心配。しかし、よく考えるに、バウンスを出してばっかりいたら止められるのはどこでも一緒だし、その対策を講じないというのではさながらスパマーなわけだ。

だとすると、やはりAmazon SESを使うのが良い気がしてきた。

2015年4月3日金曜日

オブジェクト指向におけるモデリングのアンチパターン

「このXXXは、YYYとしても使える」というようなのを作らない。


・・・こうネガティブなコンテキストで書くと、誰だってそんなことしないと言うだろうし、俺だってそう思ってるわけですが、いざコーディングしている時にふと、「おお!このオブジェクト(プロパティ、変数、なんでも)を使ってこんなこともできるのでは!まさに一石二鳥!」とか思ってノリノリになってたりするものです。少なくとも私はそうです。

が、一人二役とか一石二鳥とか考えるということは、すでに異なる2種類の何かがあるのが明解なのだから、それらはやはり別に設計しておくべきなんだと思います。たとえ、その時点の簡単な実装では同じに見えるオブジェクトでも、いずれは別の役割と振る舞いを持つんだろうと。

2015年3月2日月曜日

checkboxでチェックされてない場合は"false"とか送ってほしい

 、という場合のスクリプト。なんかもっと簡単な手はないのかね?単純なことを無駄に面倒にやってる気がして仕方ない・・・。
      <label>
        <input type="checkbox" name="dummy" class="checkbox-boolean" data-input-cls="foo-remove"> <span class="glyphicon glyphicon-trash"></span> Remove
        <input type="hidden" name="XXX" class="foo-remove form-control" value="false">
      </label>



 <script type="text/javascript">
    $(".checkbox-boolean").change(function(){
        var cb = $(this);
        $("." + cb.attr("data-input-cls"), cb.parent("label")).val(cb.prop("checked") ? "true" : "false");
    });
 </script>


※ jQuery、Bootstrap使用の状態。・・・もうちょっと状況を制限すればhiddenをクラスで指定することもないのか。

2015年2月18日水曜日

JSPのコンパイル時に非常に奇妙なエラーが出る

This static method of interface XXX can only be accessed as XXX
というような例外メッセージになる。

例えば、XXXインターフェースにyyyメソッドがあり、それをJSPでXXX.yyyと呼び出した場合。
その通りやってんだろうがよ!と怒りたくなる。つうか腹たつなもう。

解決策は、Tomcatのweb.xml、


<servlet>
        <servlet-name>jsp</servlet-name>
        <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
        <init-param>
            <param-name>fork</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>xpoweredBy</param-name>
            <param-value>false</param-value>
        </init-param>
  <!-- こっから -->
  <init-param>
      <param-name>compilerSourceVM</param-name>
      <param-value>1.8</param-value>
  </init-param>
  <init-param>
      <param-name>compilerTargetVM</param-name>
      <param-value>1.8</param-value>
  </init-param>
  <!-- ここまで -->
        <load-on-startup>3</load-on-startup>
</servlet>


「こっからここまで」を足したら直った。けど、今までEclipse上のTomcatでは1.7の指定で(JREは1.8だった)大丈夫だったのが解せない。1.7の指定が効いていなかったワケではなく、ちゃんとラムダとかはコンパイルエラーになってたのに。なんなんだ。


参考:
http://stackoverflow.com/questions/25360127/intstream-strange-error

2015年2月6日金曜日

クロスドメインでAjax、なおかつセッション情報も利用するなら・・・

クロスドメインでAjaxを使うのには、レスポンスヘッダーに

Access-Control-Allow-Origin:http://allowed-origin.test

てな感じで許可をつけてやらねばならないというのは前に書いた。

このオリジンというのはポート番号まででパスは不要、というか、リクエストヘッダーのOriginとして送られてきたものを(許可できるなら)戻すのが本筋のようだ。


で、自分がやりたいのは自サイト内部のHTTPからHTTPSへのクロスなのであり、そんなことをしたい理由はもちろん認証情報の取得だ。つまり、Cookieがいる。

が、クロスサイトなAjaxを上記で許可した場合、通信自体は許可されるが諸々の制限がついていて、Cookie、それからX-の拡張ヘッダ類は送られない。

受け取っていいヘッダを、


Access-Control-Allow-Headers:X-Foo,X-Bar

てな感じで書いてやらねばならない。これがないと、jQueryなんかがつけてくれるX-Requested-Withヘッダーなんかもつかない。


Cookieも送りたいので上記にCookieと書けばいいかというと、それではだめで、Cookieを送るには、XMLHttpRequestにwithCredentialプロパティをtrueで設定しないとならない。Cookieは認証に使われるからか、特別扱いなわけかね。

で、これを具体的に行う方法が、たとえばjQueryでは、こうなる。


jqTargetなるjQueryオブジェクトが、取得したコンテンツをロードしたい対象だとしたら、

$.ajax({
url: loadUrl,
xhrFields: {
withCredentials: true
}
}).done(function(data){
jqTarget.html(data);
});


通常なら、jqTarget.load(loadUrl);で終わるところだが。

(オリジンを許可してない場合、どっちにしろつながりもしない。この場合、ChromeのデバッガではOPTIONメソッドの履歴が残り、利用できる応答がないとかそういうことになってる。OPTIONなって使ってねーよ!と思うが、これはプリフライトと呼ばれる、クロスドメインのXMLHttpでのネゴシエート的なものの結果のようだ)




参考:

  • https://developer.mozilla.org/ja/docs/HTTP_access_control
  • http://dev.classmethod.jp/etc/about-cors/

2015年2月5日木曜日

クロスドメインのAjaxだとX-Requested-Withてついてくれないんですか?

そもそもこのヘッダ、なんでついてるのかもよく確認せず使ってましたが、jQueryがつけてくれてるだけなんですね。

で、自分の作ってたサイトで、http -> httpsでAjaxを使いたいのでAccess-Control-Allow-Originを使って通信したところ、X-Requested-Withがついてこないもので、これを見ていた自前のサーバーサイド検査 request.isXmlHTTP()が引っかかってしまった。

ただ、そもそもサーバーサイドの処理がjQueryに依存しているというのはおかしな感じがしていやだし、他にも微妙な問題がありそうなんで、Ajaxかどうか?の検査にはこのヘッダーを見るのではない代案を考えようと思う。

どうせ偽装可能なヘッダ情報なんだから、Refererとかでもいいのか・・・それとも、そもそもこんな検査にこだわらない(セキュリティの一助になればという思いだったが、もっと別の手を考える)方がいいのか・・・。

PHPって怖ろしいんだな・・・

http://d.hatena.ne.jp/ockeghem/20110905/p1

・・・こんなことがあるなんて。ちゃんとした出版社から出てる教科書なのに・・・。

って、まあ、このレベルをPHP開発者全員に当てはめたら怒られるんだろうけど。それに、JavaScriptの非同期通信を使った部分のセキュリティ確保については自分もよくわからないところが多く、それでアレコレ検索してたらこういうページにたどり着いたんだしね。

他人を笑えるほどわかってはいないか、俺も。まあ、だから俺は本は書いてないけど。

2015年1月10日土曜日

クロスドメインでAJAXをするにはAccess-Control-Allow-Origin

タイトルだけで書きたいことが終わってしまった。

さみしいからもう一度書こう。

クロスドメインでAjaxするには、HTTPヘッダーにAccecc-Control-Allow-Originで許可ドメインを指定する(プロトコルから)。

JSONPはセキュリティ上の危うさを感じるし何か無理矢理な感じがして好きになれない。ので、これを使おう。使おうと思っただけでまだ使ってないから細かいことは書けない。

まあ、やりたいことは、自前のWebアプリ内でHTTPSで応答するJSONをHTTPのページから普通に使いたいだけである。