文章目录
前言
本文主要介绍了HttpServletRequest中获取消息行、消息头、获取表单数据所用的方法、请求的转发,以及一些注意事项。
一、获取请求消息行的方法
这部分内容很简单直接上代码:
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8"); //告诉服务器使用什么编码,要与浏览器传过来的编码一致
System.out.println("请求方法是:"+req.getMethod()); //获取请求方式
System.out.println("请求的URL是:"+req.getRequestURL()); //获取请求完整url
System.out.println("请求的URI是:"+req.getRequestURI()); //获取请求资源名部分
System.out.println("请求的当前目录(项目目录)是:"+req.getContextPath()); //获取当前目录(项目目录)<重要>
String queryString = req.getQueryString(); //获取url中参数部分
System.out.println("请求的参数是:"+URLDecoder.decode(queryString,"UTF-8"));
//这边对参数进行了解码,因为在url中直接输入中文不解码的话,拿到的会是带有百分号的那种字符串,无法正常展示
//这里还要注意一点,如果请求url没有带参数,这句话会报空指针,所以保险起见,用解码的时候,最好加上非空判断。
}
输出的结果如下图:
二、获取请求消息头的方法
代码演示两种方法:
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Enumeration<String> names = req.getHeaderNames(); //获得所有请求消息头的name,返回一个枚举类型
while (names.hasMoreElements()){
String key = names.nextElement();
System.out.println(key+":"+req.getHeader(key)); //根据请求头参数的key值获取对应的value值
}
}
还有一个request.getHeaders(key)的方法,获取的是具有相同key的请求头的value值,返回的一个枚举类型。
三、获取表单数据的方法
首先,我们先创建一个表单,如下:
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Register</title>
</head>
<body>
<form action="/java_web_day01/request/demo4" method="post">
用户名:<input type="text" name="userName"></br>
密 码:<input type="password" name="pwd"></br>
性 别:<input type="radio" name="sex" value="男" checked="checked">男
<input type="radio" name="sex" value="女">女</br>
爱 好:
<input type="checkbox" name="hobby" value="篮球">篮球
<input type="checkbox" name="hobby" value="唱歌">唱歌
<input type="checkbox" name="hobby" value="跳舞">跳舞
</br>
所在城市:
<select name="city">
<option>------请选择------</option>
<option value="BJ">北京</option>
<option value="SH">上海</option>
<option value="GZ">广州</option>
</select>
</br>
<input type="submit" value="注册">
</form>
</body>
</html>
1. 几个简单的方法介绍下用法:
request.getParameter(name):获取表单中,名字为name的值。
request.getParameterValues(name):获取复选框的值,返回一个数组类型;也可以获取只有一个值的表单。
request.getParameterNames():获取所有的表单的name,返回一个枚举类型。
2. 关于getParameterMap()的用法以及数据的封装
首先根据html表单中的数据封装一个User类,类中的属性要包含表单中所有name的数据,并且User类的属性名最好与name保持一致。注意这两点就可以了,这里就不放User类的创建代码了。
创建完成后,就可以写获取表单参数的代码,并封装成User对象,代码如下:
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
Map<String, String[]> map = req.getParameterMap();
//获取表单数据的map,返回的是一个Map<String, String[]>
User user = new User();
//创建User对象
for (String key : map.keySet()) {
String[] value = map.get(key);
try {
PropertyDescriptor p = new PropertyDescriptor(key, User.class);
//PropertyDescriptor这里运用到了反射的原理,key值是从表单中的name得到的
//我们创建的User对象的属性与name值是对应的,传入User的字节码对象,这时候,我们就可以通过反射拿到User中对应属性的get和set方法了。
Method method = p.getWriteMethod();
//getWriteMethod拿到的就是set方法(如果key是userName,那我们拿到的就是setUserName())
if(!key.equalsIgnoreCase("hobby")) {
//这里对hobby做一个区分,因为hobby是可以多选的,同样也可能只选了一个,所以直接区分是不是hobby,而不是区分value长度。
method.invoke(user, value[0]);
//不是hobby的那么,value里面只会有一个值,取出第一个值,就是我们要赋值给对应属性的值。
//反射的方法调用,传入user对象,以及set方法所需的参数,此时,我们就把拿到的表单数据的值保存在了User对象中
}else {
method.invoke(user, (Object)value);
//这里value是一个数组,根据反射传入参数的方式,这里必须强转成Object类型才可以传入数组
}
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println(user);
}
上面这种方法需要我们自己对数据进行区分判断,有一点点麻烦,Apache提供了一个工具叫BeanUtils,用起来就非常简单了。下面是这种方法的实现:
首先,我们需要安装这个工具,因为我使用的是maven工程,所以直接找到这个工具的坐标加到pom.xml文件中,具体版本如下:
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
<!--maven仓库里还有更新的版本,我选了个使用人数相对更多的-->
</dependency>
代码如下:
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
try {
User user = new User();
BeanUtils.populate(user, req.getParameterMap());
//这里一行就可以搞定,非常简单
System.out.println(user);
} catch (Exception e) {
e.printStackTrace();
}
}
小结:这里显然更推荐使用Apache提供的工具了,完全不用考虑表单数据是一个值还是多个值,工具都会帮我处理好,我们只需要创建好我们自己的对象就可以了。不过还是把另一种方式记录下来,有助于我们理解反射的使用。
3. 使用getInputStream()获取表单数据
getInputStream()得到的是一个ServletStream对象,我们用读取流对象的方式来读取,用的表单还是上面那个,代码如下:
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
ServletInputStream inputStream = req.getInputStream();
int len;
byte[] arr = new byte[1024];
while ((len=inputStream.read(arr))!=-1){
String s = new String(arr, 0, len);
s = URLDecoder.decode(s,"UTF-8");
//这里需要对拿到的数据进行解码操作,要不然读取到的数据会是乱码的
System.out.println(s);
}
inputStream.close();
}
这种方式拿到的数据如下图:
四、请求的转发
最后我们来看下转发,之前我们了解了使用ServletContext实现转发,这里我们使用Request,达到的效果和之前是一样的。
代码如下:
@Override
//实现转发的代码
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("即将为您转发......");
req.getRequestDispatcher("/request/demo6").forward(req,resp);
System.out.println("业务处理完成啦!");
}
@Override
//实际业务处理的代码
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("业务正在处理中......");
}
输出结果:
总结
关于HttpServletRequest的方法就介绍到这里啦,其实方法都是很简单的,个人学习下来的感觉,比较麻烦的是编码的问题,通常我们在代码开始前加上setCharacterEncoding(“UTF-8”)这句话,但是有些编码问题还是不能解决,就需要用到其他的方式去解决,比如本文多处用到的解码方法。这类问题多多积累解决方法就好了。