http content_type multipart/form-data 和 application/x-www-form-urlencoded的区别
最近在做一个APP时,服务端需要在记录日志,记录所有请求过来的URL、IP以及参数,说道参数,那么问题来了,我是用过滤器来记录日志的,来看我在过滤器里面是怎么写的:
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) arg0; // 获取URL String url = request.getRequestURL().toString(); // 获取参数 /*StringBuffer info=new java.lang.StringBuffer(); InputStream in=request.getInputStream(); BufferedInputStream buf=new BufferedInputStream(in); BufferedInputStream bufBak=buf; byte[] buffer=new byte[1024]; int iRead; while((iRead=buf.read(buffer))!=-1) { info.append(new String(buffer,0,iRead,"UTF-8")); } logger.info(info.toString()+"------xxxxx------");*/ /* Collection<Part> ps= request.getParts(); for(Part p:ps){ Collection<String> cs=p.getHeaderNames(); for(String s:cs){ logger.info("------Collection----"+s); } }*/ String name=request.getParameter("userId"); logger.info("--------name------------"+name); Map<String,String[]> map = request.getParameterMap(); String queryString = ""; for (String key : map.keySet()) { String[] values = map.get(key); for (int i = 0; i < values.length; i++) { String value = values[i]; queryString += key + "=" + value + "&"; } } logger.info("--------------------"+queryString); String userId=null; //获取用户ID String[] userIds = (String[]) map.get("userId"); if(null!=userIds&&0<userIds.length){ userId=userIds[0]; } //活动区IP String ip = this.getClientIp(request); logger.info(url + " " + gson.toJson(map) + " " + ip + " " +userId); //logger.info(arg0.hashCode()+"-------hashCode-------------"+req.hashCode()); arg2.doFilter(arg0, arg1); }
可是运行后发现request.getParameterMap() 获取不到数据,怎么回事呢?
后来,我找Andriod客户端开放人员看了一下他们的客户端的请求代码,发现他们是用HttpURLConnection来进行请求的,大概的代码如下:
URL url = new URL(u); HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); // 设置是否向httpUrlConnection输出,因为这个是post请求,参数要放在 // http正文内,因此需要设为true, 默认情况下是false; urlConn.setDoOutput(true); // 设置是否从httpUrlConnection读入,默认情况下是true; urlConn.setDoInput(true); // Post 请求不能使用缓存 urlConn.setUseCaches(false); // 设定传送的内容类型是可序列化的java对象 // (如果不设此项,在传送序列化对象时,当WEB服务默认的不是这种类型时可能抛java.io.EOFException) urlConn.setRequestProperty("Content-Type","multipart/form-data; boundary="+"00content0boundary00\r\n"); //application/x-java-serialized-object //urlConn.setRequestProperty("Content-type","application/x-www-form-urlencoded"); // 设定请求的方法为"POST",默认是GET urlConn.setRequestMethod("POST"); // 连接,上面对urlConn的所有配置必须要在connect之前完成, urlConn.connect(); /* * Post传参的方法 */ OutputStream os = urlConn.getOutputStream(); String param = new String(p);//参数以逗号分隔的字符串eg.name=xiaoming,age=23,sex=0 os.write(param.getBytes()); // 调用HttpURLConnection连接对象的getInputStream()函数, // 将内存缓冲区中封装好的完整的HTTP请求电文发送到服务端。 StringBuffer info=new java.lang.StringBuffer(); InputStream inStrm = urlConn.getInputStream(); // <===注意,实际发送请求的代码段就在这里 BufferedInputStream buf=new BufferedInputStream(inStrm); byte[] buffer=new byte[1024]; int iRead; while((iRead=buf.read(buffer))!=-1) { info.append(new String(buffer,0,iRead,"UTF-8")); } System.out.println(info.toString()+"------xxxxx------"); return info.toString();
客户端的请求Content-Type设置成了
multipart/form-data; boundary="+"00content0boundary00\r\n"
这是一种对媒体MIME的格式,一般用来传输大文本或二进制文件上载。所以在request.getParameterMap()里面不能获取到客户端请求上来的参数
如果Content-Type设置成
application/x-www-form-urlencoded就可以通过request.getParameterMap()获取到参数了,但是在向服务器发送大量的文本、包含非ASCII字符的文本或二进制数据时这种编码方式效率很低
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。