JSP
内置对象 重点
request 对象获取用户请求 重点
response 对象处理响应 重点
转发与重定向 重点
session的原理及应用 重点
include指令 熟悉
掌握 JSP
内置对象
掌握 request 对象获取用户请求
掌握 response 对象处理响应
掌握 转发与重定向
掌握 session 的原理及应用
熟悉 include 指令
JSP
内置对象JSP
内置对象的概念Web容器:能装在web应用的容器,比如我们所学的Tomcat(webapps文件夹下就能够装载我们的web应用)
JSP
内置对象是 Web 容器创建的一组对象,在页面中可以直接使用。JSP
常用内置对象入下图所示:
javax.servlet.jsp.JspWriter
向Web浏览器内输出信息,负责管理对客户端的输出
<%
???? //在页面上输出Hello JSP
?? ?out.println("Hello JSP");
%>
javax.servlet.http.HttpServletRequest
获取客户端的参数和数据流
//根据表单组件名称获取提交数据
String getParameter(String name);
//获取表单组件对应多个值时的请求数据
String[] getParameterValues(String name);
//指定请求的编码
void setCharacterEncoding(String charset);
//返回一个RequestDispatcher对象,该对象的forward()方法用于转发请求
RequestDispatcher getRequestDispatcher(String path);
//获取客户端cookie 为什么能够获取cookie,主要是浏览器无条件的会将cookie中所有的数据在发送请求的
//携带上,这样,我们就可以从请求中获取cookie的信息了
Cookie[] getCookies();
//获取请求中所有参数和参数值的映射
Map<String,String[]> getParameterMap();
//获取当前会话
HttpSession getSession();
webapp目录就是我们访问视图时的根目录,根目录默认是一条斜杠,如果还存在子目录,访问的时候直接将子目录名称加上即可。如果只是访问视图,直接使用视图名即可。
"WEB-INF"这个目录下的所有内容都是受服务器保护的,不能够直接访问,只能通过服务器处理才能访问。
使用内置对象 request 完成注册信息显示
register.jsp
<form action="info.jsp" method="post">
<div><span>用户名</span><input type="text" name="username"></div>
<div><span>密码</span><input type="password" name="password"></div>
<div>
<span>信息来源</span>
<input type="checkbox" name="channel" value="报刊">报刊
<input type="checkbox" name="channel" value="网络">网络
<input type="checkbox" name="channel" value="朋友推荐">朋友推荐
<input type="checkbox" name="channel" value="电视"> 电视
</div>
<div>
<input type="submit" value="注册">
<input type="reset" value="重置">
</div>
</form>
info.jsp
<%
String name = request.getParameter("username");//获取参数username的值
String password = request.getParameter("password");//获取参数password的值
String[] channels = request.getParameterValues("channel");//获取参数channel的值
String channelInfo = Arrays.toString(channels).replaceAll("[\\[\\]]","");
%>
<div>用户名: <%= name %></div>
<div>密码: <%= password %></div>
<div>信息来源: <%= channelInfo %></div>
访问 register.jsp
,然后点击 注册
按钮,跳转后的页面中显示呈现乱码,如何解决呢?
在小脚本的第一行代码前面添加如下代码:
//在从请求中获取参数值之前,先对该请求的字符集编码进行设置
request.setCharacterEncoding("UTF-8");
再次测试,显示正常。但如果将 form
表单的提交方式修改为 get
,再测试,又出现了乱码,这如何解释呢?
这是因为 request.setCharacterEncoding("UTF-8");
只能解决 post
请求方式的出现的乱码,而 get
请求方式的乱码需要使用字符串转码的方式来解决。
//使用字符串的构造方法进行转码
new String(字符串.getBytes("ISO-8859-1"), "UTF-8");
转发可以访问WEB-INF下的资源,转发还可以共享请求中的参数
GET 请求的参数在URL中,而 POST 请求的参数在请求体(body) 中
GET 请求有数据长度限制,这个长度限制是浏览器或者服务器为了提升处理效率而做出的限制,而POST 请求没有。(HTTP协议本质就是一个有规则的字符串)
GET 请求的安全性低,因为参数在URL中,直接暴露了信息,而 POST 请求的安全性高,因为 POST 请求的参数在请求体(body) 中,隐藏了信息
javax.servlet.http.HttpServletResponse
对客户端请求做出响应
//添加cookie
void addCookie(Cookie c);
//重新定位新的资源,也叫重定向
void sendRedirect(String url);
//设置响应状态码
void setStatus(int status);
//获取打印流,主要用于向页面传输数据
PrintWriter getWriter();
//获取输出流,主要用于图片传输、下载等功能
ServletOutputStream getOutputStream();
//设置向页面输出的数据的字符集编码
void setCharacterEncoding(String charset);
实现登录页面跳转功能,并在跳转的页面中显示登录信息
login.jsp
<form action="process.jsp" method="post">
<div><span>用户名</span><input type="text" name="username"></div>
<div><span>密码</span><input type="password" name="password"></div>
<div>
<input type="submit" value="登录">
</div>
</form>
process.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<%
String username = request.getParameter("username");//获取参数username的值
String password = request.getParameter("password");//获取参数password的值
if("admin".equals(username) && "123456".equals(password)){
//页面重定向至主页面
response.sendRedirect("main.jsp");
}
%>
main.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<%
String username = request.getParameter("username");//获取参数username的值
String password = request.getParameter("password");//获取参数password的值
%>
<div>用户名: <%= username %></div>
<div>密码: <%= password %></div>
访问 login.jsp
,然后点击 登录
按钮,查看地址栏信息与页面信息。地址栏信息发生了变化,说明重定向发生在客户端,相当于客户端再发了一次请求,重新定位了新的资源。由于这次请求是新的请求,与之前的登录请求完全独立,因此页面信息中展示全是null
思考:如何才能将登录信息在跳转的页面中显示呢?
可以通过请求转发来实现,修改 process.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<%
String username = request.getParameter("username");//获取参数username的值
String password = request.getParameter("password");//获取参数password的值
if("admin".equals(username) && "123456".equals(password)){
//页面转发
request.getRequestDispatcher("main.jsp").forward(request, response);
}
%>
访问 login.jsp
,然后点击 登录
按钮,查看地址栏信息与页面信息。地址栏信息未发生变化,而页面进行了跳转,说明转发发生在服务器,由服务器完成。转发后,页面能够展示登录信息,说明转发可以共享请求的参数
session 就是浏览器与服务器之间的一次通话
HTTP 协议是一种无状态协议,用户在访问服务器时,服务器无法感知到用户是哪一个用户,也就无法追踪用户的后续操作。为了解决这一问题,服务器端设计了一个类 HttpSession
来感知用户,这个类产生的对象就是 session。在用户第一次访问服务器时,服务器就会为该用户生成了一个 session 对象,session 对象一产生就会生成了一个唯一标识符 JSESSIONID
, 并将这个唯一标识符使用Cookie存储在浏览器中,用户后续进行的每一个操作都将携带这个唯一标识符,服务器就根据这个唯一标识符追踪用户。session 对象产生时就有一个过期时间,主要用于检测用户是否还在进行有效的操作。如果用户具有有效的操作,那么每一次用户的有效操作都将重置该session的过期时间。这个过期时间就是检测用户登录超时的依据。除此之外,session 还可以存储数据。
javax.servlet.http.HttpSession
//以key/value的形式保存对象值
void setAttribute(String key, Object value);
//通过key获取对象值
Object getAttribute(String key);
//设置session对象失效
void invalidate();
// 获取sessionid
String getId();
//设定session的非活动时间
void setMaxInactiveInterval(intinterval);
//获取session的有效非活动时间(以秒为单位)
int getMaxInactiveInterval();
//从session中删除指定名称(key)所对应的对象
void removeAttribute(String key);
使用 session 完成登录成功后页面显示登录信息,要求登录处理使用重定向。
process.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
//获取参数username的值
String username = request.getParameter("username");
//获取参数password的值
String password = request.getParameter("password");
if ("admin".equals(username) && "123456".equals(password)) {
//将用户名存储在session中,方便后面使用的时候获取
session.setAttribute("user", username);
//页面重定向
response.sendRedirect("main.jsp");
}
%>
main.jsp
<nav><span>欢迎您,<%= session.getAttribute("user")%></span></nav>
<!-- 语法 -->
<%@ include file="文件名" %>
在开发过程中,开发的页面数量总是很多,如何确保用户的每一次操作都是有效操作呢?所谓的有效操作是指在登录没有超时的情况下进行的操作。
可以编写一个检测登录超时的页面,然后使用 include 指令引入至每一个页面中
timeout.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String username = (String)session.getAttribute("user");
if (username == null)
response.sendRedirect("login.jsp");
%>
main.jsp
<%@ include file="timeout.jsp" %>
第一种方式: Tomcat 中的 web.xml
<session-config>
<!-- 单位:分钟 -->
<session-timeout>30</session-timeout>
</session-config>
第二种方式: 工程中的 web.xml
<session-config>
<!-- 单位:分钟 -->
<session-timeout>30</session-timeout>
</session-config>
第三种方式: Java 代码实现
//设置会话超时时间,单位:秒
session.setMaxInactiveInterval(15 * 60);
javax.servlet.ServletContext
实现用户数据共享,将信息保存在服务器中,直到服务器关闭
// 以key/value的形式保存对象值
void setAttribute(String key,Object value);
//通过key获取对象值
Object getAttribute(String key);
//返回相对路径的真实路径
String getRealPath(String path);
统计网站访问次数
statistics.jsp
<%
Integer count = (Integer) application.getAttribute("count");
if(count == null){
count = 1;
} else {
count += 1;
}
application.setAttribute("count", count);
%>
<div>
当前网站访问量:<%= count %>
</div>
启动服务器,然后访问测试
Cookie 是 Web 服务器保存在客户端的一系列文本信息。Session 机制采用的是在服务端保持状态的方案,而Cookie 机制则是在客户端保持状态的方案,Cookie 又叫会话跟踪机制,用来弥补HTTP无状态协议的不足
弥补HTTP无状态协议的不足
简化登录,比如记住密码、自动登录等
//构造方法
Cookie cookie = new Cookie("名称", "值");
//设置cooki的有效期,以秒为单位
void setMaxAge(int expiry);
//在cookie创建后,对cookie进行赋值
void setValue(String value);
//获取cookie的名称
String getName();
//获取cookie的值
String getValue();
//获取cookie的有效时间,以秒为单位
String getMaxAge();
使用 Cookie 完成记住账号和密码功能
login.jsp
<%@ page import="java.net.URLDecoder" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>登录</title>
</head>
<body>
<%
// 用户名
String username = "";
// 登录密码
String password = "";
// 复选框是否选中
String checked = "";
// 获取的是请求里的所有cookie组成的数组
Cookie[] cookies = request.getCookies();
// 如果cookies数组不为空对其进行遍历
if (cookies != null && cookies.length > 0) {
// 循环遍历Cookie
for (int i = 0; i < cookies.length; i++) {
// 获取Cookie对象
Cookie cookie = cookies[i];
// 将创建的cookie名与获取的cookie数组中已经存在的cookie名进行比较
if ("username".equals(cookie.getName())) {
// "name"是在另一个jsp文件中创建的cookie名
// 获取名字叫做"name"的cookie的值
username = URLDecoder.decode(cookie.getValue(), "utf-8");
// 将“记住我”设置为勾选
checked = "checked";
}
// 将创建的cookie名与获取的cookie数组中已经存在的cookie名进行比较
if ("password".equals(cookie.getName())) {
// "password"是在另一个jsp文件中创建的cookie名
// 获取名字叫做"password"的cookie的值
password = cookie.getValue();
}
}
}
%>
<div>
<h1>用户登录</h1>
<form action="login.jsp" method="POST">
<%--<%=user%>指的是将获取的cookie值放进输入框内--%>
<img src="img/login.png"><input type="text" name="username" value="<%=user%>"/><br/><br/>
<img src="img/password.png"><input type="password" name="password" value="<%=password%>"/><br/><br/>
<input type="checkbox" name="rememberMe" checked="<%=checked%>"/>记住我
<input type="submit" name="login" value="登录"/>
</form>
</div>
</body>
</html>
process.jsp
<%@ page import="java.net.URLEncoder" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
// 获取输入用户名文本框的值
String username = request.getParameter("username");
// 获取输入密码的密码框的值
String password = request.getParameter("password");
// 在这里进行用户名和密码匹配,在这里是将用户名和密码规定死了的。
// 即用户名必须是"hello",密码必须是"world"才能登录成功
if (username.equals("admin") && password.equals("123456")) {// 如果用户名和密码都正确
// 新建名为name的Cookie
Cookie usernameCookie = new Cookie("username", URLEncoder.encode(username, "utf-8"));
// 新建名为password的Cookie
Cookie passwordCookie = new Cookie("password", password);
// 获取是否保存Cookie
String rememberme = request.getParameter("rememberMe");
// 判断复选框是否被选中,如果选中则返回on
if (rememberme.equals("on")) {
// 设置保存Cookie的时间长度,单位为秒
usernameCookie.setMaxAge(7 * 24 * 60 * 60);
passwordCookie.setMaxAge(7 * 24 * 60 * 60);
} else {
// 设置将不保存Cookie
usernameCookie.setMaxAge(0);
passwordCookie.setMaxAge(0);
}
// 输出到客户端
response.addCookie(nameCookie);
response.addCookie(passwordCookie);
// 登录成功后跳转到success.jsp
request.getRequestDispatcher("success.jsp").forward(request, response);
} else {// 如果用户名和密码都不正确
// 保存错误提示数据
session.setAttribute("error", "用户名或密码不正确");
// 登录失败后将跳转到error.jsp
request.getRequestDispatcher("error.jsp").forward(request, response);
}
%>
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录成功</title>
</head>
<body>
<h1>恭喜你,登录成功!</h1>
</body>
</html>
error.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录失败</title>
</head>
<body>
<h1 style="color: red">Error:<%=session.getAttribute("error")%></h1>
</body>
</html>