java参数解析
A. java 解析http请求数据
string p1=request.getParameter("p1");
string p2=request.getParameter("p2");
这样就获取到数据了,然后你就可以存进数据库中或者进行数据处理。
B. java解析出url请求的路径和参数键值对类
解析url,本想用正则表达式处理,但正则表达式速度较慢。用split处理一下就可以了。
packageRequestPackage;
importjava.util.HashMap;
importjava.util.Map;
publicclassCRequest{
/**
*解析出url请求的路径,包括页面
*@paramstrURLurl地址
*@returnurl路径
*/
publicstaticStringUrlPage(StringstrURL)
{
StringstrPage=null;
String[]arrSplit=null;
strURL=strURL.trim().toLowerCase();
arrSplit=strURL.split("[?]");
if(strURL.length()>0)
{
if(arrSplit.length>1)
{
if(arrSplit[0]!=null)
{
strPage=arrSplit[0];
}
}
}
returnstrPage;
}
/**
*去掉url中的路径,留下请求参数部分
*@paramstrURLurl地址
*@returnurl请求参数部分
*/
(StringstrURL)
{
StringstrAllParam=null;
String[]arrSplit=null;
strURL=strURL.trim().toLowerCase();
arrSplit=strURL.split("[?]");
if(strURL.length()>1)
{
if(arrSplit.length>1)
{
if(arrSplit[1]!=null)
{
strAllParam=arrSplit[1];
}
}
}
returnstrAllParam;
}
/**
*解析出url参数中的键值对
*如"index.jsp?Action=del&id=123",解析出Action:del,id:123存入map中
*@paramURLurl地址
*@returnurl请求参数部分
*/
publicstaticMap<String,String>URLRequest(StringURL)
{
Map<String,String>mapRequest=newHashMap<String,String>();
String[]arrSplit=null;
StringstrUrlParam=TruncateUrlPage(URL);
if(strUrlParam==null)
{
returnmapRequest;
}
//每个键值为一组www.2cto.com
arrSplit=strUrlParam.split("[&]");
for(StringstrSplit:arrSplit)
{
String[]arrSplitEqual=null;
arrSplitEqual=strSplit.split("[=]");
//解析出键值
if(arrSplitEqual.length>1)
{
//正确解析
mapRequest.put(arrSplitEqual[0],arrSplitEqual[1]);
}
else
{
if(arrSplitEqual[0]!="")
{
//只有参数没有值,不加入
mapRequest.put(arrSplitEqual[0],"");
}
}
}
returnmapRequest;
}
}
测试类
packageRequestPackage;
importjava.util.Map;
publicclassTestCRequest{
/**用于测试CRequest类
*@paramargs
*/
publicstaticvoidmain(String[]args){
//请求url
Stringstr="index.jsp?Action=del&id=123&sort=";
//url页面路径
System.out.println(CRequest.UrlPage(str));
//url参数键值对
StringstrRequestKeyAndValues="";
Map<String,String>mapRequest=CRequest.URLRequest(str);
for(StringstrRequestKey:mapRequest.keySet()){
StringstrRequestValue=mapRequest.get(strRequestKey);
strRequestKeyAndValues+="key:"+strRequestKey+",Value:"+strRequestValue+";";
}
System.out.println(strRequestKeyAndValues);
//获取无效键时,输出null
System.out.println(mapRequest.get("page"));
}
}
测试代码运行效果
index.jsp
key:id,Value:123;key:sort,Value:;key:action,Value:del;
null
C. java代码解析
图发不上来,请看参考资料连接
初学的话只要了解值传递不会改变,引用传递会改变。
至于原理,有兴趣的话可以了解一下。下面讲得很详细
讲解:按值传参与按引用传参
----------------------------------------------------------------------------
类中包含方法,方法又分为方法声明和方法实现,方法声明中又有参数列表,参数根据调用后的效果不同,即是否改变参数的原始数值,又可以分为两种:按值传递的参数与按引用传递的参数。
他们的区别是什么呢?上面旺旺老师是说调用后的效果,我们看一个案例说明:比如有个女孩非常喜欢QQ,还给自己起了个浪漫的名字“轻舞飞扬”,飞扬小姐认识了一个网友“痞子蔡”(n年前非常火的一个网络小说《第一次亲密接触》的两个主人公),他们聊的很投缘,有天飞扬小姐竟然把自己的电话号码告诉了痞子蔡,有天痞子蔡竟然电话过来约飞扬小姐见面,考虑到网络的虚幻与现实人心的叵测,飞扬小姐面临着艰难的选择:是否去见网友?
那么见网友就是个方法,方法的参数就是轻舞飞扬,如果痞子蔡是个披着羊皮的狼,那飞扬小姐就可能面临危险,比如身上少些东西或者多些东西,就是说在方法体中有可能改变参数的原始数值。
现实中飞扬小姐只有两种选择,第一,为了爱情奋不顾身,上刀山下火海,再所不辞,但这有可能改变飞扬状态,即数值;第二,委婉拒绝以求自保,但如果痞子蔡为人特别好,比如像旺旺老师这样(呕吐中),她也许会失去一段大好的姻缘。这里,如果科技足够发达,我们可以完全给出第三种选择,轻舞飞扬制作一个自己的替身,即把自己备份一份,然后把备份传入方法体,这样不论痞子蔡对她做了什么都不会对她的源体发生影响,又能检测痞子蔡对自己是否真心。
OK,这里我们就把飞扬小姐本人去见网友叫按引用传递,这样在方法体中发生的改变在方法调用完对参数还有影响,而把让她替身去叫按值传递,这样方法调用完对参数原始数值没有影响,发生改变的只是参数的备份,这份备份在方法调用完会自动消亡,也就是说飞扬的替身在见完网友自动消亡。最后可以简单概括为一句话:按值传递参数数值不变,按引用传递参数数值改变。
我们上面刚学习了JAVA的数据类型,则有:值类型就是按值传递的,而引用类型是按引用传递的。下面看一个例子:
public class TestValueAndRef {
public static void main(String[] args) {
Student student = new Student();
student.stuAge = 10;
int a = 10;
int arr[] = new int[]{9, 5, 27};
System.out.println("初始值 a = " + a);
System.out.println("初始值 student.stuAge = " + student.stuAge);
System.out.println("初始值 arr[0] = " + arr[0]);
TestValueAndRef testValueAndRef = new TestValueAndRef();
testValueAndRef.change(a, student, arr);
System.out.println("调用函数后 a = " + a);
System.out.println("调用函数后 student.stuAge = "
+ student.stuAge);
System.out.println("调用函数后 arr[0] = " + arr[0]);
}
public void change(int pa, Student pstu, int[] parr) {
//方法体中改变值类型pa的值
pa = pa + 10;
//方法体中改变引用类型stu,parr的值
pstu.stuAge = pstu.stuAge + 10;
parr[0] = parr[0] + 10;
System.out.println("方法体改变后pa = " + pa);
System.out.println("方法体改变后student.stuAge = "
+ student.stuAge);
System.out.println("方法体改变后parr[0] = " + parr[0]);
}
}
运行结果:
--------------------------------------------------------------------------
初始值 a = 10
初始值 student.stuAge = 10
初始值 arr[0] = 9
方法体改变后pa = 20
方法体改变后student.stuAge = 20
方法体改变后parr[0] = 19
调用函数后 a = 10
调用函数后 student.stuAge = 20
调用函数后 arr[0] = 19
---------------------------------------------------------------------------------
我们看到,基本数据类型int变量a虽然在方法体中改变了数值,但方法调用完后其原始数值并没有改变。而引用数据类型Student在方法体中改变年龄的数值,方法执行完其数值发生了改变,数组也是引用类型,所以其值也发生了改变。也就是说:按值传递参数数值不变,按引用传递参数数值改变。它们在内存中的变化如下所示:
根据上面讲解的值类型和引用类型的知识,int类型变量在栈中分配一块内存,而student与arr分配两块内存,当方法调用时,创建三个变量pa,pstu,parr这里相当于把栈中的数据全备份一份给这三个数值,则有:
大家看到,不管是按值传递还是按引用传递,都是把栈中的数据备份了一份给参数变量,只不过值类型备份的是具体的数值,而引用类型备份的是内存地址。
方法体执行完时:
我们看到,根据pstu与parr改变了堆中的具体数值,而pa改变的只是栈中的数值。最后方法调用结束,pstu,pa,parr三个变量消亡,则有:
根据这样的内存变换,您知道按值传递与按引用传递的深层原因了吗