2016年8月26日金曜日
mysqldump
2016年8月23日火曜日
JavaからJavaScriptを実行したときのパラメータ受け渡し
パラメータをひとつづつ渡す
パラメータを渡すにはScriptEngineのputメソッドにJavaScriptでの変数名を指定する。
JavaScript側では通常の変数として利用できる。
try {
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine e = factory.getEngineByName("js");
e.put("a", "hello");
e.put("b", "world");
String script = "ab=a + ' ' +b;";
Object ret = e.eval(script);
Bindings b = e.getBindings(ScriptContext.ENGINE_SCOPE);
for(String key : b.keySet()) {
Object v= b.get(key);
System.out.println("key=" + key + "; value=" + v + " (" + v.getClass() + ")");
}
} catch (ScriptException ex) {
ex.printStackTrace();
}
実行結果
key=a; value=hello (class java.lang.String) key=b; value=world (class java.lang.String) key=ab; value=hello world (class java.lang.String)
retには最後に実行した式の結果が入る。ここではabの値と同じ。 パラメータをMapで渡す
Mapで渡したパラメータはJavaScript側ではオブジェクトのプロパティとして使用できる。
try {
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine e = factory.getEngineByName("js");
Map<String, Object> map = new HashMap();
map.put("x", "hello");
map.put("y", "world");
e.put("map", map);
String script = "x = map.x; xy=map.x+' '+map.y;";
Object ret = e.eval(script);
Bindings b = e.getBindings(ScriptContext.ENGINE_SCOPE);
for(String key : b.keySet()) {
Object v= b.get(key);
System.out.println("key=" + key + "; value=" + v + " (" + v.getClass() + ")");
}
} catch (ScriptException ex) {
ex.printStackTrace();
}
実行結果
key=map; value={x=hello, y=world} (class java.util.HashMap)
key=x; value=hello (class java.lang.String)
key=xy; value=hello world (class java.lang.String)
パラメータをListで渡す
Listで渡したパラメータはJavaScript側では配列として使用できる。
try {
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine e = factory.getEngineByName("js");
List<String> list = new ArrayList();
list.add("Tokyo");
list.add("Nagoya");
list.add("Osaka");
e.put("list", list);
String script = "list0=list[0]; list1=list[1]; list2=list[2]; length=list.size();";
Object ret = e.eval(script);
Bindings b = e.getBindings(ScriptContext.ENGINE_SCOPE);
for(String key : b.keySet()) {
Object v= b.get(key);
System.out.println("key=" + key + "; value=" + v + " (" + v.getClass() + ")");
}
} catch (ScriptException ex) {
ex.printStackTrace();
}
実行結果
key=list; value=[Tokyo, Nagoya, Osaka] (class java.util.ArrayList) key=list0; value=Tokyo (class java.lang.String) key=list1; value=Nagoya (class java.lang.String) key=list2; value=Osaka (class java.lang.String) key=length; value=3 (class java.lang.Integer)
Listの要素にMapを渡すこともできる。
try {
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine e = factory.getEngineByName("js");
List<Map<String, Object>> list = new ArrayList();
Map<String, Object> map1 = new HashMap();
map1.put("v1", 100);
map1.put("v2", 200);
map1.put("v3", 300);
lista.add(map1);
Map map2 = new HashMap();
map2.put("v1", 110);
map2.put("v2", 210);
map2.put("v3", 310);
lista.add(map2);
e.put("list", list);
String script = "list0_v1=lista[0].v1; list1_v1=lista[1].v1;";
Object ret = e.eval(script);
Bindings b = e.getBindings(ScriptContext.ENGINE_SCOPE);
for(String key : b.keySet()) {
Object v= b.get(key);
System.out.println("key=" + key + "; value=" + v + " (" + v.getClass() + ")");
}
} catch (ScriptException ex) {
ex.printStackTrace();
}
実行結果
key=list; value=[{v1=100, v2=200, v3=300}, {v1=110, v2=210, v3=310}] (class java.util.ArrayList)
key=list0_v1; value=100 (class java.lang.Integer)
key=list1_v1; value=110 (class java.lang.Integer)
2016年7月22日金曜日
BAT バッチファイルで今日の日付を取得
C:> echo %DATE%
2016/07/20
たとえばバッチファイル中で今日の日付のファイル名やフォルダを作りたいときはYYYYMMDD形式のほうが望ましいため、以下のように整形をすることができる。
C:> set TODAY=%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%
C:> echo %TODAY%
20160720
今はもう使う機会もほとんどないが、Windows 2000以前だと%DATE%の書式が違っており同じ値を取得するには以下のようにする。
set TODAY=%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%
どの環境でもYYYYMMDD形式で取得できるようにするには次のようにOSのバージョンで場合分けする。
for /f "tokens=1-3" %%i in ('ver') do set OSVER=%%k
if "%OSVER%"=="2000" (
set TODAY=%date:~2,4%%date:~7,2%%date:~10,2%
) else (
set TODAY=%date:~0,4%%date:~5,2%%date:~8,2%
)
2016年7月19日火曜日
JavaMail と AmazonSESでメールを送る
Amazon SES を使うためには Amazon Web Service(AWS) のアカウントを持っている必要がある。 (アカウントの取り方は省略する)
EC2をすでに利用していれたので同じアカウントで利用することができた。Amazon SES のためには最低限、以下の設定が必要である。
- メールアドレスの登録
送信元(From)およびテスト用の送信先(To)のメールアドレスの設定および承認をする。 - SMTP設定
SMTPサーバーにアクセスするための認証情報などを設定する。
1. メールアドレスの登録
送信元(From)とするメールアドレスの設定および承認をする。 また、サービス利用直後はsandboxモードというあらかじめ登録されたメールアドレスにしか送れないモードとなっているが、この送信先(To)のメールアドレスも同じように登録する。
メールアドレスは以下の手順で登録する。送信元(From)、送信先(To)のアドレスをそれぞれ登録する。
- Management Consoleのメニュー"Email Addresses"を選択
- [Verify a New Email Address]を押す。ダイアログボックスに送信元とするメールアドレスを入れる。
- 入力したメールアドレスに "Amazon SES Address Verification Request"というメールが来る。その中のリンクをクリック。
- 「Amazon Simple Email Service(Amazon SES)でのメールアドレスの検証が完了しました。このアドレスからのメール送信を開始できます。」というページが開く。
- 登録完了
2. SMTP設定
SMTPサーバーにアクセスするための認証情報などを設定する。
- Management Consoleのメニュー"SMTP Settings"を選択
- [Create My SMTP Credentials]を押す
- "IAM User Name" を要求される。既定の値をそのまま使い [Create] を押す。
- 認証情報が生成される。[Show User SMTP Security Credentials]を押すと以下のような内容が表示される。
ses-smtp-user.xxxx-xxxx SMTP Username: xxxxxxxxxxxxxxx SMTP Password: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
SMTP Username と SMTP Password は後で使うのでメモしておく。
ここまでできたらAmazon SESでメール送信することができるすることができる。 早速、JavaMailを使いJavaプログラムからメールを送信してみよう。 SMTPサーバーはポート25か465か587が使えるので、自分の環境にあったものを選べばよいかと思う。 自分のローカルPCから送る場合は、プロバイダの方でポート25を制限していることが多いと思うのでそれ以外を選ぶのがいいだろう。 また、Transport Layer Security (TLS)が必要なのでJavaMailのほうでその設定をする。
以下のサンプルプログラムはAmazon SESのリファレンスガイドに載っていたものとほぼ同じである。 ビルドしてローカルPCで動かすと1で登録したメールアドレスにメールが配信される。
package test;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
public class AmazonSESTest {
// 1で登録したメールアドレス
static final String FROM = "xxx@xxx.jp";
static final String TO = "yyy@yyy.jp";
// 2で作成したSMTP Username/Passwordを設定
static final String SMTP_USERNAME = "xxxxxxxx";
static final String SMTP_PASSWORD = "xxxxxxxxxxxxxxxxxx";
// Amazon SES SMTP ホスト名
static final String HOST = "email-smtp.us-east-1.amazonaws.com";
// ポートは25,465または587を指定する
static final int PORT = 587;
private static Logger logger = Logger.getLogger(AmazonSESTest.class.getName());
public static void main(String[] args) {
try {
AmazonSESTest app = new AmazonSESTest();
app.start(args);
} catch (Throwable ex) {
logger.log(Level.SEVERE, "エラーが発生: " + ex.toString(), ex);
}
}
private void start(String[] args) throws MessagingException {
// JavaMailの設定
Properties props = System.getProperties();
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.port", PORT);
// JavaMailでTransport Layer Security (TLS)を使う設定
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.starttls.required", "true");
// JavaMail Session 作成
Session session = Session.getDefaultInstance(props);
// 送信メッセージを作成
MimeMessage msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(FROM));
msg.setRecipient(Message.RecipientType.TO, new InternetAddress(TO));
msg.setSubject("テストメール", "utf-8");
msg.setContent("AmazonSESから出したメール", "text/plain;charset=utf-8");
// メール送信
Transport transport = session.getTransport();
try {
logger.info("Amazon SES SMTP で送信中...");
transport.connect(HOST, SMTP_USERNAME, SMTP_PASSWORD);
transport.sendMessage(msg, msg.getAllRecipients());
logger.info("送信完了");
} finally {
// 後始末
transport.close();
}
}
}
最後に、Amazon SESでは個別の申請をしない場合には以下のような利用制限があるようである。 後者はproduction版を申請すれば解除されるようだが、それはまた後日試してみることにする。
- 送信できるメール数、200メール/日、1メール/秒
- 登録済みのメールアドレスにしか送信できない(sandboxモード)
2016年7月11日月曜日
2016年6月15日水曜日
BATファイル CSVの読み込み
品目,単価,個数
りんご,98,10
みかん,30,20
キウイ,78,30
このCSVを読み込んで表示するバッチは以下のようになる。
for /f "skip=1 tokens=1,2,3* delims=," %%i in (data.csv) do (
echo 品目=%%i 単価=%%j 個数=%%k
)
このバッチはCSVファイルdata.csvを開き各行をを順次for文で処理する。
for文にオプションskip=1 を付け1行目のヘッダ行は無視するようにする。
また、列が3つあるのでtokens=1,2,3*を指定している。このとき読み込んだ列はそれぞれ変数%%i, %%j, %%kに入る。for文に指定しているのは%%iだけだが、forの仕様としてi,j,k...のアルファベット順の変数に列の値が自動で入る。
列の区切り文字はdelims=, オプションで指定する。
このバッチで先のCSVファイルを読み込むと次のような感じになる。
C:\Temp>readcsv.bat
品目=りんご 単価=98 個数=10
品目=みかん 単価=30 個数=20
品目=キウイ 単価=78 個数=30
データ中にカンマが入っているとそこが区切りと認識されるのでこの方法ではうまく動かないが、 簡単にCSVファイルを処理したい場合は十分役立つのではと思う。