HttpServletRequest对象表明客户端的请求,当客户端经过HTTP协议访问服务器时,HTTP请求头中的全部信息都封装在这个对象中,开发人员经过这个对象的方法,能够得到客户的这些信息。html
======================================================================================java
HttpServletRequest经常使用方法web
getRequestURL方法返回客户端发出请求时的完整URL getRequestURI方法返回请求行中的资源名部分 getQueryString方法返回请求行中的参数部分(参数名+值) getRemoteAddr方法返回发出请求的客户机的IP地址 getRemoteHost方法返回发出请求的客户机的完整主机名 getRemotePort方法返回web服务器所使用的网络端口号 getLocalPort方法返回web服务器所使用的网络端口号 getLocalAddr方法返回web服务器的IP地址 getLocalName方法返回web服务器的主机名在Servlet中做以下测试:浏览器
// 获得URL String url = request.getRequestURL().toString(); System.out.println("URL:"+url); out.println("URL:"+url+"<br>"); // 获得URI String uri = request.getRequestURI(); System.out.println("URI:"+uri); out.println("URI:"+uri+"<br>"); // 获得参数字符串 String query_string = request.getQueryString(); System.out.println("QueryString:"+query_string); out.println("QueryString:"+query_string+"<br>"); // 获得请求方的IP地址 // 能够以此来封杀某些IP String remote_addr = request.getRemoteAddr(); System.out.println("RemoteAddr:"+remote_addr); out.println("RemoteAddr:"+remote_addr+"<br>"); // 获得请求方的完整主机名 String remote_host = request.getRemoteHost(); System.out.println("RemoteHost:"+remote_host); out.println("RemoteHost:"+remote_host+"<br>"); //获得请求方的网络端口号 int remote_port = request.getRemotePort(); System.out.println("RemotePort:"+remote_port); out.println("RemotePort:"+remote_port+"<br>"); //获得服务器本机使用的网络端口号 int local_port = request.getLocalPort(); System.out.println("LocalPort:"+local_port); out.println("LocalPort:"+local_port+"<br>"); //获得服务器本机的IP地址 String local_addr = request.getLocalAddr(); System.out.println("LocalAddr:"+local_addr); out.println("LocalAddr:"+local_addr+"<br>"); // 获得服务器本机的主机名 String local_name = request.getLocalName(); System.out.println("LocalName:"+local_name); out.println("LocalName:"+local_name+"<br>");
浏览器运行结果:服务器
======================================================================================网络
HttpServletRequest的常见应用app
----------------------------------------------------------------------------------------------------------------------------------------------------post
1.获取客户机请求头测试
getHeader方法获取某一个header的内容 getHeaders方法(若是头名字相同,返回Enumeration,用得比较少) getHeaderNames方法获取全部的http消息头
测试:url
//getHeader 经过消息头,来获取信息 // 好比要获取http请求的Host String host = request.getHeader("Host"); System.out.println("Host:"+host); System.out.println("-----------------"); //getHeaderNames方法获取全部的消息头 // 需求:请把整个http请求的消息所有获取 Enumeration<String> headers= request.getHeaderNames(); while(headers.hasMoreElements()){ // 取出消息头的名字 String headername = headers.nextElement(); System.out.println(headername+":"+ request.getHeader(headername)); }
服务器输出结果:
Host:localhost:8080 ----------------- host:localhost:8080 connection:keep-alive cache-control:max-age=0 accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 upgrade-insecure-requests:1 user-agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36 accept-encoding:gzip, deflate, sdch accept-language:zh-CN,zh;q=0.8
---------------------------------------------------------------------------------------------------------------------------------------------------- 2.获取客户机请求参数
getParameter方法 getParameterValues(String name) getParameterNames()方法
在这里,getParameter方法返回一个只有一个值的参数,getParameterValues方法返回一个能够有多个值的参数,好比用于获取复选框的选项。
案例:获取用户经过表单提交的内容。 界面部分:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"); out.println("<HTML>"); out.println(" <HEAD><TITLE>Form</TITLE></HEAD>"); out.println(" <BODY>"); out.println(" <form action='RegisterCL' method='post'>"); out.println(" 用户名:<input type='text' name='username'/><br><br>"); out.println(" 密 码:<input type='password' name='pwd'/><br><br>"); out.println(" 性 别:<input type='radio' name='sex' value='男'/>男<input type='radio' name='sex' value='女'/>女<br><br>"); out.println(" 爱 好:<input type='checkbox' name='hobby' value='音乐'/>音乐<input type='checkbox' name='hobby' value='篮球'/>篮球<input type='checkbox' name='hobby' value='电影'/>电影<br><br>"); out.println(" 所在城市:<select name='city'><option value='北京'>北京</option><option value='重庆'>重庆</option></select><br><br>"); out.println(" 你的介绍:<textarea cols='20' rows='10' name='intro'>请输入介绍...</textarea><br><br>"); out.println(" 提交照片:<input type='file' name='photo'/><br><br>"); // hidden表单 // 何时使用hidden传数据:1.不但愿用户看到该数据 2.不但愿影响界面,同时业务逻辑又要使用该数据 out.println(" <input type='hidden' value='abc' name='hidden1'/>"); out.println(" <input type='submit' value='提交'/>"); out.println(" </BODY>"); out.println("</HTML>"); out.flush(); out.close(); }
接收信息的Servlet代码:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); String u = request.getParameter("username"); String p = request.getParameter("pwd"); String sex = request.getParameter("sex"); // 若是接收复选框的内容,则应该使用getParameterValues // 若是复选框一个都没有选择,则会返回null,因此下面要进行判断 String hobbies[] = request.getParameterValues("hobby"); String city = request.getParameter("city"); String intro = request.getParameter("intro"); String hidden1 = request.getParameter("hidden1"); out.println("用户名:"+u+"<br>"); out.println("密 码:"+p+"<br>"); out.println("性 别:"+sex+"<br>"); if(hobbies == null){ out.println("你没有爱好<br>"); }else{ out.println("你的爱好有:<br>"); out.println("<ul>"); for(int i=0;i<hobbies.length;i++){ out.println("<li>"+hobbies[i]+"</li>"); } out.println("</ul>"); } out.println("所在城市:"+city+"<br>"); out.println("我的介绍:"+intro+"<br>"); out.println("隐藏控件传递的数据是:"+hidden1+"<br>"); }
运行结果:
提交以后:
---------------------------------------------------------------------------------------------------------------------------------------------------- 3.实现请求转发
请求转发指一个web资源收到客户端请求后,通知服务器去调用另一个web资源进行处理。 请求转发必定要和HttpServletResponse.sendRedirect所表示的请求重定向区别开来!
一个web资源收到客户端请求后,通知服务器去调用另一个web资源进行处理,称之为请求转发 一个web资源收到客户端请求后,通知浏览器去访问另一个web资源,称之为请求重定向。 |
HttpServletRequest对象提供了一个getRequestDispatcher方法,该方法返回一个RequestDispatcher对象,调用这个对象的forword方法能够实现请求转发。
那么什么叫作请求转发呢?假如咱们此时要经过request请求转发的方式将数据带到下一个页面该怎么作?看下面一个案例:
假如咱们的项目有三个Servlet,分别是Login、Servlet1和Servlet2,Servlet1接收Login表单post过来的数据,而后请求转发到Servlet2进行处理。
Login的代码:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); //返回一个界面 out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"); out.println("<HTML>"); out.println(" <HEAD><TITLE>LoginServlet</TITLE></HEAD>"); out.println(" <BODY>"); out.println("<h1>用户登陆</h1>"); //action 应该这样写 /web应用名称/Servlet的url out.println("<form action='/requestForward/Servlet1' method='post'>"); out.println("用户名:<input type='text' name='username'/><br><br>"); out.println("密 码:<input type='password' name='password'><br><br>"); out.println("<input type='submit' value='登陆'><br>"); out.println("</form>"); out.println(" </BODY>"); out.println("</HTML>"); out.flush(); out.close(); }
Servlet1的代码:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); request.setCharacterEncoding("utf-8"); // 接收用户名 String u = request.getParameter("username"); // 把u放入request域对象 request.setAttribute("username", u); // 表示使用转发的方法把request和response对象传递给下一个Servlet // 这里不用带web应用名称 request.getRequestDispatcher("/Servlet2").forward( request, response); }
Servlet2的代码:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); String u = request.getAttribute("username").toString(); out.println("接收到的用户名是:"+u); }
能够看到,Servlet1接收Login传递过来的数据,而后将数据放入了request域对象,而后将request对象和response对象使用转发的方法传递给了Servlet2,也就是说,Servlet2中的request对象和response对象其实就是Servlet1中的。
能够经过下述时序图了解这个交互过程:
从时序图中能够看到,浏览器只发出了一次请求,接收到了一次结果。而从Servlet1到Servlet2的转发过程只是发生在服务器内部的,浏览器并不知道。因此说,浏览器的地址栏此时应该停留在http://localhost:8080/RequestTest/Servlet1,其实无论服务器内部转发多少次,浏览器都不会知道,它的地址栏也就不会发生变化,这一切都是发生在服务器内部的。
而sendRedirect请求重定向与此不一样,请求重定向是服务器告诉浏览器接下来应该访问的WEB资源,浏览器收到这个通知以后会去请求这个资源,这是发生在浏览器的两次不一样的请求,因此地址栏也会发生变化。
这里要注意的是:
一、使用forward不能转发到该web应用以外的url。 二、由于forward是发生在web服务器的,不是浏览器,因此Servlet1和Servlet2使用的是同一个request和response对象。 三、使用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对象,它们属于两个独立的访问请求和响应过程。