HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息。
ServletRequest -- 通用request,提供一个request应该具有的最基本的方法
|
|--HttpServletRequest -- ServletRequest的孩子,针对http协议进行了进一步的增强
通过Request对象进行的常用操作
1.获取客户机信息
getRequestURL方法返回客户端发出请求完整URL
!!getRequestURI方法返回请求行中的资源名部分
getQueryString 方法返回请求行中的参数部分
!!getRemoteAddr方法返回发出请求的客户机的IP地址
!!getMethod得到客户机请求方式
!!getContextPath 获得当前web应用虚拟目录名称
2.获取请求头信息
获得客户机请求头
getHeader(name)方法 --- String
getHeaders(String name)方法 --- Enumeration<String>
getHeaderNames方法 --- Enumeration<String>
获得具体类型客户机请求头
getIntHeader(name)方法 --- int
getDateHeader(name)方法 --- long(日期对应毫秒)
*关于 防盗链的问题,请参见笔者另一篇文章: http://blog.csdn.net/dwyers/article/details/38495349
3.获取请求参数
html代码:param.html
(2)服务器以什么编码来打开呢?如果不指定,则使用ISO8859-1,这样如果请求参数中有中文必然就乱码了
(3)对于POST提交,可以设置request.setCharacterEncoding("utf-8");明确的通知服务器以浏览器发送过来的编码来打开数据就可以解决乱码
(4)但是上面的方法只对请求中实体内容部分起作用,所以GET提交的乱码并不能解决.
对于GET提交的乱码,只能手动的进行编解码从而解决乱码问题:
String username = request.getParameter("username");
username = new String(username.getBytes("iso8859-1"),"utf-8"); //注意,这两行代码同样可以解决POST提交的乱码问题。
4.利用请求域传递对象
作用范围:整个请求链上
生命周期:当服务器收到一个请求,创建出代表请求的request对象,request开始.当请求结束,服务器销毁代表请求的request对象,request域结束。
作用:在整个请求链范围内共享数据,通常我们在Servlet中处理好的数据会存入request域后请求转发到jsp页面来进行展示。
setAttribute
getAttribute
show.jsp(jsp页面)
5.实现请求转发和请求包含
(1)请求转发:
this.getServletContext().getRequestDispatcher("").forward(request,response);
request.getRequestDispatcher("").forward(request,response);
~请求转发是希望将请求交给另外一个资源执行,所以应该保证只有最后真正要执行的资源才能够输出数据,所以:
*请求转发时,如果已经有数据被写入到了response的缓冲区,但是这些数据还没有被发送到客户端,则请求转发时,这些数据将会被清空.但是清空的只是响应中的实体内容部分,头信息并不会被清空.
*而请求转发时已经有数据被打给了浏览器,那么再进行请求转发,不能成功,会抛出异常,原因是响应已经结束了,再转发交给其他人没意义了
*在最终输出数据的Servlet执行完成后,response实体内容中的数据将会被设置为已提交的状态,再往里写数据也不会起作用
-------使用以上三条,就保证了最终只有一个Servlet能够向浏览器输出数据,所以
*一个Servlet里两次请求转发也是不可以的,一次请求交给两人处理自然也是不行.
Demo6.java
控制台输出:
(2)请求包含:将两个资源的输出进行合并后输出
this.getServletContext().getRequestDispatcher("").include(request,response);
*被包含的Servlet程序不能改变响应消息的状态码和响应头,如果它里面存在这样的语句,这些语句的执行结果将被忽略
*常被用来进行页面布局
(3)三种资源处理方式的区别
请求重定向
response.sendRedirect();
请求转发
request.getRequestDispatcher().forward();
请求包含
request.getRequestDispatcher().include();
请求重定向和请求转发的区别:
请求重定向地址栏会发生变化.请求转发地址栏不发生变化.
请求重定向两次请求两次响应.请求转发一次请求一次响应.
如果需要在资源跳转时利用request域传递域属性则必须使用请求转发
如果希望资源跳转后修改用户的地址栏则使用请求重定向
如果使用请求转发也可以重定向也可以,则优先使用请求转发,减少浏览器对服务器的访问次数减轻服务器的压力.
ServletRequest -- 通用request,提供一个request应该具有的最基本的方法
|
|--HttpServletRequest -- ServletRequest的孩子,针对http协议进行了进一步的增强
通过Request对象进行的常用操作
1.获取客户机信息
getRequestURL方法返回客户端发出请求完整URL
!!getRequestURI方法返回请求行中的资源名部分
getQueryString 方法返回请求行中的参数部分
!!getRemoteAddr方法返回发出请求的客户机的IP地址
!!getMethod得到客户机请求方式
!!getContextPath 获得当前web应用虚拟目录名称
/**
*
* @project_name Day04
* @class_name CustInfoServlet
* @author Dovinya
* @data 2014-8-10 下午06:22:55
* @version 1
* @notes request获取客户机信息
*/
public class CustInfoServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//1.获取客户端请求的完整URL
String url = request.getRequestURL().toString();
System.out.println(url);
//2.获取客户端请求的资源部分的名称
String uri = request.getRequestURI().toString();
System.out.println(uri);
//3.获取请求行的参数部分
String qStr = request.getQueryString().toString();
System.out.println(qStr);
//4.获取请求客户端的ip地址
String ip = request.getRemoteAddr();
System.out.println(ip);
//5.获取客户机的请求方式
String method = request.getMethod();
System.out.println(method);
//6.获取当前web应用的名称,不是工程名!!!!这个方法特别重要!!!!!!!!!!!!!!
String webName = request.getContextPath();
System.out.println(webName);
response.sendRedirect(request.getContextPath()+"/index.jsp");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
2.获取请求头信息
获得客户机请求头
getHeader(name)方法 --- String
getHeaders(String name)方法 --- Enumeration<String>
getHeaderNames方法 --- Enumeration<String>
获得具体类型客户机请求头
getIntHeader(name)方法 --- int
getDateHeader(name)方法 --- long(日期对应毫秒)
/**
*
* @project_name Day04
* @class_name HeaderServlet
* @author Dovinya
* @data 2014-8-10 下午06:23:36
* @version 1
* @notes request获取请求头信息
*/
public class HeaderServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//1.给一个请求头名称,获取其值
String host = request.getHeader("Host");
System.out.println(host);
System.out.println("-------------------------------------------");
//2.获取所有请求头名字组成的枚举
Enumeration<String> enumeration = request.getHeaderNames();
while (enumeration.hasMoreElements()) {
String name = (String) enumeration.nextElement();
String values = request.getHeader(name);
System.out.println(name+":"+values);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
*关于 防盗链的问题,请参见笔者另一篇文章: http://blog.csdn.net/dwyers/article/details/38495349
3.获取请求参数
servlet代码:
/**
*
* @project_name Day04
* @class_name ParamServlet
* @author Dovinya
* @data 2014-8-11 下午04:58:01
* @version 1
* @notes request获取通过html页面发来的http请求参数
*/
public class ParamServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//1.获取某一个请求参数值
// String username = request.getParameter("username");
// System.out.println(username);
//2.获取所有请求参数值的枚举
// Enumeration<String> enumeration = request.getParameterNames();
// while (enumeration.hasMoreElements()) {
// String name = (String) enumeration.nextElement();
// String value = request.getParameter(name);
// System.out.println(value);
// }
//3.如果请求参数中,有中文,如何解决?
//方法一:只能解决post请求中文乱码问题
// request.setCharacterEncoding("utf-8");
// String username = request.getParameter("username");
// System.out.println(username);
//方法二:可以解决post和get两种请求乱码问题
String username = request.getParameter("username");
username = new String(username.getBytes("iso8859-1"),"utf-8");
System.out.println(username);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
html代码:param.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
<h1>POST提交</h1>
<form action="/Day04/servlet/ParamServlet" method="post">
姓名:<input type="text" name="username"/>
地址:<input type="text" name="addr"/>
<input type="submit" value="提交"/>
</form>
<h1>GET提交</h1>
<form action="/Day04/servlet/ParamServlet" method="get">
姓名:<input type="text" name="username"/>
地址:<input type="text" name="addr"/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
这里又会涉及中文乱码的问题:
(1)浏览器以什么编码来发送请求参数? 浏览器以什么编码打开的表单页面,就用什么编码发送这个页面提交的数据(2)服务器以什么编码来打开呢?如果不指定,则使用ISO8859-1,这样如果请求参数中有中文必然就乱码了
(3)对于POST提交,可以设置request.setCharacterEncoding("utf-8");明确的通知服务器以浏览器发送过来的编码来打开数据就可以解决乱码
(4)但是上面的方法只对请求中实体内容部分起作用,所以GET提交的乱码并不能解决.
对于GET提交的乱码,只能手动的进行编解码从而解决乱码问题:
String username = request.getParameter("username");
username = new String(username.getBytes("iso8859-1"),"utf-8"); //注意,这两行代码同样可以解决POST提交的乱码问题。
4.利用请求域传递对象
作用范围:整个请求链上
生命周期:当服务器收到一个请求,创建出代表请求的request对象,request开始.当请求结束,服务器销毁代表请求的request对象,request域结束。
作用:在整个请求链范围内共享数据,通常我们在Servlet中处理好的数据会存入request域后请求转发到jsp页面来进行展示。
setAttribute
getAttribute
removeAttribute
Demo3.java(servlet)
/**
*
* @project_name Day04
* @class_name Demo3
* @author Dovinya
* @data 2014-8-11 下午06:35:49
* @version 1
* @notes 演示request请求域传递对象,先传递到Demo4(servlet),或者传递到一个jsp页面中。
*/
public class Demo3 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setAttribute("banana", "yellow2");
//1.转发到Demo4 servlet
// this.getServletContext().getRequestDispatcher("/servlet/Demo4").forward(request, response);
//2.转发到JSP
this.getServletContext().getRequestDispatcher("/show.jsp").forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
Demo4.java(Servlet)
public class Demo4 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String attribute = (String) request.getAttribute("banana");
System.out.println(attribute);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
show.jsp(jsp页面)
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<font color="red">
<%=(String)request.getAttribute("banana") %>
</font>
</body>
</html>
5.实现请求转发和请求包含
(1)请求转发:
this.getServletContext().getRequestDispatcher("").forward(request,response);
request.getRequestDispatcher("").forward(request,response);
~请求转发是希望将请求交给另外一个资源执行,所以应该保证只有最后真正要执行的资源才能够输出数据,所以:
*请求转发时,如果已经有数据被写入到了response的缓冲区,但是这些数据还没有被发送到客户端,则请求转发时,这些数据将会被清空.但是清空的只是响应中的实体内容部分,头信息并不会被清空.
*而请求转发时已经有数据被打给了浏览器,那么再进行请求转发,不能成功,会抛出异常,原因是响应已经结束了,再转发交给其他人没意义了
*在最终输出数据的Servlet执行完成后,response实体内容中的数据将会被设置为已提交的状态,再往里写数据也不会起作用
-------使用以上三条,就保证了最终只有一个Servlet能够向浏览器输出数据,所以
*一个Servlet里两次请求转发也是不可以的,一次请求交给两人处理自然也是不行.
Demo5.java
/**
*
* @project_name Day04
* @class_name Demo5
* @author Dovinya
* @data 2014-8-11 上午10:11:24
* @version 1
* @notes request对象提供了一个getRequestDispatcher方法,该方法返回一个RequestDispatcher对象,
* 调用这个对象的forward方法可以实现请求转发,从而共享请求中的数据
如果在调用forward方法之前向servlet程序中写入的部分内容已经被真正的传送到了客户端,forward将不能进行,会抛出异常。
*/
public class Demo5 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("aaaaaaaaaaaaaaaaa");//控制台显示
response.getWriter().write("bbbbbbbbbbbb");//在response缓冲区,请求转发时会被清空
//response.getWriter().flush();//如果在调用forward方法之前向servlet程序中写入的部分内容已经被真正的传送到了客户端,
//forward将不能进行,会抛出异常。
//调用flush方法,就是把缓冲区内容刷给了浏览器,下面的转发不再进行。
//因为请求转发只有一个请求,和一个响应,而这个响应已经返回了。
request.getRequestDispatcher("/servlet/Demo6").forward(request, response);//请求转发
System.out.println("ccccccccccccc");//请求转发后回来打印出来
response.getWriter().write("mmmmmmmmmmmm");//可以写数据,但不会被提交。浏览器不会打印。
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
Demo6.java
public class Demo6 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("ddddddddddddddddddddddd"); //请求转发过来后控制台会打印
response.getWriter().write("eeeeeeeeeeee");//浏览器输出
System.out.println("ffffffffffffffffffffffffff");//控制台打印
response.getWriter().write("gggggggggggggggggggg");//浏览器输出
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
控制台输出:
aaaaaaaaaaaaaaaaa
ddddddddddddddddddddddd
ffffffffffffffffffffffffff
ccccccccccccc
浏览器输出:
eeeeeeeeeeeegggggggggggggggggggg(2)请求包含:将两个资源的输出进行合并后输出
this.getServletContext().getRequestDispatcher("").include(request,response);
request.getRequestDispatcher("").include(request,response);
Demo7.java
/**
*
* @project_name Day04
* @class_name Demo7
* @author Dovinya
* @data 2014-8-11 下午06:45:06
* @version 1
* @notes 演示请求包含
*/
public class Demo7 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.getWriter().write("from demo7");
request.getRequestDispatcher("/servlet/Demo8").include(request, response); //如果是forward(request,response),则输出from demo8
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
Demo8.java
public class Demo8 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.getWriter().write("from demo8");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
*被包含的Servlet程序不能改变响应消息的状态码和响应头,如果它里面存在这样的语句,这些语句的执行结果将被忽略
*常被用来进行页面布局
(3)三种资源处理方式的区别
请求重定向
response.sendRedirect();
请求转发
request.getRequestDispatcher().forward();
请求包含
request.getRequestDispatcher().include();
请求重定向和请求转发的区别:
请求重定向地址栏会发生变化.请求转发地址栏不发生变化.
请求重定向两次请求两次响应.请求转发一次请求一次响应.
如果需要在资源跳转时利用request域传递域属性则必须使用请求转发
如果希望资源跳转后修改用户的地址栏则使用请求重定向
如果使用请求转发也可以重定向也可以,则优先使用请求转发,减少浏览器对服务器的访问次数减轻服务器的压力.