关于一次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位置从而无法重复读取。
之后就可以正常校验了