1.response对象的主要作用和操作方法

response对象表示的是服务器对客户端(浏览器)的响应,是HttpServletResponse接口的对象,
这个接口是ServletResponse接口的子接口,ServletResponse也是有且仅有这么一个子接口,
这样的设计和request对象的设计类似,也是为了以后有新的协议出现,更好的拓展。

response对象的主要作用有三个:
	· 设置头信息:主要用于修改头信息内容
	· 设置Cookie
	· response进行跳转(重定向|客户端跳转)
	
response对象的主要的操作方法:
	·添加Cookie:void addCookie(Cookie cookie)
	·进行跳转:void sendRedirect(String location)  
	·设置响应的MIME类型:void setContentType(String type)
	·设置响应的编码:void setCharacterEncoding(String charset)
	·添加头信息:void addHeader(String name,  String value)
	.设置头信息setHeader()   set修改设置add添加

2.设置头信息

头信息是指能够随着浏览器一起提交到服务器,而后又能够从服务器响应给客户端的一些信息,叫做头信息,
头信息分为请求头和响应头,头信息的内容有很多,
可以使用头信息进行页面定时的刷新或者定时的跳转功能。
使用response对象可以设置头信息的内容,通过request对象取得头信息内容。
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ page import = "java.util.*" %>
<!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=utf-8">
<title>Insert title here</title>
</head>
<body>
	<%
		Enumeration<String> headNames = request.getHeaderNames();//取得所有头信息名称
		while(headNames.hasMoreElements()){
		String headerName = headNames.nextElement();//循环取得每一个头信息的名称
	%>
			<h2><%= headerName %> ----- <%= request.getHeader(headerName) %></h2>
	<%
		}
	%>
</body>
</html>

第一次运行,取得的头信息内容如下:

host ----- localhost
user-agent ----- Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0
accept ----- text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
accept-language ----- zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
accept-encoding ----- gzip, deflate
connection ----- keep-alive
referer ----- http://localhost/JavaWeb/jsp/
upgrade-insecure-requests ----- 1

第二次运行,取得的头信息如下:

host ----- localhost
user-agent ----- Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0
accept ----- text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
accept-language ----- zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
accept-encoding ----- gzip, deflate
referer ----- http://localhost/JavaWeb/jsp/
connection ----- keep-alive
cookie ----- JSESSIONID=717A4EBDBA018A7C91BCE1879D1D5495
upgrade-insecure-requests ----- 1
cache-control ----- max-age=0
通过运行结果的对比,发现第二次运行比第一次运行多了一个cookie,内容是JSESSIONID,
实际上这个ID就是第一次访问服务器的时候,服务器自动设置上的,
所以第二次访问的时候可以显示,这个ID实际上是服务器区分不同的客户端用的。

范例:页面定时刷新:

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ page import = "java.util.*" %>
<!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=utf-8">
<title>Insert title here</title>
</head>
<body>
	<%!
	//定义全局变量
		int count = 0;
	%>
	<%
		response.setHeader("refresh", "1");//设置头信息(1秒刷新一次)
	%>
	<h1><%=count++ %></h1>
</body>
</html>

这种定时刷新的功能也可以通过html中的标签完成:

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ page import = "java.util.*" %>
<!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=utf-8">
<meta http-equiv="refresh" content="1"><!-- 定时刷新设置  -->
<title>Insert title here</title>
</head>
<body>
	<%!
	//定义全局变量
		int count = 0;
	%>
	<h1><%=count++ %></h1>
</body>
</html>

定时刷新的功能,经过适当的设置,可以完成定时跳转的功能:

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ page import = "java.util.*" %>
<!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=utf-8">
<!-- <meta http-equiv="refresh" content="1">定时刷新设置  -->
<title>Insert title here</title>
</head>
<body>
	<%
		response.setHeader("refresh", "5;URL=http://www.wanczy.com");//5秒之后跳转到万策智业
	%>
	<h1>此网站5秒后跳转到万策智业,如果没有跳转,请点击<a href="http://www.wanczy.com">这里</a></h1>
</body>
</html>

当然也可以通过meta标签完成定时的跳转:

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ page import = "java.util.*" %>
<!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=utf-8">
 <meta http-equiv="refresh" content="3;URL=http://www.wanczy.com"><!--定时跳转  -->
<title>Insert title here</title>
</head>
<body>
	<h1>此网站5秒后跳转到万策智业,如果没有跳转,请点击<a href="http://www.wanczy.com">这里</a></h1>
</body>
</html>
以上的两种操作,无论使用哪一种,都可以完成定时刷新和跳转的功能,
而且我们发现跳转之后地址栏是有变化的,所以此种跳转也是重定向(客户端跳转)。

3.操作Cookie

Cookie:表示的是服务器保存在客户端的一组数据,因为存储在客户端,所以不安全。

在jsp中可以使用request获取Cookie。

Cookie本身是一个类,有其常用的操作方法:
·public Cookie(String name, String value):构造带有名称和值的Cookie对象
·取得Cookie的名称:public String getName()
·取得Cookie的值:public String getValue()
·设置Cookie最大保存时间,单位秒:public void setMaxAge(int expiry)
·设置Cookie的值:public void setValue(String newValue)

怎么将Cookie添加到客户端呢?

需要response对象完成:void addCookie(Cookie cookie)

如何取得客户端中的Cookie呢?

使用request对象取得客户端上面所有的Cookie信息:Cookie[] getCookies()

范例:设置新的Cookie

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ page import = "java.util.*" %>
<!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=utf-8">
<title>Insert title here</title>
</head>
<body>
	<%   //创建Cookie对象
		Cookie c1 = new Cookie("userName","jjm");
		Cookie c2 = new Cookie("userPass","jjm123");
		
		response.addCookie(c1);//将Cookie添加到客户端
		response.addCookie(c2);
	%>
</body>
</html>

范例:取得Cookie

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ page import = "java.util.*" %>
<!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=utf-8">
<title>Insert title here</title>
</head>
<body>
	<%
		Cookie cookie[] = request.getCookies();//取得客户端上面所有的Cookie
		for(Cookie c : cookie){
			%>
			<h1><%=c.getName() %> </h1>
            <h1><%=c.getValue() %></h1>
			<%
		}
	%>
</body>
</html>
新的浏览器访问的时候,第一次出现空指针异常,第二次显示了Cookie内容为JSESSIONID。
问题说明:实际上在新的浏览器第一次访问服务器时,服务器会将JSESSIONID设置为浏览器的Cookie,
所以第一次空指针异常原因在于服务器还没有设置Cookie就访问了Cookie,明显取得的Cookie是null,
浏览器第二次访问显示JSESSIONID是因为第一次访问的时候服务器已经将JSESSIONID设置到Cookie上去了,
那么如何设置Cookie。依靠response对象来设置Cookie,addCookie()方法就是将Cookie设置到客户端。

现在我们设置了两个Cookie,但是在取得的时候,取得了三个,多了一个JSESSIONID,实际上也是服务器自动设置的,
用来区分不同的客户端。但是在我们重启浏览器之后,要取得之前设置的Cookie,发现获取不到,而且程序报错,
这个原因在于,Cookie默认只存储在当前的浏览器中,当浏览器关闭,那么设置Cookie也就消失了,
如果想要让Cookie保存较长的时间(单位为秒),那么我们可以设置Cookie的最大保存时间。
设置Cookie最大保存时间:public void setMaxAge(int expiry)
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ page import = "java.util.*" %>
<!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=utf-8">
<title>Insert title here</title>
</head>
<body>
	<%
		Cookie c1 = new Cookie("userName","jjm");
		Cookie c2 = new Cookie("userPass","jjm123");
		c1.setMaxAge(30);
		c2.setMaxAge(60);//设置最大保存时间为60秒
		
		response.addCookie(c1);//将Cookie添加到客户端
		response.addCookie(c2);
	%>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ page import = "java.util.*" %>
<!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=utf-8">
<title>Insert title here</title>
</head>
<body>
	<%
		Cookie cookie[] = request.getCookies();//取得客户端上面所有的Cookie
		for(Cookie c : cookie){
			%>
			<h1><%=c.getName() %> </h1>
            <h1><%=c.getValue() %></h1>
			<%
		}
	%>
</body>
</html>

4.response跳转

用request.ContextPath()获得项目的绝对路径,获取的是配置虚拟目录的路径,

就是web项目的根目录,在后面加上文件资源路径就行了。

跳转:
·转发(服务端跳转):地址栏不会变化,使用jsp:forward进行跳转
·重定向(客户端跳转):地址栏会变化,表单提交,a标签,设置头信息自动跳转
使用response进行跳转,方法是sendRedirect(路径)直接完成跳转的操作。(重定向)response.sendRedirect("Demo01.jsp");
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ page import = "java.util.*" %>
<!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=utf-8">
<title>Insert title here</title>
</head>
<body>
	<%
		response.sendRedirect("Demo01.jsp");
	%>
</body>
</html>
此时页面进行了跳转,而且地址栏显示的是Demo01.jsp,说明此种形式的跳转也是属于重定向的范畴,
既然是重定向的话,我们也需要注意404错误的发生(使用绝对路径)。
用request.ContextPath()获得项目的绝对路径,获取的是配置虚拟目录的路径,
就是web项目的根目录,在后面加上文件资源路径就行了。
使用重定向:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ page import = "java.util.*" %>
<!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=utf-8">
<title>Insert title here</title>
</head>
<body>
	<%
		System.out.println("重定向之前");
	%>
	<%
		response.sendRedirect(request.getContextPath()+"/jsp/Demo01.jsp");
	%>
	<%
		System.out.println("重定向之后");
	%>
</body>
</html>
使用转发:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ page import = "java.util.*" %>
<!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=utf-8">
<title>Insert title here</title>
</head>
<body>
	<%
		System.out.println("转发之前");
	%>
	<jsp:forward page="/jsp/Demo01.jsp"/>
	<%
		System.out.println("转发之后");
	%>
</body>
</html>
发现重定向之前和重定向语句后的代码都会执行,而转发后的代码不会执行,说明转发和重定向还有区别:
转发和重定向的区别:
转发(服务端)   <jsp:forward page="/jsp/Demo01.jsp"/>
跳转之后,地址栏不会发生变化
只要执行到跳转的代码,会立刻无条件跳转
可以传递request请求域对象

重定向(客户端)   response.sendRedirect("Demo01.jsp");
重定向之后,地址栏会发生变化
是将整个页面执行完成之后,再进行跳转的
不可以传递request请求域对象

总结:

response表示的是服务器对客户端的响应
设置头信息的话,最主要的作用就是设置定时的刷新和定时的跳转
对于Cookie来说,表示的是服务器存储在客户端的一组数据,包括JSESSIONID,
使用response进行设置,通过request可以取得
头信息的内容和Cookie的内容都可以使用request对象获取
对于response的跳转,我们一定要清楚其属于重定向操作,而且要掌握重定向和转发的区别。

练习:

继续修改登陆程序,将验证成功的用户名和密码保存在Cookie,1分钟之内免登陆:
·一种情况:访问登录页面,直接跳转到登陆成功
·二种情况:访问登录页面,1分钟自动的将用户名和密码填入表单中
login.jsp页面代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<%
		Cookie cookies[] = request.getCookies();
		if(null!= cookies && cookies.length >= 2){ //表示Cookie中已经存在用户名及密码
			String username = "";
			String password = "";
			for(Cookie cook : cookies){
				if(cook.getName() .equals("username")){
					username = cook.getValue();
				}
				if(cook.getName() .equals("password")){
					password = cook.getValue();
				}
			}
			
			%>
			<jsp:forward page="loginCheck.jsp">
				<jsp:param value="<%=username %>" name="username"/>
				<jsp:param value="<%=password %>" name="password"/>
			</jsp:forward>
			<%
			
		}
	
	%>
	<form action="loginCheck.jsp" method="post">
		用户名:<input type="text" name="username">
		密码:<input type="password" name="password">
		<input type="submit" value="登录">
	</form>
</body>
</html>
loginCheck.jsp页面代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.sql.*,com.wanbangee.util.*" %>
<!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=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<%
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		Connection conn = MySQLUtil.getConnection();
		String sql = "select acc_id,acc_balance from account where acc_name = ? and acc_pass = ?";
		PreparedStatement state = conn.prepareStatement(sql);
		state.setString(1,username);
		state.setString(2,password);
		ResultSet res = state.executeQuery();
		while(res.next()){
			//登录成功//跳转到books.jsp
			/* session.setAttribute("accId",res.getInt(1));
			session.setAttribute("accBalance",res.getDouble(2));
			session.setAttribute("accName",username); */
			pageContext.setAttribute("accId",res.getInt(1),PageContext.SESSION_SCOPE);
			pageContext.setAttribute("accBalance",res.getDouble(2),PageContext.SESSION_SCOPE);
			pageContext.setAttribute("accName",username,PageContext.SESSION_SCOPE);
			
			//将用户名和密码放入到Cookie中,如果Cookie中已经存在用户名和密码,那么就不需要再次加入到Cookie中
			Cookie[] cookies = request.getCookies();//获得所有的Cookie
			if(cookies.length <= 1){//说明用户名和密码没有放置到Cookie中
				Cookie cook1 = new Cookie("username",username);
				cook1.setMaxAge(60);
				Cookie cook2 = new Cookie("password",password);
				cook2.setMaxAge(60);
				response.addCookie(cook1);
				response.addCookie(cook2);
			}
			
			%>
			<jsp:forward page="books.jsp"/>
			<%
		}
	%>
		<jsp:forward page="fail.jsp"/>
</body>
</html>
books.jsp页面代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>登录成功,欢迎您:<%= session.getAttribute("accName") + ",您的账户余额为:" + session.getAttribute("accBalance") %></h1>
</body>
</html>