Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象、和代表响应的response对象。 request和response对象即然代表请求和响应,那我们要获取客户机提交过来的数据,只需要找request对象就行了。要向容器输出数据,只需要找response对象就行了。
HttpServletResponse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。
response 常用的API
设置编码格式
response. setContentType(“text/html;charset=UTF-8”);
客户端清理缓存
response.addHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
请求重定向指:一个web资源收到客户端请求后,通知客户端去访问另外一个web资源,这称之为请求重定向。 地址栏会变,并发送2次请求,增加服务器负担 实现方式 response.sendRedirect()
在response API中提供sendRedirect() --- 完成302+Location重定向效果
例如:response.sendRedirect("/day06/welcome.html");
状态:
200 请求处理成功
302 客户端重定向
304 客户端访问资源没有被修改,客户端访问本地缓存
404 访问资源不存在
500 服务器内部出错
response.sendRedirect("/day06/welcome.html");
getOutputStream 和getWriter 区别
1)getOutputStream和getWriter不能同时使用
2)必须在getOutputStream喝getWriter之前设置响应编码
3)getOutputStream和getWriter输出内容是HTTP响应体
4)getOutputStream和getWriter存在缓冲区,在service方法结束时,自动关闭流,flush缓冲区内容
例子:
ServletOutputStream sos = response.getOutputStream();
sos.write("你好123".getBytes("UTF-8"));//getBytes默认编码为本地编码(即:gbk)
文件下载
response.setHeader("Content-Disposition","attachment;filename="+filename); ----设置文件以附件形式下载(对于浏览器识别格式文件)
例如:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//通过路径得到一个输入流
String path = this.getServletContext().getRealPath("/WEB-INF/classes/美女.jpg");
FileInputStream fis = new FileInputStream(path);
//创建字节输出流
ServletOutputStream sos = response.getOutputStream();
//得到要下载的文件名
String filename = path.substring(path.lastIndexOf("\")+1);
//设置文件名的编码
filename = URLEncoder.encode(filename, "UTF-8");//将不安全的文件名改为UTF-8格式
//告知客户端要下载文件
response.setHeader("content-disposition", "attachment;filename="+filename);
response.setHeader("content-type", "image/jpeg");
//执行输出操作
int len = 1;
byte[] b = new byte[1024];
while((len=fis.read(b))!=-1){
sos.write(b,0,len);
}
sos.close();
fis.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
刷新网页3秒钟之后重定向
response.setHeader("refresh", "3;url=http://www.baidu.com");
HttpServletRequest
HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息。 查看request的API文档
getMethod(); 获得请求方式
// ***getRequestURL();返回客户端发出请求时的完整URL。
// ***getRequestURI(); 返回请求行中的资源名部分。
// *****getContextPath(); 当前应用的虚拟目录 /day09_01_HttpServletRequest
// getQueryString() ; 返回请求行中的参数部分。
例如:
System.out.println(request.getMethod());// GET
System.out.println(request.getRequestURL()); // http://localhost:8080/day09_01_HttpServletRequest/servlet/demo1
System.out.println(request.getRequestURI()); // /day09_01_HttpServletRequest/servlet/demo1
System.out.println(request.getContextPath()); // /day09_01_HttpServletRequest
System.out.println(request.getQueryString()); // username=tom
获得客户机信息 getRequestURL方法返回客户端发出请求时的完整URL。
获得客户机请求头
getHead(name)方法
getHeaders(String name)方法
getHeaderNames方法 获得客户机请求参数(客户端提交的数据)
getParameter(name)方法
getParameterValues(String name)方法
getParameterNames方法 getParameterMap方法 //做框架用,非常实用
request常用方法2
request对象实现请求转发:请求转发指一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理。 request对象提供了一个getRequestDispatcher方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward方法可以实现请求转发。 request对象同时也是一个域对象,开发人员通过request对象在实现转发时,把数据通过request对象带给其它web资源处理。 setAttribute方法 getAttribute方法 removeAttribute方法 getAttributeNames方法
RequestDispather
表示请求分发器,它有两个方法: forward():把请求转发给目标组件
public void forward(ServletRequest request,ServletResponse response) throws ServletException,java.io.IOException include():包含目标组件的响应结果
public void include(ServletRequest request,ServletResponse response) throws ServletException,java.io.IOException 得到RequestDispatcher对象
1、ServletContext对象的getRequestDispather(String path1) path1必须用绝对路径,即以”/”开头,若用相对路径会抛出异常IllegalArgumentException
2、ServletRequest对象的getRequestDispatcher(String path2) path2可以用绝对路径也可以用相对路径
请求范围
web应用范围内的共享数据作为ServeltContext对象的属性而存在(setAttribute),只要共享ServletContext对象也就共享了其数据。 请求范围内的共享数据作为ServletRequest对象的属性而存在(setAttribute),只要共享ServletRequest对象也就共享了其数据。
重定向
重定向机制的运作流程 1、用户在浏览器端输入特定URL,请求访问服务器端的某个组件 2、服务器端的组件返回一个状态码为302的响应结果。 3、当浏览器端接收到这种响应结果后,再立即自动请求访问另一个web组件 4、浏览器端接收到来自另一个web组件的响应结果。 HttpServeltResponse的sendRedirect(String location)用于重定向
Servlet源组件生成的响应结果不会被发送到客户端。response.sendRedirect(String location)方法一律返回状态码为302的响应结果。 如果源组件在进行重定向之前,已经提交了响应结果,会抛出IllegalStateException。为了避免异常,不应该在源组件中提交响应结果。 在Servlet源组件重定向语句后面的代码也会执行。 源组件和目标组件不共享同一个ServletRequest对象。 对于sendRedirect(String location)方法的参数,如果以“/”开头,表示相对于当前服务器根路径的URL。以“http"//”开头,表示一个完整路径。 目标组件不必是同一服务器上的同一个web应用的组件,它可以是任意一个有效网页。
例子:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("注册成功!3秒钟跳到主页");
//设置3秒钟跳转
response.setHeader("refresh", "3;url=/day09_00_HttpServletResponse/servlet/demo6");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
Request 的例子
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//告诉服务器要使用什么编码,注:浏览器使用的是什么编码传过来的就是什么编码
request.setCharacterEncoding("UTF-8");//只能解决post方式的乱码
test1(request);
}
private void test1(HttpServletRequest request) {
//获取所有的表单name的名子
Enumeration names = request.getParameterNames();
while(names.hasMoreElements()){
String name = (String) names.nextElement();//得到每一个name名
String[] values = request.getParameterValues(name);//根据name名,得到value值
for (int i = 0;values!=null && i < values.length; i++) {
System.out.println(name+" "+values[i]);
}
}
}
//test1 方法
private void test1(HttpServletRequest request) throws UnsupportedEncodingException {
//获取表单数据
//根据表单中name属性的名,获取value属性的值方法
String userName = request.getParameter("userName");
String pwd = request.getParameter("pwd");
String sex = request.getParameter("sex");
String[] hobbys = request.getParameterValues("hobby");
String city = request.getParameter("city");
userName = new String(userName.getBytes("iso-8859-1"),"UTF-8");
System.out.println(userName);
System.out.println(pwd);
System.out.println(sex);
for (int i = 0;hobbys!=null && i < hobbys.length; i++) {
System.out.print(hobbys[i]+" ");
}
System.out.println();
System.out.println(city);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
请求重定向例子:
A:
public class ServletDemo7 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("A:我要借钱!");
System.out.println("B:我不有,但是我可以告诉你谁有");
/*//告诉客户端要重新定向新的资源
response.setStatus(302);
//告诉浏览器要去访问哪个URL
response.setHeader("location", "/day09_00_HttpServletResponse/servlet/demo8");*/
//请求重定向
response.sendRedirect("/day09_00_HttpServletResponse/servlet/demo8");
System.out.println("A: 我去了");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
B:
public class ServletDemo8 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("我有钱,我借你!");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
结果:
A:我要借钱!
B:我不有,但是我可以告诉你谁有
A: 我去了
我有钱,我借你!
include 例子:
ServletDemo5
public class ServletDemo5 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
String str = "aaaaa";
System.out.println("A:我想办事");
System.out.println("B:我办不了,但我可以找人帮你办");
//将非表单的数据添加到request的域中
request.setAttribute("s", str);
//将请求转发到demo6中
//request.getRequestDispatcher("/servlet/demo6").forward(request, response);
//注:请求转发不能跳转到其它应用
//使用重定向
//response.sendRedirect(request.getContextPath()+"/servlet/demo6");
System.out.println("B:事办完了");
//请求包含
request.getRequestDispatcher("/servlet/demo6").include(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
ServletDemo6:
public class ServletDemo6 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
System.out.println("这个事我能办");
//从request对象中获取s的值
String s = (String) request.getAttribute("s");
System.out.println(s);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
结果为:
A:我想办事
B:我办不了,但我可以找人帮你办
B:事办完了
这个事我能办
aaaaa
重定向和转发的区别
区别一:
重定向时浏览器上的网址改变
转发是浏览器上的网址不变
区别二:
重定向实际上产生了两次请求
转发只有一次请求
重定向:
发送请求 -->服务器运行-->响应请求,返回给浏览器一个新的地址与响应码-->浏览器根据响应码,判定该响应为重定向,自动发送一个新的请求给服务器,请求地址为之前返回的地址-->服务器运行-->响应请求给浏览器
转发:
发送请求 -->服务器运行-->进行请求的重新设置,例如通过request.setAttribute(name,value)-->根据转发的地址,获取该地址的网页-->响应请求给浏览器
区别三:
重定向时的网址可以是任何网址
转发的网址必须是本站点的网址
详解:
重定向:以前的request中存放的变量全部失效,并进入一个新的request作用域。
转发:以前的request中存放的变量不会失效,就像把两个页面拼到了一起。
正文开始:
先是看上去不同,他们的调用分别如下:
request.getRequestDispatcher("apage.jsp").forward(request, response);//转发到apage.jsp
response.sendRedirect("apage.jsp");//重定向到apage.jsp