GeekFactory

int128.hatenablog.com

流れるようなインタフェースでJSONを返す

いわゆる流れるインタフェースでJSONレスポンスを返す仕組みを実装してみました。Slim3じゃなくても使えそうです。

public class EventlogController extends Controller
{
  private final EventService eventService = new EventService();

  @Override
  public Navigation run() throws Exception
  {
    List<Event> result = eventService.getEvents(asKey("k"));
    return Jsonize.list(result)
      .property("url", new PropertyAccessor<Event, String>() {
        public String get(Event model) {
          return model.getRequestUrl();
        }
      })
      .property("time", new PropertyAccessor<Event, Long>() {
        public Long get(Event model) {
          return model.getRequestDate().getTime();
        }
      })
      .property("code", new PropertyAccessor<Event, Integer>() {
        public Integer get(Event model) {
          return model.getResponseCode();
        }
      })
      .property("responseTime", new PropertyAccessor<Event, Integer>() {
        public Integer get(Event model) {
          return model.getResponseTime();
        }
      })
      .send(response);
  }
}

この書き方は好みが分かれると思いますが、jQuery漬けの日々を送っているとだんだん自然に見えてくるから不思議です。

最後はJSONICでレスポンスを書き出しています。

public Navigation send(HttpServletResponse response) throws IOException
{
  Set<Entry<String, PropertyAccessor<M, ? extends Object>>> propertyAccessMapEntries = propertyAccessMap.entrySet();
  List<Map<String, String>> data = new ArrayList<Map<String,String>>();
  for(M model : modelList) {
    Map<String, String> map = new HashMap<String, String>();
    for(Entry<String, PropertyAccessor<M, ? extends Object>> entry : propertyAccessMapEntries) {
      map.put(entry.getKey(), entry.getValue().get(model).toString());
    }
    data.add(map);
  }
  response.setContentType("application/json");
  response.setCharacterEncoding("UTF-8");
  jsonService.format(data, response.getWriter());
  return null;
}
http://github.com/int128/healthcheck2/blob/a08cc97b75dd7594eb40f6a3cffa81af40ba8f0b/src/org/hidetake/app/healthcheck2/util/jsonize/Jsonize.java

ネタで作ってみたら意外と面白かったので、stableになったらライブラリにしたいと思います。