Hatena::ブログ(Diary)

tanamonの日記

2009-12-08

[][]WicketJSONデータを返却する(JSONIC編)

追記:

コメントいただきまして、バージョン1.2.0で以下の問題点

Mavenリポジトリ公開されることと、ISO8601形式の出力指定ができれば僕の用途的には完璧。

の両方に対応していました。ステキすぎる!


mavenの指定

JSONICMavenリポジトリが公開されていないので、まずはローカルリポジトリに登録する

mvn install:install-file -Dfile=jsonic-1.1.2.jar -DgroupId=net.arnx -DartifactId=jsonic -Dversion=1.1.2 -Dpackaging=jar -DgeneratePom=true

あるいは、Maven2でテキトウに社内リポジトリを作る方法 - tanamonの日記に従ってテキトウに社内リポジトリに登録します。

登録したらpom.xmlに追記します。

<dependency>
	<groupId>net.arnx</groupId>
	<artifactId>jsonic</artifactId>
	<version>1.1.2</version>
</dependency>

JsonicPage.java

package jp.tanamon.wicket;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import net.arnx.jsonic.JSON;
import net.arnx.jsonic.JSONHint;

import org.apache.commons.lang.time.DateUtils;
import org.apache.wicket.IRequestTarget;
import org.apache.wicket.RequestCycle;
import org.apache.wicket.markup.html.WebPage;

public class JsonicPage extends WebPage {
	public JsonicPage() {

		getRequestCycle().setRequestTarget(new IRequestTarget() {

			public void detach(RequestCycle requestCycle) {
				// nothing to do here
			}

			public void respond(RequestCycle requestCycle) {
				requestCycle.getResponse().setContentType("application/json; charset=utf-8");

				List<JsonData> list = new ArrayList<JsonData>();
				list.add(new JsonData("All Day Event", new Date(), null));
				list.add(new JsonData("Long Event", DateUtils.setDays(new Date(), 2), DateUtils.setDays(new Date(), 10)));

				// POJO to JSON-String
				requestCycle.getResponse().write(JSON.encode(list, true));
			}
		});
	}

	public class JsonData {
		private static final String ISO8601_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss+09:00";

		public String title;

		@JSONHint(format = ISO8601_DATE_FORMAT)
		public Date start;

		@JSONHint(format = ISO8601_DATE_FORMAT)
		public Date end;

		public JsonData(String title, Date start, Date end) {
			this.title = title;
			this.start = start;
			this.end = end;
		}
	}
}

出力内容

[
	{
		"end": null,
		"start": "2009-12-08T11:06:18+09:00",
		"title": "All Day Event"
	},
	{
		"end": "2009-12-10T11:06:18+09:00",
		"start": "2009-12-02T11:06:18+09:00",
		"title": "Long Event"
	}
]

メモ


結局、json-libとJSONICのどっちがいいの?

JSONICのほうが優しさがある。

Mavenリポジトリ公開されることと、ISO8601形式の出力指定ができれば僕の用途的には完璧。

[][]WicketJSONデータを返却する(json-lib編)

mavenの指定

<dependency>
	<groupId>net.sf.json-lib</groupId>
	<artifactId>json-lib</artifactId>
	<version>2.3</version>
	<classifier>jdk15</classifier>
</dependency>
<dependency>
	<groupId>commons-lang</groupId>
	<artifactId>commons-lang</artifactId>
	<version>2.4</version>
</dependency>

json-libではclassifierを忘れずに。

あと、DateクラスをISO8601形式の文字列に変換するためにcommons-langも使ってます。


JsonLibPage.java

package jp.tanamon.wicket;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import net.sf.json.JSONArray;
import net.sf.json.JsonConfig;
import net.sf.json.processors.JsonValueProcessor;

import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.wicket.IRequestTarget;
import org.apache.wicket.RequestCycle;
import org.apache.wicket.markup.html.WebPage;

public class JsonLibPage extends WebPage {
	public JsonLibPage() {

		getRequestCycle().setRequestTarget(new IRequestTarget() {

			public void detach(RequestCycle requestCycle) {
				// nothing to do here
			}

			public void respond(RequestCycle requestCycle) {
				requestCycle.getResponse().setContentType("application/json; charset=utf-8");

				List<JsonData> list = new ArrayList<JsonData>();
				list.add(new JsonData("All Day Event", new Date(), null));
				list.add(new JsonData("Long Event", DateUtils.setDays(new Date(), 2), DateUtils.setDays(new Date(), 10)));

				// POJO to JsonObject
				JsonConfig config = new JsonConfig();
				config.registerJsonValueProcessor(java.util.Date.class, new DateJsonValueProcessor());
				JSONArray jsonArray = JSONArray.fromObject(list, config);

				// JsonObject to String
				requestCycle.getResponse().write(jsonArray.toString());
			}
		});
	}

	public class DateJsonValueProcessor implements JsonValueProcessor {
		public Object processArrayValue(Object value, JsonConfig config) {
			return process((Date) value, config);
		}

		public Object processObjectValue(String key, Object value, JsonConfig config) {
			return process((Date) value, config);
		}

		private Object process(Date date, JsonConfig config) {
			if (date == null) {
				return null;
			}
			return DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format(date);
		}
	}

	public class JsonData {
		private String title;

		private Date start;

		private Date end;

		public JsonData(String title, Date start, Date end) {
			this.title = title;
			this.start = start;
			this.end = end;
		}

		public String getTitle() {
			return title;
		}

		public void setTitle(String title) {
			this.title = title;
		}

		public Date getStart() {
			return start;
		}

		public void setStart(Date start) {
			this.start = start;
		}

		public Date getEnd() {
			return end;
		}

		public void setEnd(Date end) {
			this.end = end;
		}
	}
}

出力内容

[{"end":null,"start":"2009-12-08T11:05:44+09:00","title":"All Day Event"},{"end":"2009-12-10T11:05:44+09:00","start":"2009-12-02T11:05:44+09:00","title":"Long Event"}]

メモ

  • Dateクラスは普通に変換させると残念なことになるのでJsonValueProcessorを使って変換させる必要がある
  • POJOの解析にはcommons-beanutilsを使っているので、setter/getterが必要
  • アノテーションとかそういうものはない