All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.logicbus.backend.message.JsonMessage Maven / Gradle / Ivy

There is a newer version: 1.6.17
Show newest version
package com.logicbus.backend.message;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

import com.anysoft.util.compress.Compressor;
import com.anysoft.util.compress.compressor.GZIP;
import com.logicbus.backend.message.tools.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alogic.idnote.IdNote;
import com.anysoft.util.IOTools;
import com.anysoft.util.JsonTools;
import com.anysoft.util.PropertiesConstants;
import com.anysoft.util.Settings;
import com.logicbus.backend.Context;

/**
 * 基于JSON的消息协议
 * @author duanyy
 * 
 * @since 1.2.1
 * 
 * @version 1.4.0 [20141117 duanyy] 
* - Message被改造为接口
* * @version 1.6.1.1 [20141118 duanyy]
* - 修正没有读入的情况下,root为空的bug
* - MessageDoc暴露InputStream和OutputStream
* * @version 1.6.1.2 [20141118 duanyy]
* - 支持MessageDoc的Raw数据功能
* * @version 1.6.2.1 [20141223 duanyy]
* - 增加对Comet的支持
* * @version 1.6.3.14 [20150409 duanyy]
* - 修正formContentType所取的参数名问题,笔误
* * @version 1.6.5.6 [20160523 duanyy]
* - 淘汰MessageDoc,采用Context替代
* - 增加getContentType和getContentLength
* * @version 1.6.7.9 [20170201 duanyy]
* - 采用SLF4j日志框架输出日志
* * @version 1.6.7.15 [20170221 duanyy]
* - 输出时设置Content-Length以便支持keepalive
* * @version 1.6.11.22 [duanyy 20180314]
* - 支持按指定jsonpath路径来输出文档
* * @version 1.6.11.62 [duanyy 20180928]
* - 删除冗余的代码
* * @version 1.6.12.8 [20181121 duanyy]
* - 关闭缺省的jsonp支持
* * @version 1.6.12.13 [20181213 duanyy]
* - 增加code字段的拦截,通过idnote框架展现错误reason
* * @version 1.6.12.19 [20190118 duanyy]
* - 对文档返回的主机信息做掩码处理
* * @version 1.6.13.21 [20201021 duanyy]
* - 支持gzip压缩
* * @version 1.6.14.2 [20210316 duanyy]
* - 移植逻辑到Tools框架
* - 增加输入payload的摘要功能
*/ public class JsonMessage implements Message { protected static final Logger logger = LoggerFactory.getLogger(JsonMessage.class); protected static String formContentType = "application/x-www-form-urlencoded"; protected static GzipTool gzipTool = null; protected static JsonFactory jsonFactory = null; protected static HostMask hostMask = null; protected static IdNoteTool idnoteTool = null; protected static ContentDigest contentDigest = null; static { gzipTool = Settings.getToolkit(GzipTool.class); jsonFactory = Settings.getToolkit(JsonFactory.class); hostMask = Settings.getToolkit(HostMask.class); idnoteTool = Settings.getToolkit(IdNoteTool.class); contentDigest = Settings.getToolkit(ContentDigest.class); formContentType = PropertiesConstants.getString(Settings.get(), "http.formContentType", "application/x-www-form-urlencoded"); } /** * Json结构的根节点 */ protected Map root = null; private long contentLength = 0; private String contentType = "application/json;charset=utf-8"; private String outputPath = null; /** * 获取JSON结构的根节点 * * @return JSON结构的根节点 */ public Map getRoot(){ return root; } @Override public String toString(){ return jsonFactory.toJsonString(root); } @Override public String getContentType() { return contentType; } @Override public long getContentLength() { return contentLength; } /** * 设置输出目录 * @param path jsonPath */ public void setOutputPath(String path){ this.outputPath = path; } @SuppressWarnings("unchecked") @Override public void init(Context ctx) { boolean gzipEnable = gzipTool.isRequestGzipEnable(ctx); String data = null; { byte [] inputData = ctx.getRequestRaw(); if (inputData != null){ try { if (gzipEnable){ inputData = gzipTool.decompress(ctx,inputData); } data = new String(inputData,ctx.getEncoding()); }catch (Exception ex){ } } } if (data == null){ //当客户端通过form来post的时候,Message不去读取输入流。 String _contentType = ctx.getRequestContentType(); if (_contentType == null || !_contentType.startsWith(formContentType)){ InputStream in = null; try { in = ctx.getInputStream(); if (gzipEnable){ in = gzipTool.getInputStream(ctx,in); } data = Context.readFromInputStream(in, ctx.getEncoding()); }catch (Exception ex){ logger.error("Error when reading data from inputstream",ex); }finally{ IOTools.close(in); } } } if (contentDigest != null) { contentDigest.digest(ctx, data); } if (StringUtils.isNotEmpty(data)){ contentLength += data.getBytes().length; Object rootObj = jsonFactory.fromJsonString(data); if (rootObj instanceof Map){ root = (Map)rootObj; } } if (root == null){ root = new HashMap(); } contentType = "application/json;charset=" + ctx.getEncoding(); } @Override public void finish(Context ctx,boolean closeStream) { Map _root = getRoot(); JsonTools.setString(_root, "code", ctx.getReturnCode()); IdNote idnote = idnoteTool.getIdNote(ctx.getReturnCode()); if (idnote != null){ JsonTools.setString(_root, "reason", idnote.getNote()); JsonTools.setString(_root, "advise", ctx.getReason()); }else{ JsonTools.setString(_root, "reason", ctx.getReason()); } JsonTools.setString(_root, "duration", String.valueOf(ctx.getDuration())); JsonTools.setString(_root, "host", hostMask.getHost(ctx.getHost())); JsonTools.setString(_root, "serial", ctx.getGlobalSerial()); OutputStream out = null; try { Object outputObject = _root; try { outputObject = jsonFactory.readJsonPath(outputObject,outputPath); }catch (Exception ex){ logger.error("Can not location jsonpath " + outputPath); } outputObject = outputObject == null ? _root : outputObject; String data = jsonFactory.toJsonString(outputObject); data = jsonFactory.wrapJsonp(ctx,data); out = ctx.getOutputStream(); ctx.setResponseContentType(contentType); byte [] bytes = data.getBytes(ctx.getEncoding()); if (gzipTool.isResponseGzipEnable(ctx)){ bytes = gzipTool.compress(ctx,bytes); } contentLength += bytes.length; ctx.setResponseContentLength(bytes.length); Context.writeToOutpuStream(out, bytes); out.flush(); }catch (Exception ex){ logger.error("Error when writing data to outputstream",ex); }finally{ if (closeStream) { IOTools.close(out); } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy