request 获取请求的正文

来源:互联网 发布:qq防撤回软件 编辑:程序博客网 时间:2024/05/17 09:07

今天和大家探讨一下request是怎样获取请求正文的。

先看下申请请求的前端。

<html>  <head>    <title>login </title>  </head>  <body><form action="/day08_69_requestresponse/RequestDemo3" method="post">    用户名:<input type="text" name="username" /><br/>    密码:<input type="password" name="password" /><br/>    确认密码:<input type="password" name="password" /><br/>    性别:<input type="radio" name="sex" value="1" checked>男    <input type="radio" name="sex" value="0">女    <br/>    <input type="submit" value="注册" /></form>  </body></html>


一开始我们可以先这样简单的获取一下web前端传来请求正文(包括字段 username,password,sex)。此时不包括确认密码。

//获取请求的正文,根据名称获取值  正文的体现形式是:key=value 和请求的方式没有关系(get和post方式都可以取到)没有使用确认密码private void test1(HttpServletRequest request)throws ServletException, IOException {String username = request.getParameter("username");String password = request.getParameter("password");String sex = request.getParameter("sex");System.out.println(username+","+password+","+sex);}
然后我们加上确认密码,那么就出现了一个问题,password的字段有两个,一个是密码框,一个是确认密码框。所以我们把password看成一个数组。可以这样写。

//获取请求的正文,根据名称获取值。使用了确认密码private void test2(HttpServletRequest request)throws ServletException, IOException {String username = request.getParameter("username");String[] password = request.getParameterValues("password");String sex = request.getParameter("sex");System.out.println(username+","+Arrays.asList(password)+","+sex);}
这样解决了问题,但是我们每次通过已知字段去获取值如果字段较少是可以,但是如果很多就非常麻烦了。于是我们可以用枚举首先获取到所有正文中的字段。然后通过这些字段再去找值。

private void test3(HttpServletRequest request)throws ServletException, IOException {Enumeration<String> names = request.getParameterNames();//遍历名称的枚举while(names.hasMoreElements()){String name = names.nextElement();String value = request.getParameter(name);System.out.println(name+","+value);}}
可是我们获取了这些数据最终要传到数据操作层去操作的,如果字段很多,我们获取出来后需要一个一个的传参,那么就显得很麻烦,因此我们考虑用一个user对象来封装下,就是我们所说的实体,这样就可以传一个实体解决问题了。(此时我们先不加入确认密码。)

//获取请求的正文,封装到User对象中没有使用确认密码油漆工方法,不建议使用private void test4(HttpServletRequest request)throws ServletException, IOException {String username = request.getParameter("username");String password = request.getParameter("password");String sex = request.getParameter("sex");//定义一个User对象User user = new User();System.out.println("封装前:"+user.toString());user.setUsername(username);user.setPassword(password);user.setSex(sex);System.out.println("封装后:"+user.toString());}
这样虽然传参的时候通过传递实体简化了传参过程,可是这样也是有问题的,因为看上面的代码我们知道我们需要获取一个值设置一个值,现在是三个字段,如果字段过多这样就显得很麻烦,因此这个也叫油漆工方法,其实我一开始写项目的时候就是用的这个方法。所以为了解决一个个设置参数给user很麻烦的问题,我们可以用java中的反射和内省这样写。(此时我们也先不考虑确认密码)

//使用反射和内省封装javabean 要求:必须命名规范。表单中name属性的值和javabean中属性对应没有使用确认密码private void test5(HttpServletRequest request)throws ServletException, IOException {Enumeration<String> names = request.getParameterNames();User user = new User();System.out.println("封装前:"+user.toString());//遍历名称的枚举while(names.hasMoreElements()){String name = names.nextElement();String value = request.getParameter(name);try{//获取一个属性描述器,指定的javabean的属性描述器PropertyDescriptor pd = new PropertyDescriptor(name, User.class);//获取写的方法Method method = pd.getWriteMethod();//执行method方法method.invoke(user, value);}catch(Exception e){e.printStackTrace();}}System.out.println("封装后:"+user.toString());}
现在看起来就很符合我们的需求了,既不用一个个取值,也不用一个个设置值。但是问题来了,如果我们加上确认密码呢,那么这样就没法使用了,因为password需要有两个值。而其他的一个就可以。要解决这个问题,我们先看下下面的代码,使用Map集合泛型使用<String,String[]>的形式来解决这个问题。

//获取请求的正文。使用map的形式。 map的key是表单输入域名称,value是值的数组使用确认密码private void test6(HttpServletRequest request)throws ServletException, IOException {Map<String,String[]> map = request.getParameterMap();//使用增强for遍历mapfor(Map.Entry<String, String[]> me : map.entrySet()){String name = me.getKey();String[] values = me.getValue();System.out.println(name+","+Arrays.asList(values));}}
这样就解决了这个问题,然后在加上我们原来的反射和内省就变得完美了。

//使用反射和内省封装请求的正文到Users的javabean中使用确认密码private void test7(HttpServletRequest request)throws ServletException, IOException {Map<String,String[]> map = request.getParameterMap();Users user = new Users();System.out.println("封装前:"+user.toString());//使用增强for遍历mapfor(Map.Entry<String, String[]> me : map.entrySet()){String name = me.getKey();String[] values = me.getValue();try{//获取Users的属性描述器PropertyDescriptor pd = new PropertyDescriptor(name, Users.class);//获取属性的写方法Method method = pd.getWriteMethod();//执行方法if(values.length>1){method.invoke(user, new Object[]{values});}else{method.invoke(user, values);}}catch(Exception e){e.printStackTrace();}}System.out.println("封装后:"+user.toString());}
最后在和大家分享一个更加简单的方法,那就是使用apache的第三方资源包,beanutils实现请求正文的封装,其实就是封装了test7 中的内容,而阿帕奇给我们封装好了,直接使用就行。但是要注意的是,使用这种方法必须命名和login中的字段完全相同,才可以使用,这就是我们所说的约定优于编码。

//使用apache的第三方资源包,beanutils实现请求正文的封装使用确认密码private void test8(HttpServletRequest request)throws ServletException, IOException {Users user = new Users();System.out.println("封装前:"+user.toString());try{BeanUtils.populate(user, request.getParameterMap());}catch(Exception e){e.printStackTrace();}System.out.println("封装后:"+user.toString());}

如果哪里不对希望大家提出来。谢谢大家了。敬请斧正。








0 0