一:介绍
1)HttpServletRequest接口来自于Servlet规范中,在Tomcat中存在servlet-api.jar
2)HttpServletRequest接口实现类由Http服务器负责提供
3)HttpServletRequest接口负责在doGet/doPost方法运行时读取Http请求协议包中的信息
4)开发人员习惯于将HttpServletRequest接口修饰的对象称为【请求对象】
二:作用
1)可以读取Http请求协议包中【请求行】信息
2)可以读取保存在Http请求协议包中【请求头】或则【请求体】中请求参数信息
3)可以代替浏览器向Http服务器申请资源文件调用
三:代码实例
下面我们就来对上述提到的三个作用来进行下代码实例:
1:读取Http请求协议包中【请求行】信息
我们都知道在http请求协议包中的请求行中放入的是我们的URL地址和我们的请求方法等,那么当程序员想要获得这些信息的时候,该如何获取呢?
此时当然少不了我们的请求对象req了,通过请求对象req来调用getRequestURL方法和getMethod方法便可以获取到了,下面来看代码:
public class OneServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.通过请求对象,读取【请求行】中【url】信息 String url = request.getRequestURL().toString(); //2.通过请求对象,读取【请求行】中【method】信息 String method = request.getMethod(); System.out.println("URL "+url); System.out.println("method "+method); } }
输出结果为:
下面再来拓展一个概念:URI
URI:资源文件精准定位地址,在请求行并没有URI这个属性。URI 实际上是从URL中截取一个字符串,这个字符串格式为"/网站名/资源文件名"
作用:URI用于让Http服务器对被访问的资源文件进行精准定位
下面来看代码,假设此时的URL的路径为http://localhost:8080/myweb/one,那么最终的URI的路径应该为/myweb/one
public class OneServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //通过请求对象,读取【请求行】中uri信息 String uri = request.getRequestURI(); System.out.println("URI "+uri); } }
输出结果为:
2:读取Http请求协议包中【请求头】或则【请求体】中请求参数信息
此处我们可以通过request.getParameterNames来获取到我们的所有的参数名称(注意getParameterNames方法的返回值为枚举类型Enumeration),然后通过while循环遍历得到每一个参数名称,最终再通过request.getParameter(参数名称)来获取到所有参数名称对应的value值,下面来看代码:
public class TwoServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.通过请求对象request获得【请求头】中【所有请求参数名】 Enumeration paramNames =request.getParameterNames(); //将所有请求参数名称保存到一个枚举对象进行返回 while(paramNames.hasMoreElements()){ String paramName = (String)paramNames.nextElement(); //2.通过请求对象读取指定的请求参数的值 //利用getParameter方法便可以读值 String value = request.getParameter(paramName); System.out.println("请求参数名 "+paramName+" 请求参数值 "+value); } } }
此时我们写一个前端请求,方法为get(注意如果没有指明特定的请求方法的话,浏览器默认都是get方法),代码如下所示:
<form action="/myweb/two" method="get"> 用户名称:<input type="text" name="username"/> 用户密码:<input type="password" name="Password"/> <input type="submit" value="提交按钮:get方式访问servlet"/> </form>
注意此处的action中的请求地址为/myweb/one,myweb为发布时的项目名,two为当我们定义TwoServlet接口实现类来处理此前端请求时,我们给这个请求设置的简短请求别名,如果有同学有疑问,可以在我的这篇博客:https://blog.csdn.net/qq_41972686/article/details/116899756处点击查看具体的web.xml配置文件中关于url-pattern设置简短请求别名的讲解。
前端中需要注意的一个点就是input标签中的name属性,其就是负责在请求中为我们传递参数值的参数名称,这个name属性非常重要!!。
假设此时我们在用户名称处填写的名字为宋彪,用户名密码处填写的密码为123456,那么当我们点击提交后最终在浏览器中参数传递的格式为:
http://localhost:8080/myweb/two?username=宋彪&Password=123456
这个格式非常重要,必须背会,所有浏览器都是这样提交数据的:name=value&name=value&name=value
那么当我们点击提交后,最终在TwoServlet中我们所获得的结果为:
3:解决[POST]请求方式中发送中文参数乱码的情况
还是接着上面的例子:我们继续写一个请求,方法为【POST】:
<form action="/myweb/three" method="post"> 用户名称:<input type="text" name="username"/> 用户密码:<input type="password" name="Password"/> <input type="submit" value="提交按钮,Post请求访问servlet"/> </form>
此处我们的用户名称仍然填为宋彪,密码仍为123456,那么来看下输出结果吧:
我们会发现此时竟然会出现中文乱码,这个时候肯定会有同学纳闷了,明明之前在get方法处的时候我们还好好的,并没有出现乱码的情况,为什么到post方法这里就出现了乱码呢?
当浏览器以GET方式发送请求,请求参数信息保存在【请求头】,在Http请求协议包到达Http服务器之后,第一件事就是进行解码 请求头二进制内容由Tomcat负责解码,Tomcat9.0默认使用【utf-8】字符集,可以解释一切国家文字
浏览器以POST方式发送请求,请求参数保存在【请求体】,在Http请求协议包到达Http服务器之后,第一件事就是进行解码,请求体二进制内容由当前请求对象(request)负责解码。request默认使用[ISO-8859-1]字符集,一个东欧语系字符集 此时如果请求体参数内容是中文,将无法解码只能得到乱码
解决办法:
在Post请求方式下,在读取请求体内容之前,应该通知请求对象使用utf-8字符集对请求体内容进行一次重新解码,此时我们使用req.setCharacterEncoding方法来进行重新编码
代码示例:
public class ThreeServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8"); String username = req.getParameter("username"); String password = req.getParameter("Password"); System.out.println("前台输入的用户名为=" + username + "前台输入的密码为" + password); } }
输出结果为:
我们会发现此时不再乱码了。