httpServletRequest.getParameter 参数中存在“&”导致获取不到完整参数的问题
记录最近遇到的坑。
起因
账管有个信用卡绑定接口,我的调用的时候需要传号码、地址等信息,使用的是 HttpURLConnection,发送的时候将参数转为key=value&key=value 的形式,账管那边使用 httpServletRequest.getParameter() 进行获取参数。
问题就是当某些地址中存在 & 符号的时候,因为账管获取参数的时候是通过 & 符号进行截取的,就会导致他们获取参数不全。
如:a=123&b=park¢er
本来 b 的 value 应该是 park¢er,现在他们那边只能获取到 park,这就导致两边参数不一样,签名也不一样,然后验签失败。
解决方案
以上就是事情的起因,期初我的建议是他们那边能不能换成 json 格式的接收,我们这边直接发送 json 格式的数据,这样应该不会有问题,但是他们死活不愿意改。
后续方案是我们将参数中的 & 进行 URL 编码,将其转化为 %26。
我们实现的方法大概如下:
public String pay(String url, Map<String, String> params) { URL u = null; HttpURLConnection con = null; // 构建请求参数 StringBuffer sb = new StringBuffer(); String strResult = null; if (params != null) { for (Entry<String, String> e : params.entrySet()) { sb.append(e.getKey()); sb.append("="); sb.append(e.getValue()); sb.append("&"); } strResult = sb.substring(0, sb.length() - 1); } // 尝试发送请求 try { u = new URL(url); con = (HttpURLConnection) u.openConnection(); // POST 只能为大写,严格限制,post会不识别 con.setRequestMethod("POST"); con.setDoOutput(true); con.setDoInput(true); con.setUseCaches(false); con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream(), "UTF-8"); osw.write(sb.toString()); osw.flush(); osw.close(); } catch (Exception e) { e.printStackTrace(); } finally { if (con != null) { con.disconnect(); } } // 读取返回内容 StringBuffer buffer = new StringBuffer(); try { //一定要有返回值,否则无法把请求发送给server端。 BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8")); String temp; while ((temp = br.readLine()) != null) { buffer.append(temp); } } catch (Exception e) { logger.error("*****报错:", e); } return buffer.toString(); }
改造为:
String value = e.getValue(); if (value.contains("&")) { try { // URL编码,针对“&”进行处理,防止截取参数不完整导致验签失败 value = URLEncoder.encode(value, "UTF-8"); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } } sb.append(value);
分析原因
使用 httpServletRequest.getParameter 接收post请求参数,发送端 content Type 必须设置为 application/x-www-form-urlencoded;否则会接收不到
使用 httpServletRequest.getParameter 也是获取不到 json 格式的数据的,发送端只能发送 key=value&key=value 格式的数据。所以如果需要发送 json 格式的数据,两边都需要进行改造。
application/x-www-form-urlencoded 通过表单提交,在sevlet实现中,mutipart/form-data 和 application/x-www-form-urlencoded 会被特殊处理,请求参数将被放置于 request.paramter,这是一个map。
我们可以从map中获取参数进行验证,或者其他拦截需求,map的获取类似hibernate的延迟加载,当调用 request.getparamter() 方法,servlet才会从请求流中读取请求参数加载入map。InputStream 也会存有这份数据,但如果这份数据被读取,那么到了controller层将无法读出数据,同样,拦截之后到达controller层时请求数据已经被加载入了controller层方法实参,实参对象需要有set方法,框架会以反射的方式调用属性的set方法注入数据,数据只会被注入到已有的属性。
当以 application/json 的 content-type 传送数据,被传送的对象只需被json序列化。当以 application/x-www-form-urlencoded 的方式传送数据。请求的内容需要以…=…&…=…的格式提交,在请求体内内容将会以”&”和“ = ”进行拆分。
- springMvc 完美解决 multipart/form-data 方式提交请求 在 Filter 中 ServletRequest.getParameter方法 获取不到参数的问题
- springMvc 完美解决 multipart/form-data 方式提交请求 在 Filter 中 ServletRequest.getParameter方法 获取不到参数的问题
- springMvc 完美解决 multipart/form-data 方式提交请求 在 Filter 中 ServletRequest.getParameter方法 获取不到参数的问题
- HttpServletRequest. getParameter获取的参数格式
- Web HttpServletRequest的getRequestURL方法获取不到https协议请求问题
- 【错误记录】HttpServletRequest.getParameter获取不到数据
- 过滤器中处理multipart/form-data头部的post请求request.getParameter(")获取不到参数问题
- 解决apache/nginx做反向代理导致request.getServerName()外网环境获取不到代理地址(或域名)的问题
- 解决apache/nginx做反向代理导致request.getServerName()外网环境获取不到代理地址(或域名)的问题
- 解决apache/nginx做反向代理导致request.getServerName()外网环境获取不到代理地址(或域名)的问题
- 20170325-HttpServletRequest中获取参数问题
- 解决apache/nginx做反向代理导致request.getServerName()外网环境获取不到代理地址(或域名)的问题
- HttpServletRequest获取中文参数乱码问题
- request.getParameter()获取不到数据的问题
- 解决apache/nginx做反向代理导致request.getServerName()外网环境获取不到代理地址(或域名)的问题
- SpringMVC中使用Ajax POST请求以json格式传递参数服务端通过request.getParameter("name")无法获取参数值问题分析
- 解决apache/nginx做反向代理导致request.getServerName()外网环境获取不到代理地址(或域名)的问题
- 在servlet中GET请求可以通过HttpServletRequest的getRequestURL方法和getQueryString()得到完整的请求路径和请求所有参数列表,POST的需要getPa
- 解决apache/nginx做反向代理导致request.getServerName()外网环境获取不到代理地址(或域名)的问题
- 解决apache/nginx做反向代理导致request.getServerName()外网环境获取不到代理地址(或域名)的问题