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字符的文本或二进制数据时这种编码方式效率很低




郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。