com.logicbus.backend.message.RawMessage Maven / Gradle / Ivy
package com.logicbus.backend.message;
import java.io.InputStream;
import java.io.OutputStream;
import com.anysoft.util.PropertiesConstants;
import com.anysoft.util.Settings;
import com.anysoft.util.compress.Compressor;
import com.anysoft.util.compress.compressor.GZIP;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.anysoft.util.IOTools;
import com.logicbus.backend.Context;
/**
* Raw消息
*
* @author duanyy
*
* @since 1.0.4
*
* @version 1.0.5 [20140412 duanyy]
* - 修改消息传递模型。
*
* @version 1.4.0 [20141117 duanyy]
* - Message被改造为接口
* - MessageDoc暴露InputStream和OutputStream
*
* @version 1.6.1.2 [20141118 duanyy]
* - 支持MessageDoc的Raw数据功能
*
* @version 1.6.2.1 [20141223 duanyy]
* - 增加对Comet的支持
*
* @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.13.21 [20201021 duanyy]
* - 支持gzip压缩
*/
public class RawMessage implements Message {
protected static final Logger logger = LoggerFactory.getLogger(RawMessage.class);
/**
* 消息文本
*/
protected StringBuffer buf = new StringBuffer();
private long contentLength = 0;
private static Compressor gzipCompressor = new GZIP();
private static boolean gzipSupport = false;
/**
* gzip开启的报文长度
*/
private static int gzipEnableLength = 1024;
static {
gzipSupport = PropertiesConstants.getBoolean(Settings.get(),"http.raw.gzip",gzipSupport);
gzipEnableLength = PropertiesConstants.getInt(Settings.get(),"http.gzip.length",gzipEnableLength);
}
/**
* 获取消息文本
* @return 消息文本
*/
public StringBuffer getBuffer(){
return buf;
}
/**
* to string
*/
public String toString(){
return buf.toString();
}
private boolean isGzipEnable(Context ctx,String header){
if (!gzipSupport) return false;
String gzip = ctx.getRequestHeader(header);
return StringUtils.isNotEmpty(gzip)?gzip.equalsIgnoreCase("gzip"):false;
}
public void init(Context ctx) {
boolean gzipEnable = isGzipEnable(ctx,"Content-Encoding");
String data = null;
{
byte [] inputData = ctx.getRequestRaw();
if (inputData != null){
try {
if (gzipEnable && inputData.length > 0){
inputData = gzipCompressor.decompress(inputData);
}
data = new String(inputData, ctx.getEncoding());
}catch (Exception ex){
}
}
}
if (data == null){
InputStream in = null;
try {
in = ctx.getInputStream();
if (gzipEnable && in.available() > 0){
in = gzipCompressor.getInputStream(in);
}
data = Context.readFromInputStream(in, ctx.getEncoding());
}catch (Exception ex){
logger.error("Error when reading data from inputstream",ex);
}finally{
IOTools.close(in);
}
}
if (data != null){
contentLength += data.getBytes().length;
buf.append(data);
}
contentType = "text/plain;charset=" + ctx.getEncoding();
}
public void finish(Context ctx,boolean closeStream) {
boolean gzipEnable = isGzipEnable(ctx,"Accept-Encoding");
OutputStream out = null;
try {
ctx.setResponseContentType(contentType);
out = ctx.getOutputStream();
byte [] bytes = buf.toString().getBytes(ctx.getEncoding());
if (gzipEnable && gzipEnableLength < bytes.length){
bytes = gzipCompressor.compress(bytes);
ctx.setResponseHeader("Content-Encoding","gzip");
}
ctx.setResponseContentLength(bytes.length);
contentLength += 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);
}
}
protected String contentType = "text/plain";
public void setContentType(String _contentType){
contentType = _contentType;
}
@Override
public String getContentType() {
return contentType;
}
@Override
public long getContentLength() {
return contentLength;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy