原文地址

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长度过大的问题的更多相关文章

  1. idea 为模块添加Tomcat依赖 解决: Intelij IDEA 创建WEB项目时没有Servlet的jar包

    解决: Intelij IDEA 创建WEB项目时没有Servlet的jar包 今天创建SpringMVC项目时 用到HttpServletRequest时, 发现项目中根本没有Servlet这个包, ...

  2. 解决: Intelij IDEA 创建WEB项目时没有Servlet的jar包

    今天创建SpringMVC项目时 用到HttpServletRequest时, 发现项目中根本没有Servlet这个包, 在网上搜了一下,这个问题是因为web项目没有添加服务器导致的. 配置tomec ...

  3. 解决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 ...

  4. ASP.NET Web服务调用发生错误,错误代码404

    现象: iOS端使用ASIHTTP连接Web服务时,得到的数据是一个错误代码为404的页面,错误信息(web.config添加<customErrors mode="Off" ...

  5. 服务设计模式一:Web服务概述

    目录 1. Web服务是什么 2.为什么要使用Web服务 3.Web服务考虑的因素和替代方案 4.SOA是什么 Web服务是什么? 所谓服务,通俗的理解就是别人帮你做一些事情,比如说,腰酸背痛了,找个 ...

  6. Web服务端性能提升实践

    随着互联网的不断发展,日常生活中越来越多的需求通过网络来实现,从衣食住行到金融教育,从口袋到身份,人们无时无刻不依赖着网络,而且越来越多的人通过网络来完成自己的需求. 作为直接面对来自客户请求的Web ...

  7. Linux实战教学笔记37:企业级Nginx Web服务优化实战(上)

    一,Nginx基本安全优化 1.1 调整参数隐藏Nginx软件版本号信息 一般来说,软件的漏洞都和版本有关,这个很像汽车的缺陷,同一批次的要有问题就都有问题,别的批次可能就都是好的.因此,我们应尽量隐 ...

  8. 踩坑踩坑之Flask+ uWSGI + Tensorflow的Web服务部署

    一.简介 作为算法开发人员,在算法模块完成后,拟部署Web服务以对外提供服务,从而将算法模型落地应用.本文针对首次基于Flask + uWSGI + Tensorflow + Nginx部署Web服务 ...

  9. Python Web 服务开发者: 第 1 部分

    Python Web 服务开发者: 第 1 部分 Python Web 服务世界 Python 的座右铭一向是“装备齐全”,这是指在安装该语言时会附带一大套标准库和功能程序.本文概述了在 Python ...

  10. 利用OpenShift托管Node.js Web服务进行微信公众号开发

    最近写了一个微信的翻译机器人.用户只要关注该公众号,发送英文的消息,就能收到中文翻译的回复.有兴趣的读者可以扫描下面的二维码关注该公众号,尝试发送英文单词试试看.(有时候第一次发送单词会收到“该公众号 ...

随机推荐

  1. glance对接ceph

    目录 glance对接ceph 1. 上传镜像 2. 对接ceph 2.1 创建池 2.2 创建用户 2.3 下发ceph文件 2.4 修改globals文件 2.5 更新glance配置 3. 上传 ...

  2. USB协议详解第1讲(核心概念通俗理解)

    0.概括 USB协议学习中最重要几个概念如下,没有提及的就是对USB协议学习中不重要的或者编程不需要用到的.大家也不用着急,概念必须要学会,否则都不知道下面这些东西是什么还学什么通用串行总线协议,大家 ...

  3. 某小说解锁VIP

    在User类中定位到这个方法,尝试直接返回true 可以发现apk显示了vip的到期时间,测试一下vip是否有效 显然这个vip是没起作用的,还有地方在控制这个vip的方法.在jadx中查看交叉引用 ...

  4. Centos7下非lvm的分区扩容

    Centos7下非lvm的分区扩容(重要) 前言:一般在生产环境中,如果需要使用一个分区保存大量的文件,建议的做法是在虚拟化环境中增加一块单独的硬盘,挂载一个单独的分区,比如 /data 上图我们可以 ...

  5. vue3+tpyeScript + element plus 三级复选框,全选控制全部,左侧选中控制右侧全选

    .markdown-body { line-height: 1.75; font-weight: 400; font-size: 16px; overflow-x: hidden; color: rg ...

  6. Litmus 实践:让群魔在混沌中乱舞,看 K8s 能撑到何时

    对于云服务而言,如果系统出现异常,将会带来很大的损失.为了最大程度地降低损失,我们只能不断探寻系统何时会出现异常,甚至缩小到某些特定参数变化是否会造成系统异常.然而随着云原生的发展,不断推进着微服务的 ...

  7. 第147篇:微信小程序开发中Promise的使用(aysnc,await)

    好家伙, 0.错误描述 今天在开发中犯了一个比较严重的错误 对于Promise的错误使用 场景: 微信小程序中展示搜索条件列表 // API请求工具函数 const apiRequest = (url ...

  8. 玩黑悟空要配什么显卡?ToDesk云电脑一招搞定!

    近期国产游戏大作<黑神话·悟空>的预售开启,许多玩家对于如何配置自己的电脑以畅玩这款画质卓越.支持全景光追的3A大作产生了浓厚的兴趣. 尤其是显卡的选择,成为了玩家们关注的焦点.<黑 ...

  9. 工作中的技术总结_ thymeleaf的应用 _select&input的数据回显 _20210910

    工作中的技术总结_ thymeleaf的应用 _select&input的数据回显 _20210910 在需要用户输入的场合,常常会有对用户填入数据的验证,对数据的验证不通过则需要返回到表单页 ...

  10. springBoot项目启动卡在Root WebApplicationContext: initialization completed... (非DEBUG断点问题)

    通过源码启动排查发现,初始化连接池时创建了200次,通过配置文件中将initialSize值改为10,启动时间从1分钟变为了3秒.