HttpServletRequest对象调用

${pageContext.request.contextPath}样是通过 get方法去取的,先pageContext.getRequest()得到HttpServletRequest对象,再调用 HttpServletRequest的getContextPath方法

作用是取出部署的应用程序名,这样不管如何部署,所用路径都是正确的。

El表达式的写法:${pageContext.request.contextPath}

jsp的写法:<%=request.getContextPath()%>

=============================================================

HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户的这些信息。

=============================================================

HttpServletRequest常用方法

getRequestURL方法返回客户端发出请求时的完整URL
getRequestURI方法返回请求行中的资源名部分
getQueryString方法返回请求行中的参数部分(参数名+值)
getRemoteAddr方法返回发出请求的客户机的IP地址
getRemoteHost方法返回发出请求的客户机的完整主机名
getRemotePort方法返回web服务器所使用的网络端口号
getLocalPort方法返回web服务器所使用的网络端口号
getLocalAddr方法返回web服务器的IP地址
getLocalName方法返回web服务器的主机名

在Servlet中作如下测试:

[java]  view plain  copy
  1. // 得到URL  
  2.         String url = request.getRequestURL().toString();  
  3.         System.out.println("URL:"+url);  
  4.         out.println("URL:"+url+"<br>");  
  5.         // 得到URI  
  6.         String uri = request.getRequestURI();  
  7.         System.out.println("URI:"+uri);  
  8.         out.println("URI:"+uri+"<br>");  
  9.         // 得到参数字符串  
  10.         String query_string = request.getQueryString();  
  11.         System.out.println("QueryString:"+query_string);  
  12.         out.println("QueryString:"+query_string+"<br>");  
  13.         // 得到请求方的IP地址  
  14.         // 可以以此来封杀某些IP  
  15.         String remote_addr = request.getRemoteAddr();  
  16.         System.out.println("RemoteAddr:"+remote_addr);  
  17.         out.println("RemoteAddr:"+remote_addr+"<br>");  
  18.         // 得到请求方的完整主机名  
  19.         String remote_host = request.getRemoteHost();  
  20.         System.out.println("RemoteHost:"+remote_host);  
  21.         out.println("RemoteHost:"+remote_host+"<br>");  
  22.         //得到请求方的网络端口号  
  23.         int remote_port = request.getRemotePort();  
  24.         System.out.println("RemotePort:"+remote_port);  
  25.         out.println("RemotePort:"+remote_port+"<br>");  
  26.         //得到服务器本机使用的网络端口号  
  27.         int local_port = request.getLocalPort();  
  28.         System.out.println("LocalPort:"+local_port);  
  29.         out.println("LocalPort:"+local_port+"<br>");  
  30.         //得到服务器本机的IP地址  
  31.         String local_addr = request.getLocalAddr();  
  32.         System.out.println("LocalAddr:"+local_addr);  
  33.         out.println("LocalAddr:"+local_addr+"<br>");  
  34.         // 得到服务器本机的主机名  
  35.         String local_name = request.getLocalName();  
  36.         System.out.println("LocalName:"+local_name);  
  37.         out.println("LocalName:"+local_name+"<br>");  
浏览器运行结果:

======================================================================================

HttpServletRequest的常见应用

----------------------------------------------------------------------------------------------------------------------------------------------------

1.获取客户机请求头

[java]  view plain  copy
  1. getHeader方法获取某一个header的内容  
  2. getHeaders方法(如果头名字相同,返回Enumeration,用得比较少)  
  3. getHeaderNames方法获取所有的http消息头  
测试:

[java]  view plain  copy
  1. //getHeader 通过消息头,来获取信息  
  2.         // 比如要获取http请求的Host  
  3.         String host = request.getHeader("Host");  
  4.         System.out.println("Host:"+host);  
  5.           
  6.         System.out.println("-----------------");  
  7.           
  8.         //getHeaderNames方法获取所有的消息头  
  9.         // 需求:请把整个http请求的消息全部获取  
  10.         Enumeration<String> headers= request.getHeaderNames();  
  11.         while(headers.hasMoreElements()){  
  12.             // 取出消息头的名字  
  13.             String headername = headers.nextElement();  
  14.             System.out.println(headername+":"+ request.getHeader(headername));  
  15.         }  

服务器输出结果:

[plain]  view plain  copy
  1. Host:localhost:8080  
  2. -----------------  
  3. host:localhost:8080  
  4. connection:keep-alive  
  5. cache-control:max-age=0  
  6. accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8  
  7. upgrade-insecure-requests:1  
  8. user-agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36  
  9. accept-encoding:gzip, deflate, sdch  
  10. accept-language:zh-CN,zh;q=0.8  
----------------------------------------------------------------------------------------------------------------------------------------------------
2.获取客户机请求参数

[java]  view plain  copy
  1. getParameter方法  
  2. getParameterValues(String name)  
  3. getParameterNames()方法  
在这里,getParameter方法返回一个只有一个值的参数,getParameterValues方法返回一个可以有多个值的参数,比如用于获取复选框的选项。

案例:获取用户通过表单提交的内容。
界面部分:

[java]  view plain  copy
  1. public void doGet(HttpServletRequest request, HttpServletResponse response)  
  2.             throws ServletException, IOException {  
  3.   
  4.         response.setContentType("text/html;charset=utf-8");  
  5.         PrintWriter out = response.getWriter();  
  6.         out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");  
  7.         out.println("<HTML>");  
  8.         out.println("  <HEAD><TITLE>Form</TITLE></HEAD>");  
  9.         out.println("  <BODY>");  
  10.         out.println("     <form action='RegisterCL' method='post'>");  
  11.         out.println("     用户名:<input type='text' name='username'/><br><br>");  
  12.         out.println("     密 码:<input type='password' name='pwd'/><br><br>");  
  13.         out.println("     性 别:<input type='radio' name='sex' value='男'/>男<input type='radio' name='sex' value='女'/>女<br><br>");  
  14.         out.println("     爱 好:<input type='checkbox' name='hobby' value='音乐'/>音乐<input type='checkbox' name='hobby' value='篮球'/>篮球<input type='checkbox' name='hobby' value='电影'/>电影<br><br>");  
  15.         out.println("     所在城市:<select name='city'><option value='北京'>北京</option><option value='重庆'>重庆</option></select><br><br>");  
  16.         out.println("     你的介绍:<textarea cols='20' rows='10' name='intro'>请输入介绍...</textarea><br><br>");  
  17.         out.println("     提交照片:<input type='file' name='photo'/><br><br>");  
  18.         // hidden表单  
  19.         // 什么时候使用hidden传数据:1.不希望用户看到该数据  2.不希望影响界面,同时业务逻辑又要使用该数据  
  20.         out.println("     <input type='hidden' value='abc' name='hidden1'/>");  
  21.         out.println("     <input type='submit' value='提交'/>");  
  22.         out.println("  </BODY>");  
  23.         out.println("</HTML>");  
  24.         out.flush();  
  25.         out.close();  
  26.     }  
接收信息的Servlet代码:

[java]  view plain  copy
  1. public void doGet(HttpServletRequest request, HttpServletResponse response)  
  2.             throws ServletException, IOException {  
  3.   
  4.         request.setCharacterEncoding("utf-8");  
  5.         response.setContentType("text/html;charset=utf-8");  
  6.         PrintWriter out = response.getWriter();  
  7.           
  8.         String u = request.getParameter("username");  
  9.         String p = request.getParameter("pwd");  
  10.         String sex = request.getParameter("sex");  
  11.         // 如果接收复选框的内容,则应该使用getParameterValues  
  12.         // 如果复选框一个都没有选择,则会返回null,所以下面要进行判断  
  13.         String hobbies[] = request.getParameterValues("hobby");  
  14.         String city = request.getParameter("city");  
  15.         String intro = request.getParameter("intro");  
  16.         String hidden1 = request.getParameter("hidden1");  
  17.           
  18.         out.println("用户名:"+u+"<br>");  
  19.         out.println("密 码:"+p+"<br>");  
  20.         out.println("性 别:"+sex+"<br>");  
  21.         if(hobbies == null){  
  22.             out.println("你没有爱好<br>");  
  23.         }else{  
  24.             out.println("你的爱好有:<br>");  
  25.             out.println("<ul>");  
  26.             for(int i=0;i<hobbies.length;i++){  
  27.                 out.println("<li>"+hobbies[i]+"</li>");  
  28.             }  
  29.             out.println("</ul>");  
  30.         }  
  31.         out.println("所在城市:"+city+"<br>");  
  32.         out.println("个人介绍:"+intro+"<br>");  
  33.         out.println("隐藏控件传递的数据是:"+hidden1+"<br>");  
  34.     }  
运行结果:

提交之后:



----------------------------------------------------------------------------------------------------------------------------------------------------
3.实现请求转发

请求转发指一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理。
请求转发一定要和HttpServletResponse.sendRedirect所表示的请求重定向区别开来!

一个web资源收到客户端请求后,通知服务器调用另外一个web资源进行处理,称之为请求转发
一个web资源收到客户端请求后,通知浏览器访问另外一个web资源,称之为请求重定向。
HttpServletRequest对象提供了一个getRequestDispatcher方法,该方法返回一个RequestDispatcher对象,调用这个对象的forword方法可以实现请求转发。

那么什么叫做请求转发呢?假如我们此时要通过request请求转发的方式将数据带到下一个页面该怎么做?看下面一个案例:

假如我们的项目有三个Servlet,分别是Login、Servlet1和Servlet2,Servlet1接收Login表单post过来的数据,然后请求转发到Servlet2进行处理。

Login的代码:

[java]  view plain  copy
  1. public void doGet(HttpServletRequest request, HttpServletResponse response)  
  2.             throws ServletException, IOException {  
  3.   
  4.         response.setContentType("text/html;charset=utf-8");  
  5.         PrintWriter out = response.getWriter();  
  6.         //返回一个界面  
  7.         out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");  
  8.         out.println("<HTML>");  
  9.         out.println("  <HEAD><TITLE>LoginServlet</TITLE></HEAD>");  
  10.         out.println("  <BODY>");  
  11.         out.println("<h1>用户登录</h1>");  
  12.         //action 应该这样写 /web应用名称/Servlet的url  
  13.         out.println("<form action='/requestForward/Servlet1' method='post'>");  
  14.         out.println("用户名:<input type='text' name='username'/><br><br>");  
  15.         out.println("密 码:<input type='password' name='password'><br><br>");  
  16.         out.println("<input type='submit' value='登录'><br>");  
  17.         out.println("</form>");  
  18.         out.println("  </BODY>");  
  19.         out.println("</HTML>");  
  20.         out.flush();  
  21.         out.close();  
  22.     }  
Servlet1的代码:
[java]  view plain  copy
  1. public void doGet(HttpServletRequest request, HttpServletResponse response)  
  2.             throws ServletException, IOException {  
  3.   
  4.         response.setContentType("text/html;charset=utf-8");  
  5.         request.setCharacterEncoding("utf-8");  
  6.         // 接收用户名  
  7.         String u = request.getParameter("username");  
  8.           
  9.         // 把u放入request域对象  
  10.         request.setAttribute("username", u);  
  11.           
  12.         // 表示使用转发的方法把request和response对象传递给下一个Servlet  
  13.         // 这里不用带web应用名称  
  14.         request.getRequestDispatcher("/Servlet2").forward(  
  15.                 request, response);  
  16.     }  
Servlet2的代码:

[java]  view plain  copy
  1. public void doGet(HttpServletRequest request, HttpServletResponse response)  
  2.             throws ServletException, IOException {  
  3.   
  4.         response.setContentType("text/html;charset=utf-8");  
  5.           
  6.         PrintWriter out = response.getWriter();  
  7.           
  8.         String u = request.getAttribute("username").toString();  
  9.         out.println("接收到的用户名是:"+u);  
  10.     }  
可以看到,Servlet1接收Login传递过来的数据,然后将数据放入了request域对象,然后将request对象和response对象使用转发的方法传递给了Servlet2,也就是说,Servlet2中的request对象和response对象其实就是Servlet1中的。

可以通过下述时序图了解这个交互过程:



从时序图中可以看到,浏览器只发出了一次请求,接收到了一次结果。而从Servlet1到Servlet2的转发过程只是发生在服务器内部的,浏览器并不知道。所以说,浏览器的地址栏此时应该停留在http://localhost:8080/RequestTest/Servlet1,其实不管服务器内部转发多少次,浏览器都不会知道,它的地址栏也就不会发生变化,这一切都是发生在服务器内部的。

而sendRedirect请求重定向与此不同,请求重定向是服务器告诉浏览器接下来应该访问的WEB资源,浏览器收到这个通知之后会去请求这个资源,这是发生在浏览器的两次不同的请求,所以地址栏也会发生变化。

这里要注意的是:

1、使用forward不能转发到该web应用之外的url。
2、因为forward是发生在web服务器的,不是浏览器,所以Servlet1和Servlet2使用的是同一个request和response对象。
3、使用sendRedirect()方法不能够通过request.setAttribute()方法把属性传递给下一个Servlet。很显然,这是两次不同的请求,request对象都不一样,怎么可能通过request传递数据。

----------------------------------------------------------------------------------------------------------------------------------------------------

下面总结一下请求重定向(sendRedirect)和请求转发的区别:
【1】RequestDispatcher.forward方法只能将请求转发给同一个WEB应用中的组件;而HttpServletResponse.sendRedirect方法还可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL重定向到其他站点的资源。
【2】如果传递给HttpServletResponse.sendRedirect方法的相对URL以”/”开头,它是相对于整个WEB站点的根目录;如果创建RequestDispatcher对象时指定的相对URL以”/”开头,它是相对于当前WEB应用程序的根目录。
【3】调用HttpServletResponse.sendRedirect方法重定向的访问过程结束后,浏览器地址栏中显示的URL会发生变化,由初始的URL地址变成重定向的目标URL;调用RequestDispatcher.forward方法的请求转发过程结束后,浏览器地址栏保持初始的URL地址不变。
【4】HttpServletResponse.sendRedirect方法对浏览器的请求直接作出响应,响应的结果就是告诉浏览器去重新发出对另外一个URL的访问请求;RequestDispatcher.forward方法在服务器端内部将请求转发给另外一个资源,浏览器只知道发出了请求并得到了响应结果,并不知道在服务器程序内部发生了转发行为。
【5】RequestDispatcher.forward方法的调用者与被调用者之间共享相同的request对象和response对象,它们属于同一个访问请求和响应过程;而HttpServletResponse.sendRedirect方法调用者与被调用者使用各自的request对象和response对象,它们属于两个独立的访问请求和响应过程。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值