关于一次post请求参数为json格式时,HTTPServletRequest拿不到请求参数,从而记录一次笔记

  今天在试着搭建微服务zuul网关的时候,想到用zuul自带的过滤器来做一次token校验,结果就是为了图省事儿用了post方法传了json格式的参数,结果就是传了token参数,他就是校验不到。

自己在代码里用的 HTTPServletRequest来接受参数

 结果当然就是无论怎么传都接受不到了,对于getParameter这种获取方式,只能获取到表单形式(header),从而拿不到参数为json格式的post请求参数。(对于请求参数的获取方式大家自行百度吧哈哈,选择适合自己的最重要。)

所以更改取值方法,用I/O流去读取就可以拿到一个json类型的字符串,从而在取出自己想要的token去校验就可以了:

@Override
    public Object run() {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        log.info(String.format("%s >>> %s", request.getMethod(), request.getRequestURL().toString()));
//        Object accessToken = request.getParameter("token");
        Object accessToken = null;
        try {
            ServletInputStream inputStream = request.getInputStream();
            String s = CharStreams.toString(new InputStreamReader(inputStream, Charsets.UTF_8));
            JSONObject jsonObject = JSON.parseObject(s);
            accessToken = jsonObject.get("token");
            log.info("token值为:" + accessToken);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (accessToken == null) {
            log.warn("token is empty");
            requestContext.setSendZuulResponse(false);
            requestContext.setResponseStatusCode(401);
            try {
                requestContext.getResponse().getWriter().write("token is empty");
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
        log.info("check ok");
        return null;
    }

主要就是更改获取方式代码:

但是,既然涉及到I/O流了,就不得不提一下,流只能读取一次,所以request.getParameter()、 request.getInputStream()、request.getReader()这三种方法是有冲突的 ,还有就是controller中使用@RequestBody注解 是不能自动注入对象的,原因都是流只能一次读取,其ServletInputStream源码并没有重写reset()方法,read时postion一旦到了最终位置会返回一个-1,由于没有reset所以回不到最初的0位置从而无法重复读取。

之后就可以正常校验了