package frame.call.writer; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.math.BigDecimal; import java.net.URLEncoder; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.Stack; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import frame.config.Configer; import frame.data.Entity; import frame.data.EntitySet; import frame.data.reader.EntityReaderContainer; import frame.data.reader.IEntityReader; import frame.object.http.JsonItem; import frame.object.http.ObjectItem; import frame.object.http.ResultItem; import frame.object.http.ResultPool; import frame.util.Util; public class EnvelopWriter { public final static String Code_URL = "url"; private final static String NAME_EMPTY = "emptyname"; protected static Logger logger; protected static EntityReaderContainer objectReaderContainer; private HttpServletResponse response; protected PrintWriter writer; // 响应字符流 protected OutputStream outputStream; // 响应字节流 private Stack notEmpty; private boolean encode; static { logger = Logger.getLogger(EnvelopWriter.class); objectReaderContainer = EntityReaderContainer.getInstance(); } public EnvelopWriter(HttpServletRequest request, HttpServletResponse response) throws IOException { this.response = response; notEmpty = new Stack(); encode = true; } public PrintWriter getWriter() { return writer; } private void getPrintWriterFromResponse() throws IOException {// 获取指向浏览器的字符输出流 response.setCharacterEncoding("UTF-8"); writer = response.getWriter(); notEmpty.clear(); notEmpty.add(false); } public void replay(ResultPool result) throws Exception { List itemList = result.getItemList(); getPrintWriterFromResponse(); if (result.isJson()) { writer.write(result.getJson()); return; } writeBegin(); try { writeBoolean(IEnvelop.ResultCode_Success, result.isSuccess()); if (result.isSuccess()) { for (ResultItem item: itemList) { if (item instanceof ObjectItem) { IBeanWriter beanWriter = item.getBeanWriter(); writeOneObjectItem(item.getName(), item.getValue(), beanWriter); } else if (item instanceof JsonItem) { writeOneJsonItem(item.getName(), item.getValue()); } } } else { writeString(IEnvelop.ResultCode_ErrorCode, result.getErrorCode()); writeString(IEnvelop.ResultCode_ErrorMessage, result.getErrorMessage()); } } finally { writeEnd(); } } @SuppressWarnings("rawtypes") private void writeOneObjectItem(String name, Object value, IBeanWriter beanWriter) throws Exception { if (value instanceof IBeanWriter) { writeSmartWriter(name, (IBeanWriter) value); } else if (value instanceof String) { writeString(name, (String) value);// 写字符串 } else if (value instanceof Integer) { writeInteger(name, (Integer) value);// 写整型 } else if (value instanceof BigDecimal) { writeBigDecimal(name, (BigDecimal) value);// 写大小数 } else if (value instanceof Date) { writeDate(name, (Date) value);// 写日期 } else if (value instanceof Boolean) { writeBoolean(name, (Boolean) value);// 写boolean } else if (value instanceof Entity) { writeEntity(name, (Entity) value);// 写实体 } else if (value instanceof EntitySet) { writeEntitySet(name, (EntitySet) value);// 写实体集 } else if (value instanceof Collection) { writeCollection(name, (Collection) value, beanWriter); } else { writeObject(name, value, beanWriter);// 写对象 } } private void writeOneJsonItem(String name, Object value) throws Exception { writeComma(); writeName(name); writer.write((String)value); setNotEmpty(); } private void writeSmartWriter(String name, IBeanWriter smartWriter) { writeComma(); writeName(name); smartWriter.write(this); setNotEmpty(); } private void writeBegin() { writer.write("{"); } private void writeEnd() { writer.write("}"); } public void flush() { if (writer != null) { try { writer.flush(); writer.close(); } catch (Exception e) { logger.error(e); } } if (outputStream != null) { try { outputStream.flush(); outputStream.close(); } catch (Exception e) { logger.error(e); } } } public void write(String value) { writer.write(value); } public void writeString(String name, String value) { writeComma(); writeName(name); writer.write("\""); writer.write(encode(value)); writer.write("\""); setNotEmpty(); } public void writeInteger(String name, Integer value) { writeComma(); writeName(name); writer.write(String.valueOf(value)); setNotEmpty(); } public void writeBigDecimal(String name, BigDecimal value) { writeComma(); writeName(name); if (value != null) { writer.write(value.toString()); } else { writer.write("null"); } setNotEmpty(); } public void writeDate(String name, Date value) { writeComma(); writeName(name); if (value == null) { writer.write("null"); } else { writer.write("\""); writer.write(Util.DataTimeToString(value)); writer.write("\""); } setNotEmpty(); } public void writeBoolean(String name, Boolean value) { writeComma(); writeName(name); writer.write(value.toString()); setNotEmpty(); } public void writeEntity(String name, Entity entity) { if (entity == null) { return; } if (name == null) { name = IEnvelop.ResultCode_DataLine; } writeComma(); writeName(name); doWriteEntity(entity); setNotEmpty(); } private void doWriteEntity(Entity entity) { String[] propertyNames = entity.getLowerNames(); writer.write("{"); int cnt = propertyNames.length; int i; for (i = 0; i < cnt; i++) { if (i > 0) { writer.print(", "); } writeName(propertyNames[i]); try { writer.write(entity.getJSONString(i)); } catch (Exception e) { writer.write("error"); } } writer.write("}"); } public void writeEntitySet(String name, EntitySet entitySet) { if (name == null) { name = IEnvelop.ResultCode_DataSet; } writeComma(); if (entitySet == null || entitySet.size() == 0) { writer.write("\"count\": 0, "); writeName(name); writer.write("[]"); return; } int cnt = entitySet.size(); writer.write("\"count\": " + cnt); writer.write(", "); writeName(name); writer.write("["); boolean empty = true; for (Entity entity : entitySet) { if (!empty) { writer.write(", "); } doWriteEntity(entity); empty = false; } writer.write("]"); setNotEmpty(); } @SuppressWarnings("rawtypes") private void writeCollection(String name, Collection collection, IBeanWriter beanWriter) throws Exception { writeComma(); writeName(name); beginArray(); if (collection.isEmpty()) { endArray(); return; } for (Object obj : collection) { writeOneObjectItem(NAME_EMPTY, obj, beanWriter); } endArray(); } public void writeObject(String name, IBeanWriter smartWriter) { writeComma(); writeName(name); beginObject(); smartWriter.write(this); endObject(); setNotEmpty(); } public void writeObject(String name, Collection smartWriters) { writeComma(); writeName(name); beginObject(); for (IBeanWriter smartWriter : smartWriters) { smartWriter.write(this); } endObject(); setNotEmpty(); } public void writeArray(String name, Collection smartWriters) { writeComma(); writeName(name); beginArray(); for (IBeanWriter smartWriter : smartWriters) { writeComma(); smartWriter.write(this); setNotEmpty(); } endArray(); setNotEmpty(); } public void writeObject(Object object) { writeObject(null, object, null); } public void writeObject(String name, Object object, IBeanWriter beanWriter) { try { writeComma(); writeName(name); if (beanWriter == null) { IEntityReader entityReader = objectReaderContainer.getEntityReader(object.getClass()); writer.write(entityReader.getJSONString(object)); } else { beanWriter.setBean(object); beanWriter.write(this); } setNotEmpty(); } catch (Exception e) { e.printStackTrace(); writeString(name, "error"); } } private String encode(String value) { if (!encode) { return value; } String result = ""; if (value == null) { return result; } try { result = URLEncoder.encode(value, "UTF-8"); result = result.replace("+", "%20"); } catch (Exception e) { result = value; } return result; } public void ReplyError(String errorMessage) throws IOException { ReplyError(null, errorMessage); } public void ReplyError(String errorCode, String errorMessage) throws IOException { getPrintWriterFromResponse(); writeBegin(); try { writeBoolean(IEnvelop.ResultCode_Success, false); if (!Util.isEmptyStr(errorCode)) { writeString(IEnvelop.ResultCode_ErrorCode, errorCode); } writeString(IEnvelop.ResultCode_ErrorMessage, errorMessage); } finally { writeEnd(); } } public void replayTimeout() throws IOException { getPrintWriterFromResponse(); writeBegin(); try { writeBoolean(IEnvelop.ResultCode_Success, false); writer.write("\"timeoutPage\": \"" + URLEncoder.encode(Configer.getPage_TimeOut(), "UTF-8") + "\""); } finally { writeEnd(); } } public void beginObject(String propName) { if (propName == null) { propName = "empty"; } propName = propName.toLowerCase(); notEmpty.push(false); writer.write("\"" + propName + "\": {"); } public void beginObject() { writeComma(); notEmpty.push(false); writer.write("{"); } public void endObject() { notEmpty.pop(); writer.write("}"); setNotEmpty(); } public void beginArray() { notEmpty.push(false); writer.write("["); } public void endArray() { notEmpty.pop(); writer.write("]"); setNotEmpty(); } public void writeComma() { if (notEmpty.peek()) { writer.write(", "); } } private void setNotEmpty() { if (notEmpty.peek()) { return; } notEmpty.pop(); notEmpty.push(true); } private void writeName(String name) { if (name == null) { writer.write("\"empty\": "); return; } if (!NAME_EMPTY.equals(name)) { writer.write("\"" + name.toLowerCase() + "\": "); } } public boolean isEncode() { return encode; } public void setEncode(boolean encode) { this.encode = encode; } }