public Writer open(final PrintWriter writer) throws IOException {
    JsonWriter jsonWriter = GSON.newJsonWriter(new java.io.Writer() {

      @Override
      public void write(char[] cbuf, int off, int len) throws IOException {
        writer.write(cbuf, off, len);
      }

      @Override
      public void flush() throws IOException {
        writer.flush();
      }

      @Override
      public void close() throws IOException {
        // do nothing
      }
    });
    jsonWriter.setIndent("  ");
    jsonWriter.beginObject();
    return new Writer() {
      @Override
      public void flush() throws IOException {
        jsonWriter.flush();
      }

      @Override
      public void close() throws IOException {
        jsonWriter.endObject();
        jsonWriter.close();
      }

      @Override
      public void write(String key, String value) throws IOException {
        jsonWriter.name(key).value(value);
      }

      @Override
      public int write(MBeanServer mBeanServer, ObjectName qry, String attribute,
        boolean description, ObjectName excluded) throws IOException {
        return JSONBean.write(jsonWriter, mBeanServer, qry, attribute, description, excluded);
      }
    };
  }
Notice that, closing the return {@link Writer} will not close the {@code writer} passed in, you
still need to close the {@code writer} by yourself.
<p/>
This is because that, we can only finish the json after you call {@link Writer#close()}. So if
we just close the {@code writer}, you can write nothing after finished the json.
hbase-http/src/main/java/org/apache/hadoop/hbase/util/JSONBean.java