解决用netty去做web服务时,post长度过大的问题
原文地址
http://my.oschina.net/momohuang/blog/114552
先说一下,本来是想自己写socket ,启动一个简单点的web服务用于接收数据的。写完之后,发现会有各种情况没有考虑到的,很有可能出现问题,而且,太折腾了。于是,就用了netty去其web服务,另外,我也觉得netty基本上是最简单的web服务了吧,如果童鞋们有其他推荐的话,就留个言呗。
1、server
public class AdminServer {
protected static final Log log = LogFactory.getLog(AdminServer.class);
public static void main(String[] args) {
log.info("start app");
start(8088);
// System.out.println("admin start on "+1);
}
public static void start(int port) {
// 配置服务器-使用java线程池作为解释线程
ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));
// 设置 pipeline factory.
bootstrap.setPipelineFactory(new ServerPipelineFactory());
// 绑定端口
bootstrap.bind(new InetSocketAddress(port));
System.out.println("admin start on "+port);
ServiceLocator.initServiceLocator();
}
private static class ServerPipelineFactory implements
ChannelPipelineFactory {
public ChannelPipeline getPipeline() throws Exception {
// Create a default pipeline implementation.
ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("decoder", new HttpRequestDecoder());
pipeline.addLast("encoder", new HttpResponseEncoder());
//http处理handler
pipeline.addLast("handler", new AdminServerHandler());
return pipeline;
}
}
}
启动了服务,绑定了8088端口。
2、当客户端给服务端post数据的时候,如果数据超过50K,这个时候服务端接受到的post内容是空的了。这是因为超过了 服务端默认的post的长度的最大值。
http协议里边,本来是没有对post的长度进行限制,但是,无论是系统层面或者是服务端层面的,都会对post的长度进行限制,这个也有利于网络安全。
3、在netty中的解决方法
private static class ServerPipelineFactory implements
ChannelPipelineFactory {
public ChannelPipeline getPipeline() throws Exception {
// Create a default pipeline implementation.
ChannelPipeline pipeline = Channels.pipeline();
// pipeline.addFirst("frameDecoder", new LengthFieldBasedFrameDecoder(100000000,0,4,0,4));
pipeline.addLast("decoder", new HttpRequestDecoder());
pipeline.addLast("encoder", new HttpResponseEncoder());
// pipeline.addLast("streamer", new ChunkedWriteHandler());
pipeline.addLast("aggregator", new HttpChunkAggregator(65536));//设置块的最大字节数
//http处理handler
pipeline.addLast("handler", new AdminServerHandler());
return pipeline;
}
}
加上
pipeline.addLast("aggregator", new HttpChunkAggregator(65536))
之后,设置默认的chunk最大为 65536,这样,就可以接受最大post的内容大小为 65536。
这样有一个不好的地方,就是这个大小不好控制,开大了,会浪费空间。并且在接受到的字符串的最后,会出现空白的字符串,这是由于post的内容长度小于chunk里边的ChannelBuffer的数组的大小,程序给予补全。
4、自己设置,自己读取chunk
加上
pipeline.addLast("streamer", new ChunkedWriteHandler());
设置为给位 分开一个个chunk去接受信息。
public boolean excuteChunk(ChannelHandlerContext ctx, MessageEvent e)
throws TooLongFrameException {
// HttpMessage currentMessage = e.getMessage();
if (e.getMessage() instanceof HttpMessage) {
HttpMessage m = (HttpMessage) e.getMessage();
if (m.isChunked()) {
// A chunked message - remove 'Transfer-Encoding' header,
// initialize the cumulative buffer, and wait for incoming
// chunks.
List<String> encodings = m
.getHeaders(HttpHeaders.Names.TRANSFER_ENCODING);
encodings.remove(HttpHeaders.Values.CHUNKED);
if (encodings.isEmpty()) {
m.removeHeader(HttpHeaders.Names.TRANSFER_ENCODING);
}
m.setContent(ChannelBuffers.dynamicBuffer(e.getChannel()
.getConfig().getBufferFactory()));
this.currentMessage = m;
} else {
// Not a chunked message - pass through.
this.currentMessage = null;
}
return false;
} else if (e.getMessage() instanceof HttpChunk) {
// Sanity check
if (currentMessage == null) {
throw new IllegalStateException("received "
+ HttpChunk.class.getSimpleName() + " without "
+ HttpMessage.class.getSimpleName());
}
// Merge the received chunk into the content of the current message.
HttpChunk chunk = (HttpChunk) e.getMessage();
ChannelBuffer content = currentMessage.getContent();
if (content.readableBytes() > maxContentLength
- chunk.getContent().readableBytes()) {
throw new TooLongFrameException("HTTP content length exceeded "
+ maxContentLength + " bytes.");
}
content.writeBytes(chunk.getContent());
if (chunk.isLast()) {
this.currentMessage = null;
currentMessage.setHeader(HttpHeaders.Names.CONTENT_LENGTH,
String.valueOf(content.readableBytes()));
return true;
// Channels.fireMessageReceived(ctx, currentMessage,
// e.getRemoteAddress());
}
}
return true;
}
在handle中,自己做处理,接受 整个post过来的数据,然后在整合起来,即可
解决用netty去做web服务时,post长度过大的问题的更多相关文章
- idea 为模块添加Tomcat依赖 解决: Intelij IDEA 创建WEB项目时没有Servlet的jar包
解决: Intelij IDEA 创建WEB项目时没有Servlet的jar包 今天创建SpringMVC项目时 用到HttpServletRequest时, 发现项目中根本没有Servlet这个包, ...
- 解决: Intelij IDEA 创建WEB项目时没有Servlet的jar包
今天创建SpringMVC项目时 用到HttpServletRequest时, 发现项目中根本没有Servlet这个包, 在网上搜了一下,这个问题是因为web项目没有添加服务器导致的. 配置tomec ...
- 解决eclipse中运行web项目时弹出的"Port 8080 required by Tomcat 9.0 Server at localhost is already in use...
1.tomcat默认端口是8080,可以修改通过tomcat的端口 修改tomcat\conf\server.xml 结果运行程序,还是报"Port 8080 required by ...
- ASP.NET Web服务调用发生错误,错误代码404
现象: iOS端使用ASIHTTP连接Web服务时,得到的数据是一个错误代码为404的页面,错误信息(web.config添加<customErrors mode="Off" ...
- 服务设计模式一:Web服务概述
目录 1. Web服务是什么 2.为什么要使用Web服务 3.Web服务考虑的因素和替代方案 4.SOA是什么 Web服务是什么? 所谓服务,通俗的理解就是别人帮你做一些事情,比如说,腰酸背痛了,找个 ...
- Web服务端性能提升实践
随着互联网的不断发展,日常生活中越来越多的需求通过网络来实现,从衣食住行到金融教育,从口袋到身份,人们无时无刻不依赖着网络,而且越来越多的人通过网络来完成自己的需求. 作为直接面对来自客户请求的Web ...
- Linux实战教学笔记37:企业级Nginx Web服务优化实战(上)
一,Nginx基本安全优化 1.1 调整参数隐藏Nginx软件版本号信息 一般来说,软件的漏洞都和版本有关,这个很像汽车的缺陷,同一批次的要有问题就都有问题,别的批次可能就都是好的.因此,我们应尽量隐 ...
- 踩坑踩坑之Flask+ uWSGI + Tensorflow的Web服务部署
一.简介 作为算法开发人员,在算法模块完成后,拟部署Web服务以对外提供服务,从而将算法模型落地应用.本文针对首次基于Flask + uWSGI + Tensorflow + Nginx部署Web服务 ...
- Python Web 服务开发者: 第 1 部分
Python Web 服务开发者: 第 1 部分 Python Web 服务世界 Python 的座右铭一向是“装备齐全”,这是指在安装该语言时会附带一大套标准库和功能程序.本文概述了在 Python ...
- 利用OpenShift托管Node.js Web服务进行微信公众号开发
最近写了一个微信的翻译机器人.用户只要关注该公众号,发送英文的消息,就能收到中文翻译的回复.有兴趣的读者可以扫描下面的二维码关注该公众号,尝试发送英文单词试试看.(有时候第一次发送单词会收到“该公众号 ...
随机推荐
- glance对接ceph
目录 glance对接ceph 1. 上传镜像 2. 对接ceph 2.1 创建池 2.2 创建用户 2.3 下发ceph文件 2.4 修改globals文件 2.5 更新glance配置 3. 上传 ...
- 基于Python后端构建多种不同的系统终端界面研究
在我们一般开发系统的时候,往往会根据实际需要做出各种不同的系统终端界面,如基于BS的,CS.APP.小程序等等,一般都是基于一个统一接入的Web API后端,本篇系统探寻对基于Python后端构建多种 ...
- Linux+PXE+DHCP+TFTP+NFS实现无人值守安装
一.实验环境:OS:Redhat6.4软件:DHCP服务.TFTP服务.NFS服务硬件:Dell R630服务器两台物理连接图: em1 em1 二.工作原理:服务器通过PXE网卡启动,从dhcp服务 ...
- 妙用编辑器:使用Notepad--的标记颜色功能更高效的阅读日志文件
应用场景 在日常维护工作中,经常需要查看一些日志,以判断系统的运行状态或者进行问题定位,当系统出现故障时,一般都会有特殊的关键字,但对于浩如烟海的日志来说,识别这些关键字信息还是非常费眼力的,比如有如 ...
- 一起来看看大佬是怎样配置nginx虚拟主机
在真实的服务器环境,为了充分利用服务器资源,一台nginx web服务器会同时配置N个虚拟主机,这样可以充分利用服务器的资源,方便管理员的统一管理 配置nginx虚拟主机首先肯定要先部署咱们的ngin ...
- CF980-Div2-D
CF980-Div2-D 题意 从 \(1\) 开始决策,若选当前数,则累计贡献 \(a[i]\) 并跳到 \(j\) 位置,\(j\) 是 \(\lt i\) 且没有决策过(包括选了和没选)的最大位 ...
- 利用 canvas 实现签名效果
利用 canvas 实现签名效果 使用插件 jSignature github:https://github.com/brinley/jSignature 如果再H5 中使用需要加载 flash ...
- 《JVM第7课》堆区
1.概念 堆是JVM中最重要的一块区域,JVM规范中规定所有的对象和数组都应该存放在堆中,在执行字节码指令时,会把创建的对象存入堆中,对象的引用地址存入虚拟机栈的栈帧中.不过当方法执行完之后,刚刚所创 ...
- DCDC电路设计之FB引脚布线
该随笔从与非网上搬运,原文: 案例讲解,DCDC电源反馈路径的布线规则 下面为正文内容: 在本文中,将对用来将输出信号反馈给电源ic的FB引脚的布线进行说明. 反馈路径的布线 反馈信号的布线在信号布线 ...
- ExtJS & Asp.NET
企业应用中,要快速开发Web应用,前端使用ExtJS还行,包含许多常用的控件,图标,配色方案... 帖上部分载图: 完全可订制的登录界面: 可调整的布局: 可综合使用的模态对话框: 树结构及动态加载: ...