HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中。要得到浏览器信息,就找HttpServletRequest对象。

HttpServletRequest常用方法

获取客户端【浏览器】信息

  • getRequestURL方法返回客户端发出请求时的完整URL。
  • getRequestURI方法返回请求行中的资源名部分。
  • getQueryString 方法返回请求行中的参数部分。
  • getPathInfo方法返回请求URL中的额外路径信息。额外路径信息是请求URL中的位于Servlet的路径之后和查询参数之前的内容,它以“/”开头。
  • getRemoteAddr方法返回发出请求的客户机的IP地址
  • getRemoteHost方法返回发出请求的客户机的完整主机名
  • getRemotePort方法返回客户机所使用的网络端口号
  • getLocalAddr方法返回WEB服务器的IP地址。
  • getLocalName方法返回WEB服务器的主机名

获取客户端请求头

  • getHeader方法
  • getHeaders方法
  • getHeaderNames方法

获取客户端请求参数(客户端提交的数据)

  • getParameter方法
  • getParameterValues(String name)方法
  • getParameterNames方法
  • getParameterMap方法

HttpServletRequest应用

防盗链

防止简单的复制URL和粘贴URL就可以访问。

获取Referer这个消息头,判断Referer是否是从首页过来的。

//获取Referer消息头
String referer=request.getHeader("Referer");
//如果不是从首页或者地址栏直接访问
if(referer==null||!referer.contains("localhost:8080/index.jsp")){
response.sendRedirect(/index.jsp);
return;
}
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("是跳转过来");

表单提交数据【通过post方式提交数据】

//设置request字符编码格式
request.setCharacterEncoding("UTF-8");
//获取单个值
String account=request.getParameter("userAccount");
String password=request.getParameter("password");
//获取多个值
String[] hobbies=request.getParameterValues("hobbies");
System.out.println(account);
System.out.println(password);
response.getWriter().write("OK");

超链接方式提交数据【通过get方式提交数据】

string url="servlet的地址?参数名="+参数值 &"参数名="+参数值;
response.sendRedirect(url);
//设置request字符编码格式
request.setCharacterEncoding("UTF-8");
String account=request.getParameter("userAccount");
String password=request.getParameter("password");
response.getWriter().write("OK");

实现转发

使用request的getRequestDispacher.forward(request,response)实现转发,做到的功能也是页面跳转。

//获取到requestDispatcher对象,跳转到index.html
final RequestDispatcher requestDispatcher = request.getRequestDispatcher("/index.html");
//调用requestDispatcher对象的forward()实现转发,传入request和response的方法
requestDispatcher.forward(request,response);

之前讲过Servlet之间可以通过Servletcontext实现通讯,ServletContext也能称之为域对象,而request也可以称之为域对象,只不过ServletContext的域是整个web应用,而request的域仅仅代表一次http请求。

一个Servlet中代码

//设置参数
request.setAttribute("username","tony");
//获取RequestDispatcher对象
RequestDispatcher requestDispatcher=request.getRequestDispatcher("/Servlet2");
//调用requestDispatcher对象的forward()实现转发,传入request和response
requestDispatcher.forward(request,response);

在Servlet2中代码

//获取到存进request对象的值
String userName=(String)request.getAttribute("username");
response.getWriter().write(userName);

可以使用ServletContext和request实现Servlet之间的通讯,一般原则:可以使用request就尽可能使用request。因为ServletContext代表着整个web应用,使用ServletContext会消耗大量的资源,而request对象会随着请求的结束而结束,资源会被回收。使用request域进行Servlet之间的通讯在开发中是非常频繁的。

转发的时序图

请求转发的细节

在调用forward方法之前,在Servlet程序中写入的部分内容已经被真正地传送到了客户端,forward方法将抛出异常。不要在转发之前写数据给浏览器。如果在调用forward方法之前向Servlet引擎的缓冲区中写入了内容,只要写入到缓冲区中的内容还没有被真正输出到客户端,forward方法就可以被正常执行,原来写入到输出缓冲区中的内容将被清空,但是,已写入到HttpServletResponse对象中的响应头字段信息保持有效。

ServletOutputStream servletOutputStream=response.getOutputStream();
servletOutputStream.write("---------".getBytes());
//关闭流,确保让数据到浏览器中
servletOutputStream.close();
//跳转,后台出现异常,无法跳转
final RequestDispatcher requestDispatcher = request.getRequestDispatcher("/index.html"); requestDispatcher.forward(request,response);

转发和重定向的区别

实际发生位置不同,地址栏不同

  • 转发是发生在服务器的:转发是由服务器进行跳转的,在转发的过程中,浏览器的地址栏是没有发生变化的。浏览器是不知道该跳转的动作,转发是对浏览器透明的。实现转发只是一次的http请求,一次转发中request和response对象都是同一个。解释了使用request作为域对象能进行ServletServlet之间的通讯。
  • 重定向式发生在浏览器的:重定向式由浏览器进行跳转的,进行重定向跳转的时候,浏览器地址会发生变化的。实现重定向的原理是由response的状态码和Location头组合而实现的。这是由浏览器进行的页面跳转实现重定向会发出两个http请求,request域对象是无效的,因为它不是同一个request对象。

用法不同

资源地址不同,给服务器用的直接从资源名开始写,给浏览器用的要把应用名写上

  • request.getRequestDispatcher("/资源名 URI").forward(request,response);    转发时"/"代表的是本应用程序的根目录
  • response.sendRedirect("/web应用/资源名 URI");   重定向时"/"代表的是webapps目录

能够去往的URL的范围不一样

  • 转发是服务器跳转只能去往当前web应用的资源
  • 重定向是浏览器跳转,可以去往任何的资源

传递数据的类型不同

  • 转发的request对象可以传递各种类型的对象,包括对象
  • 重定向只能传递字符串

跳转的时间不同

  • 转发时:执行到跳转语句时就会立刻跳转
  • 重定向:整个页面执行完之后才执行跳转

转发是带着转发前的请求的参数的,重定向是新的请求。

  • 转发:访问Servlet处理业务逻辑,然后forward到jsp显示处理结果,浏览器里URL不变
  • 重定向:提交表单,处理成功后redirect到另一个jsp,防止表达重复提交,浏览器里URL变了。

RequestDispatcher的include()方法

写网页的时候,一般网页的头部和尾部都是不需要改变的,如果多个地方使用Servlet输出网头和网尾的话,需要把代码重新写一遍。而使用RequestDispatcher的include()方法就可以实现包含网头和网尾的效果了。

request.getRequestDispatcher("/Head").include(request, response);
response.getWriter().write("-----------------------------------------");
request.getRequestDispatcher("/Foot").include(request, response);

 

 posted on 2019-05-18 19:19  会飞的金鱼  阅读(110)  评论(0)    收藏  举报