5.HTTP请求参数解析
这一章,将要处理http请求参数的解析,一方面是get请求参数,另一方面是post请求,做一个参完善
首先是设计了一个请求解析器RequestParser
public Map<String, Object> parse() {
// 获取 Content-type
String contentType = getContentType();
// 获取请求类型
HttpMethod method = request.method();
if (HttpMethod.GET == method) {
Map<String, Object> parameterMap = new HashMap<>();
QueryStringDecoder decoder = new QueryStringDecoder(request.uri());
decoder.parameters().forEach((key, value) -> parameterMap.put(key, value.get(0)));
return parameterMap;
} else if (HttpMethod.POST == method) {
switch (contentType) {
case "multipart/form-data":
Map<String, Object> parameterMap = new HashMap<>();
HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(request);
decoder.offer(request);
decoder.getBodyHttpDatas().forEach(data -> {
Attribute attr = (Attribute) data;
try {
parameterMap.put(data.getName(), attr.getValue());
} catch (IOException ignore) {
}
});
return parameterMap;
case "application/json":
ByteBuf byteBuf = request.content().copy();
if (byteBuf.isReadable()) {
String content = byteBuf.toString(StandardCharsets.UTF_8);
return JSON.parseObject(content);
}
break;
default:
throw new RuntimeException("未实现的协议类型 Content-Type:" + contentType);
}
}
throw new RuntimeException("未实现的请求类型 HttpMethod:" + method);
}
get请求就是从url中获取对应的参数即可,post请求要区分是multipart/form-data
(from表单类型) 还是application/json
(json类型)
对于表单类型使用的是HttpPostRequestDecoder
netty的post请求编码器进行解析
对于json类型直接可以使用json转换即可,先从报文信息中获取,在进行转换
另外一方面是增加了一个SimpleTypeRegistry
基础类型注册器,用来判断是否为基础类型
在DefaultGatewaySession中有使用
public Object get(String methodName, Map<String, Object> params) {
Connection connection = dataSource.getConnection();
HttpStatement httpStatement = configuration.getHttpStatement(uri);
String parameterType = httpStatement.getParameterType();
/*
* 调用服务
* 封装参数 PS:为什么这样构建参数,可以参考测试案例;cn.bugstack.gateway.test.RPCTest
* 01(允许):java.lang.String
* 02(允许):cn.bugstack.gateway.rpc.dto.XReq
* 03(拒绝):java.lang.String, cn.bugstack.gateway.rpc.dto.XReq —— 不提供多参数方法的处理
* */
return connection.execute(methodName,
new String[]{parameterType},
new String[]{"ignore"},
SimpleTypeRegistry.isSimpleType(parameterType) ? params.values().toArray() : new Object[]{params});
}
有点细节的是,为什么第三个参数用ignore,原因是 其实并没有被使用这个参数,可以忽略