【前言】本篇的主旨是编写基础代码解释客户端的get和post数据(不包括对中文乱码的修正,也不包括对文件流的解释,下篇会涉及文件上传),假如你是搜索来到这里的话,就表示你遇到了类似的问题,这个问题与http的数据格式有一点点关系,你可以查阅这篇文章得到基础知识:
http://pplxh.blog.51cto.com/729279/221921
【正文】
先上代码再解释:
package Easis.HTTP;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.Map;
import java.util.regex.Pattern;
/**
* Created with IntelliJ IDEA.
* User: Administrator
* Date: 13-4-28
* Time: 下午9:03
* To change this template use File | Settings | File Templates.
*/
public class RequestEnhance {
private String _RequestContent="";
private String _QueryString="";
private String _QueryString_Handled="";
private String _urlEncoding="";
public static String UrlEncoding_GBK="GBK";
public static String UrlEncoding_UTF8="utf-8";
public static String UrlEncoding_ISO_8559_1="iso-8559-1";
private HttpServletRequest _RequestCopy=null;
private Hashtable<String,String> _paras_by_get=new Hashtable<String, String>();
private Hashtable<String,String> _paras_by_post=new Hashtable<String, String>();
public RequestEnhance(HttpServletRequest request,String URLEncoding){
_init(request,URLEncoding);
}
///这里要利用原始的requeset对象来获取querystring及getReader,
///注意:使用了getReander以后你就无法在
///原始的request对象再使用getParameter,getInputStream及getReader了,
///作为补偿,这里用getRequestContent来给大家访问最原始的request正文内容。
public RequestEnhance(HttpServletRequest request){
_init(request,"");
}
private void _init(HttpServletRequest request,String URLEncoding){
this._urlEncoding=URLEncoding;
this._RequestCopy=request;
try{
this._QueryString=request.getQueryString();
BufferedReader bf=request.getReader();
String tmp1=bf.readLine();
StringBuilder sb2=new StringBuilder();
while (tmp1!=null){
sb2.append(tmp1);
tmp1=bf.readLine();
}
bf.close();
this._RequestContent=sb2.toString();
this.InitParamByGet(this._QueryString);
//--处理表单数据,注意三种方式,“multipart/form-data”、“text/plain”、“application/x-www-form-urlencoded”
InitParamByPost();
String End11="";
}
catch (Exception e){
e.printStackTrace();
}
}
private void InitParamByGet(String URLQUERY) throws Exception{
String _str=URLQUERY;
if(URLQUERY==null||URLQUERY.trim().length()<1){}
else{
_str=URLQUERY.trim();
_str= URLQUERY.replaceAll("&+","&");
this._QueryString_Handled=_str;
String[] str_res= _str.split("&+");
if(str_res!=null&&str_res.length>0){
for(String tmp_mix:str_res){
String[] t_arr_key_value=tmp_mix.split("=",2);
if(t_arr_key_value!=null&&t_arr_key_value.length>1){
String s1= t_arr_key_value[0];
if(this._urlEncoding.length()<1){
String tKey=new String(t_arr_key_value[0].getBytes());
String tValue=new String(t_arr_key_value[1].getBytes());
this._paras_by_get.put(tKey,tValue);
}
else{
String tKey=new String(t_arr_key_value[0].getBytes(this._urlEncoding));
String tValue=new String(t_arr_key_value[1].getBytes(this._urlEncoding));
this._paras_by_get.put(tKey,tValue);
}
}
}}}}
public String getQueryString(){
return _QueryString;
}
public String getRequestContent(){
return _RequestContent;
}
public String getQueryStringHandled(){
return _QueryString_Handled;
}
private void InitParamByPost() throws Exception {
String _contentType= this._RequestCopy.getContentType();
if(_contentType.equals("text/plain")){}
else if(_contentType.equals("application/x-www-form-urlencoded")){
_initParam_application_x_www_form_urlencoded();
}
else if(_contentType.equals("multipart/form-data")){}
else{
throw new Exception("please make sure that you form data has a certain content type(one of \"text/plain\" or \"application/x-www-form-urlencoded\" or \"multipart/form-data\")");
}
}
///这个用于处理普通post文档,application/x-www-form-urlencoded,(浏览器默认的是这个无法传送文件,解释方式与url的一样)
private void _initParam_application_x_www_form_urlencoded() throws Exception{
String _str=this._RequestContent==null?"":this._RequestContent.trim();
if(_str==null||_str.trim().length()<1){}
else{
_str= _str.replaceAll("&+","&");
this._QueryString_Handled=_str;
String[] str_res= _str.split("&+");
if(str_res!=null&&str_res.length>0){
for(String tmp_mix:str_res){
String[] t_arr_key_value=tmp_mix.split("=",2);
if(t_arr_key_value!=null&&t_arr_key_value.length>1){
String s1= t_arr_key_value[0];
if(this._urlEncoding.length()<1){
String tKey=new String(t_arr_key_value[0].getBytes());
String tValue=new String(t_arr_key_value[1].getBytes());
this._paras_by_post.put(tKey,tValue);
}
else{
String tKey=new String(t_arr_key_value[0].getBytes(this._urlEncoding));
String tValue=new String(t_arr_key_value[1].getBytes(this._urlEncoding));
this._paras_by_post.put(tKey,tValue);
}
}
}}}
}
///只有encryptype为multipart/form-data的表单会发送文档流。
private void _initParam_multipart_form_data(){}
///这个处理text/plain方式的字符串(不知道如何处理,假如是a1=value1&a2=value2,那么就变成:a1=value1a2=value2,处理不了。)
private void _intParam_text_plain(){}
public Hashtable<String,String> getUrlParas(){
return this._paras_by_get;
}
}
上面的代码主要是对下面两种情况获取参数:
1、xx.jsp?p1=v1&p2=v2.....
2、使用表单且表单的method=post,enctype=application/x-www-form-urlencoded时候的参数解释。
经过初步的调试及参数查看,两者的格式都是 键1=值1&键2=值2 ,解释起来很简单,
但是对于text/plain的表单,它的数据格式是 username=usernamevaluepassword=thisisthepassword
连分隔符都不见,暂时想不到分离参数的方法。
下一篇将尝试解释从客户端传过来的文件流(enctype="multipart/form-data"的情况),不过经过我对IE,chrome的调试,发现了很有用处的东西,似乎是文件流的分隔符,如下图: