Netty4 HTTP请求参数解析(GET, POST)

我们在使用Netty编写HTTP服务器时,一个非常痛苦的地方就是解析POST请求的代码真是太丑陋了,远没有servlet中request.getParameter()优雅。我猜测这是因为Netty是一个网络通讯框架,所以设计者希望尽可能的把底层数据暴露给开发者以提供更好的灵活性。我们可以自己将HTTP请求参数封装成类似于servlet的调用方式。

下面是一个RequestParser类,使用时只需:

@Override
    protected void messageReceived(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception {
        Map<String, String> parmMap = new RequestParser(msg).parse(); // 将GET, POST所有请求参数转换成Map对象

        System.out.println(parmMap);
    }

对于请求

curl -d "names=whf&abc=123" http://127.0.0.1:8080

输出结果为:

{names=whf, abc=123}

这样请求参数的获取就优雅多了。下面是该类的全部代码:

import cn.fh.http.exception.BaseCheckedException;
import cn.fh.http.exception.MethodNotSupportedException;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.handler.codec.http.multipart.Attribute;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import io.netty.handler.codec.http.multipart.InterfaceHttpData;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * HTTP请求参数解析器, 支持GET, POST
 * Created by whf on 12/23/15.
 */
public class RequestParser {
    private FullHttpRequest fullReq;

    /**
     * 构造一个解析器
     * @param req
     */
    public RequestParser(FullHttpRequest req) {
        this.fullReq = req;
    }

    /**
     * 解析请求参数
     * @return 包含所有请求参数的键值对, 如果没有参数, 则返回空Map
     *
     * @throws BaseCheckedException
     * @throws IOException
     */
    public Map<String, String> parse() throws BaseCheckedException, IOException {
        HttpMethod method = fullReq.method();

        Map<String, String> parmMap = new HashMap<>();

        if (HttpMethod.GET == method) {
            // 是GET请求
            QueryStringDecoder decoder = new QueryStringDecoder(fullReq.uri());
            decoder.parameters().entrySet().forEach( entry -> {
                // entry.getValue()是一个List, 只取第一个元素
                parmMap.put(entry.getKey(), entry.getValue().get(0));
            });
        } else if (HttpMethod.POST == method) {
            // 是POST请求
            HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(fullReq);
            decoder.offer(fullReq);

            List<InterfaceHttpData> parmList = decoder.getBodyHttpDatas();

            for (InterfaceHttpData parm : parmList) {

                Attribute data = (Attribute) parm;
                parmMap.put(data.getName(), data.getValue());
            }

        } else {
            // 不支持其它方法
            throw new MethodNotSupportedException(""); // 这是个自定义的异常, 可删掉这一行
        }

        return parmMap;
    }
}
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值