0
点赞
收藏
分享

微信扫一扫

Netty获取Http参数反射执行方法参数映射

zibianqu 2022-04-14 阅读 53
java

获取参数名称的一种方式参数映射:

String[] parameterNames =
 new LocalVariableTableParameterNameDiscoverer().getParameterNames(method);

反射映射参数:

/**
 * 构造一个请求参数对象
 */
public class RequestParam {
    //是否是参数体
    private boolean isBody;

    //参数体,一个参数名独占一行
    private List<Map<String, Object>> data;

    public boolean isBody() {
        return isBody;
    }

    public void setBody(boolean body) {
        isBody = body;
    }

    public List<Map<String, Object>> getData() {
        return data;
    }

    public void setData(List<Map<String, Object>> data) {
        this.data = data;
    }
}

解析原始参数(解决其他版本无法获取报文体参数):

解决这篇文章无法获取POST报文体参数:(1条消息) Netty4 HTTP请求参数解析(GET, POST)_Mrs陶的博客-CSDN博客_netty获取http参数

/**
 * HTTP请求参数解析器, 支持GET, POST
 */
public class RequestParser {
    private FullHttpRequest fullReq;

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

    /**
     * 解析请求参数
     *
     * @return 包含所有请求参数的键值对, 如果没有参数, 则返回空Map
     * @throws RuntimeException
     * @throws IOException
     */
    public RequestParam parse() throws Exception, IOException {
        HttpMethod method = fullReq.method();
        RequestParam param = new RequestParam();
        Map<String, Object> parmMap = new HashMap<>();
        List<Map<String, Object>> paramList = new ArrayList<>();
        if (HttpMethod.GET == method) {
            param.setBody(false);
            // 是GET请求
            QueryStringDecoder decoder = new QueryStringDecoder(fullReq.uri());
            decoder.parameters().entrySet().forEach(entry -> {
                // entry.getValue()是一个List, 只取第一个元素
                parmMap.put(entry.getKey(), entry.getValue().get(0));
                paramList.add(parmMap);
            });
        } else if (HttpMethod.POST == method) {
            // 是POST请求
            String content = fullReq.content().toString(Charset.defaultCharset());
            JSONObject jsonObject = JSONUtil.parseObj(content);
            jsonObject.forEach((key, value) -> {
                parmMap.put(key, value);
            });
            param.setBody(true);
            paramList.add(parmMap);
        } else {
            // 不支持其它方法
            throw new RuntimeException(""); // 这是个自定义的异常, 可删掉这一行
        }


        param.setData(paramList);
        return param;
    }
}

将参数映射成反射所需要的Object[]数组参数:

/**
 * 参数映射
 */
private Object[] mappingArgs(Method method, RequestParam param) {
    // 判断params不为空
    Class<?>[] parameterTypes = method.getParameterTypes();
    Object[] objects = new Object[parameterTypes.length];
    //是否是json报文体
    if (param.isBody()) {
        for (int i = 0; i < parameterTypes.length; i++) {
            Class<?> parameterType = parameterTypes[i];
            Map<String, Object> map = param.getData().get(i);
            Class<?> aClass;
            try {
                aClass = parameterType.newInstance().getClass();
            } catch (Exception e) {
                throw new RuntimeException("参数类型错误");
            }
            Object o = JSONUtil.toBean(JSONUtil.parseObj(map), aClass);
            objects[i] = o;
        }
    } else {
        List<Map<String, Object>> data = param.getData();
        String[] parameterNames = new LocalVariableTableParameterNameDiscoverer().getParameterNames(method);
        for (int i = 0; i < parameterNames.length; i++) {
            String parameterName = parameterNames[i];
            for (int j = 0; j < data.size(); j++) {
                Map<String, Object> map = data.get(j);
                if (map.containsKey(parameterNames[i])) {
                    Object o = map.get(parameterName);
                    objects[i] = o;
                }
            }
        }

    }
    return objects;
}

执行反射方法:

String content = (String) method.invoke(object, args);
举报

相关推荐

0 条评论