Http请求报文由三部分组成:请求行,请求头,请求体
请求行:请求方法、请求地址、协议名称和版本号
请求头:Referer、User-Agent、Accept、Cookie、Cache-Control、Content-Length等属性。Content-Length可用于服务端判断消息接受完的条件
请求体:GET请求与POST请求传递方式不同(Message Body)
request line 和每个 header 各占一行,以换行符 CRLF(即 \r\n)分割
传输数据有限,因为浏览器对URL的长度有限制。拼接在URL中,但这种方式也适用于POST方法。比如微信的语音识别接口…
POST:http://api.weixin.qq.com/cgi-bin/media/voice/queryrecoresultfortext?access_token=ACCESS_TOKEN&voice_id=xxxxxx&lang=zh_CN
Http响应报文由三部分组成:响应行,响应头,响应体
响应行:报文协议及版本,状态码及状态描述
响应头:Referer、User-Agent、Accept、Cookie、Cache-Control等属性
响应体:服务器返回的数据
1xx 消息,一般是告诉客户端,请求已经收到了,正在处理,别急...
2xx 处理成功,一般表示:请求收悉、我明白你要的、请求已受理、已经处理完成等信息.
3xx 重定向到其它地方。它让客户端再发起一个请求以完成整个处理。
4xx 处理发生错误,责任在客户端,如客户端的请求一个不存在的资源,客户端未被授权,禁止访问等。
5xx 处理发生错误,责任在服务端,如服务端抛出异常,路由出错,HTTP版本不支持等。
pre-request script和test scripts一样,都是javascript,同时还支持表达式,可以用两个{{}}访问环境变量。
# Pre-request Script调用
var temp = parseInt(postman.getGlobalVariable("xhbxId"));
temp += 1;
postman.setGlobalVariable("xhbxId", temp);
# 响应Tests
var temp = postman.getGlobalVariable("xhbxId");
tests["Body matches string"] = responseBody.has("\"_id\":\""+temp+"\"");
# 测试结果会展示在Test Results中
HttpRequest request = (HttpRequest) msg;
String uri = request.uri();
// 用浏览器发起 HTTP 请求时,常常会被 uri = "/favicon.ico" 所干扰
if(uri.equals(FAVICON_ICO)){
return;
}
// 吧URI分割成key-value形式
QueryStringDecoder decoder = new QueryStringDecoder(uriString);
Map> parame = decoder.parameters();
Iterator>> iterator = parame.entrySet().iterator();
while(iterator.hasNext()){
Entry> next = iterator.next();
parmMap.put(next.getKey(), next.getValue().get(0));
}
FullHttpRequest fullRequest = (FullHttpRequest) msg;
String jsonStr = fullRequest.content().toString(Charsets.toCharset(CharEncoding.UTF_8));
JSONObject obj = JSON.parseObject(jsonStr);
for(Entry item : obj.entrySet()){
System.out.println(item.getKey()+"="+item.getValue().toString());
}
方法一:
FullHttpRequest fullRequest = (FullHttpRequest) msg;
String jsonStr = fullRequest.content().toString(Charsets.toCharset(CharEncoding.UTF_8));
QueryStringDecoder queryDecoder = new QueryStringDecoder(jsonStr, false);
Map> uriAttributes = queryDecoder.parameters();
for (Map.Entry> attr : uriAttributes.entrySet()) {
for (String attrVal : attr.getValue()) {
System.out.println(attr.getKey()+"="+attrVal);
}
}
方法二:
HttpRequest request = (HttpRequest) msg;
HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(factory, request, Charsets.toCharset(CharEncoding.UTF_8));
List datas = decoder.getBodyHttpDatas();
for (InterfaceHttpData data : datas) {
if(data.getHttpDataType() == HttpDataType.Attribute) {
Attribute attribute = (Attribute) data;
System.out.println(attribute.getName() + "=" + attribute.getValue());
}
}
DiskFileUpload.baseDirectory = "/data/fileupload/";
HttpRequest request = (HttpRequest) msg;
HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(factory, request, Charsets.toCharset(CharEncoding.UTF_8));
List datas = decoder.getBodyHttpDatas();
for (InterfaceHttpData data : datas) {
if(data.getHttpDataType() == HttpDataType.FileUpload) {
FileUpload fileUpload = (FileUpload) data;
String fileName = fileUpload.getFilename();
if(fileUpload.isCompleted()) {
//保存到磁盘
StringBuffer fileNameBuf = new StringBuffer();
fileNameBuf.append(DiskFileUpload.baseDirectory).append(fileName);
fileUpload.renameTo(new File(fileNameBuf.toString()));
}
}
}
如果你要实现一个顶层解码器,就要继承 MessageToMessageDecoder 并重写其 decode 方法。
MessageToMessageDecoder 继承了 ChannelHandlerAdapter,也就是说解码器其实就是一个 handler,只不过是专门用来做解码的事情。
netty 提供了内存泄漏的监测机制,默认就会从分配的 ByteBuf 里抽样出大约 1% 的来进行跟踪
-Dio.netty.leakDetectionLevel=advanced
禁用(DISABLED) - 完全禁止泄露检测,省点消耗
简单(SIMPLE) - 默认等级,告诉我们取样的 1% 的 ByteBuf 是否发生了泄露,但总共一次只打印一次,看不到就没有了。
高级(ADVANCED) - 告诉我们取样的 1% 的 ByteBuf 发生泄露的地方。每种类型的泄漏(创建的地方与访问路径一致)只打印一次。
偏执(PARANOID) - 跟高级选项类似,但此选项检测所有 ByteBuf,而不仅仅是取样的那 1%。在高压力测试时,对性能有明显影响。
1、使用消息头部 Content-Length判断
2、使用消息首部字段 Transfer-Encoding判断
即 chunked 编码传输
参考链接:https://www.cnblogs.com/cyfonly/p/5616493.html