だましだまし

そういう生き方 メモ用として使っていく

FreeMarkerでテンプレートの評価をしたくない時

FreeMarkerが好きでちょくちょく使っているがjqueryのtemplateも"${}"これを採用していて、FreeMarkerが評価しようとして盛大に死ぬことがある。
で、そういう時はnoparseっていう構文を使えばいい。

<#noparse>
var markup = "<li><b>${Name}</b> (${ReleaseYear})</li>";
</#noparse>

これでnoparseで囲んだところは無視される。
マニュアルはこちら

AWS S3にputする時に最初の「/」はいらないっていう話

AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
AmazonS3 s3 = new AmazonS3Client(credentials);
   中略
s3.putObject(bucketName, s3FilePath, new File(localFilePath));

なんかこんな感じでputする時にs3FilePathに「/application/data/hoge.txt」という値を入れると、見事にS3のバケットに空フォルダが作成された。
指定するパスを「application/data/hoge.txt」にしたらバケット直下にapplicationディレクトリ(正確にはディレクトリじゃないけど)ができた。
またハマると嫌なのでメモ。

FireFox で入れてるアドオン一覧

メモ用に書いてみる

Add Bookmark Here
Edit Cookies
DNS Flusher
Firebug
FireGestures
FireMobileSimulator
RESTClient
Tab Mix Plus
Tamper Data
User Agent Switcher
テキストリンク

並べてみると大して使ってないな。
あと Walnut for Firefox ってテーマ入れてる。
タグの一括編集用のアドオンとかないのかなー、昔あったけど今のバージョンに対応してないんだよなあ。

firefoxのバージョンを22にしたらテキストサイズやら何やらが大きくなった件

メニューの文字とかタブの文字とかまででかくなってなんの嫌がらせかと思ったけど、高DPI環境だとこうなるよっていう風に公式が悪びれず抜かしてるので、とりあえず自分でどうにかするしかなさそう。
about:configからlayout.css.devPixelsPerPxの値を変更することで一応小さくすることは出来たが、微妙に違和感ある。てか小さすぎる。
これは海外の方々は既にブチ切れて何かしら対処をしてらっしゃるだろうとの予測をたててググってみたら案の定あった。
Firefox 22 font is huge!!!! • mozillaZine Forums
これの一番最後のレスをそのままやってみたら、違和感無くなった。

  1. アドレスバーに「about:config」を入力してEnter
  2. layout.css.devPixelsPerPxを検索
  3. 値を「1.0」に変更
  4. アドオン「Theme Font & Size Changer」をインストール
  5. フォントサイズを14に変更

素晴らしい。

デプロイメント・アセンブリー

昨日からeclipseのkepler使い始めてて、かついつもどおりpleiadesのall in oneをインストールした。
それでwebプロジェクトで、「Deployment Assembly」を探したんだけどどこにもない。
もうフィルタに「assembly」とか突っ込んでもなんの応答もない。
フォーラムにバグ報告してやろうかと思ったところ掲題の「デプロイメント・アセンブリー」を発見した。
もう日本語化やめようかな。

jsonicのlistだけを持つクラスを使いたくない場合

jsonicの話。
まず下記みたいなjsonが欲しいっていうとき

{"data":[{"id":"001","name":"bean001"},{"id":"002","name":"bean002"}]}

この場合まずbeanクラスを用意する
TestJSONBean.java

public class TestJSONBean {
	public String id;
	public String name;
}

で、ここまでは良いとして、このあとによく下記のようなクラスをサンプルとかで見かける。
TestJSONData.java

import java.util.List;

public class TestJSONData {
	public List<TestJSONBean> data;
}

これにプラスでメンバにIDとかある奴もあったりしてそれなら分かるんだけど、少なくともこのクラスはあんまり作りたくないなと思う。
なんかこのクラスの存在自体が美しくないっていうか、なので回避策ないかなーって思ったら割りとあっさり出来た。
まずこの上記のクラスを素直に使った場合のencode・decode。

@Test
public void jsonic001() {
	TestJSONData jsonData = new TestJSONData();
	List<TestJSONBean> list = new ArrayList<>();
	TestJSONBean bean001 = new TestJSONBean();
	bean001.id = "001";
	bean001.name = "bean001";
	TestJSONBean bean002 = new TestJSONBean();
	bean002.id = "002";
	bean002.name = "bean002";
	list.add(bean001);
	list.add(bean002);
	jsonData.data = list;
	String jsonString = JSON.encode(jsonData);
	System.out.println("encode→" + jsonString);
	jsonData = JSON.decode(jsonString, TestJSONData.class);
	jsonString = JSON.encode(jsonData);
	System.out.println("decode→encode→" + jsonString);
}

「え? なにそのテストコード見づらい……」っていう苦情には答えられない。
で、これの結果が下記。

encode→{"data":[{"id":"001","name":"bean001"},{"id":"002","name":"bean002"}]}
decode→encode→{"data":[{"id":"001","name":"bean001"},{"id":"002","name":"bean002"}]}

当然期待通りの動作をする。
で、回避策としてMapにしてみようとしたコードが次の通り。

@Test
public void jsonic002() {
	List<TestJSONBean> list = new ArrayList<>();
	TestJSONBean bean001 = new TestJSONBean();
	bean001.id = "001";
	bean001.name = "bean001";
	TestJSONBean bean002 = new TestJSONBean();
	bean002.id = "002";
	bean002.name = "bean002";
	list.add(bean001);
	list.add(bean002);
	Map<String, List<TestJSONBean>> map = new HashMap<>();
	map.put("data", list);
	String jsonString = JSON.encode(map);
	System.out.println("encode→" + jsonString);
	map = JSON.decode(jsonString);
	jsonString = JSON.encode(map);
	System.out.println("decode→encode→" + jsonString);
	System.out.println("map.get(\"data\"):" + map.get("data").toString());
}

結果

encode→{"data":[{"id":"001","name":"bean001"},{"id":"002","name":"bean002"}]}
decode→encode→{"data":[{"id":"001","name":"bean001"},{"id":"002","name":"bean002"}]}
map.get("data"):[{id=001, name=bean001}, {id=002, name=bean002}]

期待通りの動作になった。
どうしてもTestJSONData.javaみたいなクラスを作りたくないっていう人はこれでやるのもいいかも。
「いや、そもそもjsonic遅いから使ってねーよ」っていう人はなぜここまでこの記事読んだのかを聞きたい。
jacksonの方が遥かに速いのは間違いないけども。

Spring AOPで引数を分解して取得したい

今回はSpringの話。ヒステリックブルーの「春~spring~」の話ではなく、frameworkの方のSpring。
引数をargsで全部取得してtoStringでログに出すみたいなサンプルは山ほどあったんだけど、引数をまとめずに一つ一つ取得するサンプルが少なかったのでメモ。

まずpom.xmlのdependenciesに以下を追加。

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-aop</artifactId>
	<version>3.2.3.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.aspectj</groupId>
	<artifactId>aspectjrt</artifactId>
	<version>1.7.2</version>
</dependency>
<dependency>
	<groupId>org.aspectj</groupId>
	<artifactId>aspectjweaver</artifactId>
	<version>1.7.2</version>
</dependency>

全部現時点の最新版にしといた。

で、aopされる側のインターフェースとクラスを作成

TestService.java

package nets.service;

public interface TestService {
	public void execute(String hoge, Integer foo);
}

TestServiceImpl.java

package nets.service;

public class TestServiceImpl implements TestService {

	@Override
	public void execute(String hoge, Integer foo) {
		System.out.println("service impl hoge=" + hoge + ", foo=" + foo);
	}

}

次にaopするクラスを作成

ServiceAspect.java

package nets.aspects;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class ServiceAspect {

	@Pointcut("execution(* nets.service.TestService.execute(..))")
	public void serviceExecution() {
	}

	@Before(value = "serviceExecution() && args(arg0, arg1)")
	public void beforeExecution(JoinPoint joinpoint, String arg0, Integer arg1) throws Throwable {
		System.out.println("before hoge arg0=" + arg0 + ", foo arg1=" + arg1);
	}
}

applicationContext.xmlに下記を追加。aopスキーマ部分は省略。

<aop:aspectj-autoproxy proxy-target-class="false"  />
<bean class="nets.service.TestServiceImpl" />
<bean class="nets.aspects.ServiceAspect" />

で、実際に下記のコードで動かしてみた

@Test
public void aop() {
	try (ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("config/applicationContext.xml")) {
		TestService sut = context.getBean(TestService.class);
		sut.execute("hoge", 128);
	}
}

実行結果はこちら

before hoge arg0=hoge, foo arg1=128
service impl hoge=hoge, foo=128

いけてる。
なんとなくどっちもprototypeにしてやってみる。

<bean class="nets.service.TestServiceImpl" scope="prototype" />
<bean class="nets.aspects.ServiceAspect" scope="prototype" />

結果は省略するが、これも上手く動いた。

エンジニアの強い味方であるstackoverflowにそのものズバリのサンプルが載ってたんだけど、その通り書くのもあれだから下記みたいに最初書いたら動かなくてハマった。

@Aspect
public class ServiceAspect {

	@Pointcut("execution(* nets.service.TestService.execute(..))")
	public void execution() {
	}

	@Before(value = "execution() && args(arg0, arg1)")
	public void beforeExecution(JoinPoint joinpoint, String arg0, Integer arg1) throws Throwable {
		System.out.println("before hoge arg0=" + arg0 + ", foo arg1=" + arg1);
	}
}

こう書くと@Beforeの方の読み込み時に

Pointcut is not well-formed: expecting 'name pattern' at character position 10
execution() && args(arg0, arg1)

みたいなエラーが出る。結論から言うと対象のメソッドの名前を"execution"にしてるのが原因だった。
内部的に既に使用している名称だからそこは変えないとダメってことらしい。