JSP(Java Server Pages),其根本是一个简化的 Servlet 设计,实现了在 Java 当中使用 HTML 标签。JSP 是一种动态网页技术标准,也是Java EE的标准。JSP与Servlet一样,是在服务器端执行的。
常见动态网站开发技术对比
- JSP:Java平台,安全性高,适合开发大型的,企业级的Web应用程序。
- Asp.net:.Net平台,简单易学。但是安全性以及跨平台型差。
- Php:简单,搞笑,成本低,开发周期短,特别适合中小型企业的Web应用开发。(LAMP:linux+Apache+MySql+Php)
JSP 基本语法
Jsp页面元素构成
- 指令
- 表达式
- 小脚本
- 声明
- 注释
- 静态内容
指令
- page 指令。
- include 指令。将一个外部文件嵌入到当前jsp文件中,同时解析这个页面中的jsp语句。
- taglib 指令。使用标签库定义新的自定义标签,在jsp页面中启用定制行为。
page
page 指令。通常位于jsp页面的顶端,同一个页面可以有多个page指令。
语法:
<%@ page 属性1="属性值" 属性2="属性值1,属性值2" ... 属性n="属性值n" %>
属性 | 描述 | 默认值 |
---|---|---|
language | 指定jsp页面使用的脚本语言 | java |
import | 通过该属性来引用脚本语言中使用到的类文件 | 无 |
contentType | 用来指定jsp页面所采用的编码格式 | IntelliJ IDEA中:text/html;charset=UTF-8<br />Eclipse中:text/html; charset=ISO-8859-1 |
【Eclipse 新建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>
</body>
</html>
【IntelliJ IDEA 新建jsp默认代码如下】
<%--
Created by IntelliJ IDEA.
User: zdy
Date: 2016/12/28 0028
Time: 11:09
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
</body>
</html>
include
include 指令。将一个外部文件嵌入到当前jsp文件中,同时解析这个页面中的jsp语句。
语法:
<%@ include file="url" %>
【示例】
<%@include file="date.jsp" %>
date.jsp
<body>
<%
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy年MM月dd日");
Date date=new Date();
String s=simpleDateFormat.format(date);
out.println(s);
%>
</body>
taglib
taglib 指令。使用标签库定义新的自定义标签,在jsp页面中启用定制行为。
注释
HTML注释,客户端源代码可见
<!--html注释-->
JSP 注释,客户端源代码不可见
<%--JSP注释--%>
JSP 脚本注释,客户端源代码不可见。位于<% %>中的注释。
//单行注释
/**/多行注释
脚本
在jsp中执行的java代码。
语法:
<% java 代码 %>
【示例】
<body>
你好,JSP!
<!--我是html注释-->
<%--我是jsp注释--%>
//我是注释吗?我不是注释
/*我是注释吗?我不是注释*/
<%
//单行注释
/*多行注释*/
out.println("大家好,我能显示在页面上!");
System.out.println("大家好,我不能显示在页面上,我打印在控制台上!");
%>
</body>
声明
在jsp页面中定义变量或者方法。
语法:
<%! java 代码 %> //语句以分号结束
表达式
在jsp页面中执行的表达式。
语法:
<%= 表达式 %> //表达式不以分号结束
【示例】
<body>
<%!
String s="zdy";//声明一个变量
//声明一个函数
int add(int x,int y){
return x+y;
}
%>
你好,<%=s%>,10+5=<%=add(10,5)%>
</body>
【页面显示】
你好,zdy,10+5=15
【实例2】
<%!
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
String s=sdf.format(new Date());
%>
今天是:<%=s%>
【页面显示】
今天是:2016-12-28
JSP 页面生命周期
JSP 内置对象
JSP内置对象是Web容器创建的一组对象,不适用new关键字就可以使用的内置对象。
JSP 九大内置对象
- 常用的:out,request,response,session,application
- 不常用的:page,pageContext,exception,config
Web 程序的请求响应模式
- 用户发送请求(request)
- 服务器给用户响应(response)
缓冲区buffer,内存的一块区域用来保存临时数据。
out
JspWriter类的实例,是向客户端输出内容常用的对象。
- void println() 向客户端打印字符串
- void clear() 清除缓冲区的内容,如果在flush之后调用会抛出异常
- void clearBuffer() 清除缓冲区的内容,如果在flush之后调用不会抛出异常
- void flush() 将缓冲区内容输出到客户端
- int getBufferSize() 返回缓冲区字节数的大小,如不设缓冲区则为0
- int getRemaining() 返回缓冲区还剩余多少可用
- boolean isAutoFlush() 返回缓冲区满时,是自动清空还是抛出异常
- void close() 关闭输出流
【示例】
缓冲区大小:<%=out.getBufferSize()%>Byte<br />
缓冲区剩余大小:<%=out.getRemaining()%>Byte<br />
是否自动清空缓冲区:<%=out.isAutoFlush()%><br />
request
客户端的请求信息被封装在 request 对象中,通过他才能了解到客户的需求,然后做出响应。它是 HttpServletRequset 类的实例。request 对象具有请求域,即完成客户端的请求之前,该对象一直有效。
常用方法
- String getParameter(String name) 返回name指定参数的参数值
- String[] getParameterValues(String name) 返回包含参数name的所有值的数组
- void setAttribute(String,Object) 存储此请求中的属性
- object getAttribute(String name) 返回指定属性的属性值
- String getContentType() 得到请求体的MIME类型
- String getProtocol() 返回请求用的协议类型及版本号
- String getServerName() 返回接收请求的服务器主机名
- int getServerPort() 返回服务器接受此请求所用的端口号
- String getCharacterEncoding() 返回字符编码方式
- void setCharacterEncoding(String) 设置请求的字符编码方式
- int getContentLength() 返回请求体的长度(字节)
- String getRemoteAddr() 返回发送此请求的客户端ip地址
- String getRealPath(String path) 返回一虚拟路径的真实路径【已经被弃用deprecated】
- String request.getContextPath() 返回上下文路径
解决表单中文乱码问题:
<%
request.setCharacterEncoding("utf-8");
%>
解决URL中文乱码问题:
<Connector port="8888" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="utf-8" />
【示例】
index.jsp
<body>
<form action="dologin.jsp" name="loginForm" method="post">
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td>爱好:</td>
<td>
<input type="checkbox" name="f" value="read">读书
<input type="checkbox" name="f" value="music">音乐
<input type="checkbox" name="f" value="movie">电影
<input type="checkbox" name="f" value="internet">上网
</td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="login"></td>
</tr>
</table>
</form>
<a href="dologin.jsp?username=张丹阳">link</a>
</body>
dologin.jsp
<body>
登录成功!<br />
<%
request.setCharacterEncoding("utf-8");
request.setAttribute("attr","123456");
%>
用户名:<%=request.getParameter("username")%><br />
密码:<%=request.getParameter("password")%><br />
attr:<%=request.getAttribute("attr")%><br />
爱好:
<%
String[] f=request.getParameterValues("f");
if (f!=null){
for (String s:f) {
out.println(s);
}
}
%><br />
MIME类型:<%=request.getContentType()%><br />
协议类型及版本号:<%=request.getProtocol()%><br />
服务器主机名:<%=request.getServerName()%><br />
服务器端口号:<%=request.getServerPort()%><br />
请求文件的长度:<%=request.getContentLength()%><br />
请求客户端的IP地址:<%=request.getRemoteAddr()%><br />
请求的上下文路径:<%=request.getContextPath()%>
</body>
【页面显示 http://localhost:8888/MyWeb/dologin.jsp】
登录成功!
用户名:张丹阳
密码:8888888888
attr:123456
爱好: read music
MIME类型:application/x-www-form-urlencoded
协议类型及版本号:HTTP/1.1
服务器主机名:localhost
服务器端口号:8888
请求文件的长度:71
请求客户端的IP地址:0:0:0:0:0:0:0:1
请求的上下文路径:/MyWeb
response
response对象包含了响应客户请求的有关信息,但在JSP中很少直接用到它。是 HttpServletResponse 类的实例。response 对象具有页面作用域,即访问一个页面时,该页面内的 response 对象只能对这次访问有效,其它页面的 response 对象对当前页面无效。
常用方法
- String getCharacterEncoding() 返回响应用的是何种字符编码
- void setContentType(String type) 设置相应的MIME类型
- PrintWriter getWriter() 返回可以向客户端输出字符的一个对象(跟out对象对比,此对象输出总是先于out对象输出)
- sendRedirect(java.lang.String location) 重新定向客户端的请求
【示例】
<body>
<%
response.setContentType("text/html;charset=UTF-8");
out.println("这是out输出");
out.flush();
PrintWriter outer=response.getWriter();
outer.println("response.getWriter()实例输出");
%>
</body>
<%
response.sendRedirect("index.jsp");//请求重定向
%>
请求转发与请求重定向
- 请求重定向:客户端行为,response.sendRedirect(),从本质上讲等同于两次请求,前一次的请求对象不会保存,地址栏的URL地址会改变。
- 请求转发:服务器行为, request.getRequestDispatcher().forward(req,resp) 是一次请求,转发后请求对象会保存,地址栏的URL地址不会改变。
【示例】
//请求重定向
response.sendRedirect("request.jsp");
//请求转发
request.getRequestDispatcher("dologin.jsp").forward(request,response);
session
- session 表示客户端与服务器的一次会话
- Web 中的 session 指的是用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间,也就是用户浏览这个网站所花费的时间
- session 实际是一个特定的时间概念
- 在服务器的内存中保存着不同用户的 session ,与用户一一对应
- session 对象是一个jsp内置对象
- session 对象在第一个jsp页面被装载时自动创建,完成会话期管理
- 从一个客户打开浏览器并连接到服务器开始,到客户关闭浏览器离开这个服务器结束,被称为一个会话
- 当一个客户访问一个服务器时,可能会在服务器的几个页面之间切换,服务期应当通过某种方法知道这是一个客户,就需要session对象
- session 对象是 HttpSession 类的实例
常用方法
- long getCreationTime() 返回session创建时间
- public String getId() 返回session创建时jsp引擎为他设置的唯一ID号
- public Object setAttribute(String name,Object value) 使用指定名称将对象绑定到此会话
- public Object getAttribute(String) 返回与此会话中的指定名称绑定在一起的对象,如果没有对象绑定在该名称下,则返回null
- Enumeration getAttributeNames() 返回一个包含此session中所有可用属性的数组
- int getMaxInactiveInterval() 返回两次请求间隔多长时间此session被取消掉(单位秒)
【示例】
session.jsp
<body>
<%
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date=new Date(session.getCreationTime());
session.setAttribute("username","zdy");
session.setAttribute("password","pwd");
session.setAttribute("age",20);
session.setMaxInactiveInterval(10);//10s
%>
Session创建时间:<%=simpleDateFormat.format(date)%><br />
Session ID:<%=session.getId()%><br />
从Session中获取用户名:<%=session.getAttribute("username")%><br />
Session中保存的属性有:
<%
Enumeration<String> m=session.getAttributeNames();
Enumeration enumeration=session.getAttributeNames();
while (enumeration.hasMoreElements()){
Object e=enumeration.nextElement();
out.println("属性名:"+ e.toString());
out.println("属性值:"+session.getAttribute(e.toString()));
}
%>
<a href="session2.jsp" target="_blank">跳转</a>
</body>
session2.jsp
<body>
<%
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date=new Date(session.getCreationTime());
%>
Session创建时间:<%=simpleDateFormat.format(date)%><br />
Session ID:<%=session.getId()%><br />
从Session中获取用户名:<%=session.getAttribute("username")%><br />
</body>
session 生命周期
- 创建:当客户端第一次访问某个jsp或者Servlet时,服务器会为当前会话创建一个SessionId,每次客户端向服务端发送请求时,都会将此SessionId携带过去,服务端会对此SessionId进行校验。
- 活动:
- 某次会话当中通过超链接打开的新页面属于同义词会话
- 只要当前会话页面没有全部关闭,重新打开新的浏览器窗口访问同一项目资源时属于同一次会话
- 除非本次会话的所有页面都关闭后再重新访问某个jsp或者Servlet将会创建新的会话
- 注意:原有会话还在,只是这个旧的SessionId依然存在于服务端,只不过再也没有客户端会携带它然后交与服务端校验。
- 销毁:
- 调用了session.invalidate()方法
- session过期(超时)
- 服务器重新启动
设置session超时时间的方式
方法1:session.setMaxInactiveInterval(10);//单位秒
方法2:web.xml中配置(单位是分钟):
<session-config>
<session-timeout>30</session-timeout>
</session-config>
application
- application对象实现了用户间数据的共享,可存放全局变量
- application开始于服务器的启动,终止于服务器的关闭
- 在用户的前后连接或不同用户之间的连接中,可以对application对象的同一属性进行操作
- 在任何地方对application对象属性的操作,都将影响到其他用户对此的访问
- 服务器的启动和关闭决定了application对象的生命
- application对象是ServletContext类的实例
常用方法
- public void setAttribute(String name,Object value)使用指定名称将对象绑定到此会话
- public Object getAttribute(String names) 返回与此会话中的指定名称绑定在一起的对象,如果没有对象绑定在该名称下,则返回null
- Enumeration getAttributeNames() 返回所有可用属性名的枚举
- String getServerInfo() 返回 JSP (Servlet) 引擎名及版本号
【示例】
<body>
<%
application.setAttribute("city","北京");
application.setAttribute("postcode","100000");
application.setAttribute("extel","010");
%>
城市:<%=application.getAttribute("city")%><br />
application属性有:
<%
Enumeration enumeration=application.getAttributeNames();
while (enumeration.hasMoreElements()){
out.println(enumeration.nextElement().toString()+" ");
}
%><br />
JSP(SERVLET)引擎名与版本号:<%=application.getServerInfo()%><br />
</body>
page
page对象指向当前jsp页面本身(类似类中的this指针),是java.lang.Object类的实例。
常用方法
- class getClass() 返回此Object的类
- int hashCode() 返回此Object的hash码
- boolean equals(Object obj) 判断此 Object 是否与指定的 Object 对象相等
- void copy(Object obj) 把此Object拷贝到指定的Object对象中
- Object clone() 克隆此 Object 对象
- String toString() 把此 Object 对象转换成 String 类的对象
- void notify() 唤醒一个等待线程
- void notifyAll() 唤醒所有等待线程
- void wait(int timeout) 使一个线程出于等待直到timeout结束或被唤醒
- void wait() 使一个线程出于等待直到被唤醒
pageContext
- pageContext 对象提供了对jsp页面内所有对象及名字空间的访问
- pageContext 对象可以访问到本业所在的session,也可以获取本页面所在的application的某一属性值
- pageContext 对象相当于页面中所有功能的集大成者
- pageContext 对象的本类名也叫 pageContext
常用方法
- JspWriter getOut() 返回当前客户端响应被使用的 JspWriter 流(out)
- HttpSession getSession() 返回当前页中的 HttpSession 对象(session)
- Object getPage() 返回当前页的 Object 对象(page)
- ServletRequest getRequest() 返回当前页的 ServletRequest 对象(request)
- ServletResponse getResponse() 返回当前页的 ServletResponse 对象(response)
- void setAttribute(String name,Object attribute) 设置属性及属性值
- Object getAttribute(String name,int scope) 在指定范围内获取属性的值
- int getAttributeScope(String name) 返回某属性的作用范围
- void forward(String relativeUrlPath) 使当前页面重导到另一页面,url不变
- void include(String relativeUrlPath) 在当前位置包含另一文件
【示例1】
用户名是:<%=pageContext.getSession().getAttribute("username")%>
【示例2】
<%
pageContext.forward("index.jsp");
%>
【示例3】
<%
pageContext.include("index.jsp");
%>
Config
config 是在一个 Servlet 初始化时,jsp引擎向它传递信息用的,此信息包括 Servlet 初始化时所要用到的参数(通过属性名和属性值构成)以及服务器的有关信息(通过传递一个ServletContext对象)
常用方法
- ServletContext getServletContext() 返回含有服务器相关信息的 ServletContext 对象
- String getInitParameter(String name) 返回初始化参数的值
- Enumeration getInitParameterNames() 返回 Servlet 初始化所需所有参数的枚举
exception
exception 对象是一个异常对象,当一个页面中在运行过程中发生了异常,就产生这个对象。如果一个JSP页面要应用此对象,就必须把 isErrorPage 设为true(在page指令中设置),否则无法编译。他实际上是java.lang.Throwable 的对象。
常用方法
- String getMessage() 返回描述异常的消息
- String toString() 返回关于异常的简短描述信息
- void printStackTrace() 显示异常及其栈轨迹
- Throwable FillStackTrace() 重写异常的执行栈轨迹
【示例】
exception.jsp 在page指令中将错误页面定向到error.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" errorPage="error.jsp" %>
<html>
<head>
<title>exception</title>
</head>
<body>
<%
System.out.println(100/0);
%>
</body>
</html>
error.jsp 在page指令中指定 isErrorPage 为true
<%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true" %>
<html>
<head>
<title>Title</title>
</head>
<body>
异常消息是:<%=exception.getMessage()%><br />
异常的字符串描述:<%=exception.toString()%>
</body>
</html>
【运行结果】页面url未该变,是exception.jsp
异常消息是:/ by zero
异常的字符串描述:java.lang.ArithmeticException: / by zero
JavaBean
JavaBean 就是符合某种特定规范的java类。使用 JavaBeans 的好处是解决代码重复编写,减少代码的冗余,功能区分明确,提高代码的维护性。
设计原则
- 公有类
- 无参的公有构造方法
- getter和setter方法
- 属性私有
Jsp动作
jsp动作元素(action elements)为请求处理阶段提供信息。动作元素遵循xml元素的语法,有一个包含元素明德开始标签,可以有属性、可选的内容、与开始标签匹配的结束标签。
第一类:与存取JavaBean有关的
<jsp:useBean><jsp:setProperty><jsp:getProperty>
【讲解&实例】见下面的javabean部分
第二类:基本的动作元素,6个 (JSP1.2+)
<jsp:include><jsp:forward><jsp:param><jsp:plugin><jsp:params><jsp:fallback>
<jsp:include>
语法:
<jsp:include page="url" flush="true|false" />
page 要包含的页面
flush 被包含的页面是否从缓冲区读取
【示例】
<jsp:include page="date.jsp" flush="false"/>
include 指令 与 include 动作比较
- | include指令 | include动作 |
---|---|---|
语法格式 | <%@ include file="url" %> |
<jsp:include page="url"> |
发生作用的时间 | 页面转换期间 | 请求期间 |
包含的内容 | 文件的实际内容 | 页面的输出 |
转化成的Servlet | 主页面和包含页面转换成一个Servlet | 主页面和包含页面转换为独立的Servlet |
编译时间 | 较慢,资源必须被解析 | 较快 |
执行时间 | 较快 | 较慢,每次资源必须被解析 |
-
<jsp:include>
动作在请求期间被执行,而include指令在编译期页面间被执行 - 页面内容经常变化时更适合使用
<jsp:include>
动作 - 页面内容不经常变化时更适合使用include指令
-
<jsp:include>
动作包含的是执行结果,而include指令包含的是文件内容
<jsp:forward>
语法:
<jsp:forward page="url" />
等同于转发:
request.getRequestDispatcher("/url").forward(request,response);
【示例】
<jsp:forward page="userinf.jsp" />
等价于
<%
request.getRequestDispatcher("userinf.jsp").forward(request,response);
%>
<jsp:param>
语法:
<jsp:param name="参数名" value="参数值">
常常与<jsp:forward>
一起使用,作为其子标签
【示例】
<jsp:forward page="userinf.jsp" >
<jsp:param name="email" value="email@gmail.com" />
</jsp:forward>
第三类:主要与JSP document有关的,6个 (JSP2+)
<jsp:root><jsp:declaration><jsp:scriptlet><jsp:expression><jsp:text><jsp:output>
第四类:主要用来动态生成XML元素标签的值,3个(JSP2+)
<jsp:attribute><jsp:body><jsp:element>
第五类:主要用在Tage File中,2个(JSP2+)
<jsp:invoke><jsp:dobody>
在jsp页面中使用javabean
使用普通方式创建javabean实例
<%
User u=new User();
u.setName("zdy");
%>
用户名:<%=u.getName()%>
使用jsp动作标签使用javabean
在jsp页面中实例化或者在指定范围内使用javabean。
useBean
在jsp中实例化或者在指定范围内使用javabean
<jsp:useBean id="标识符" class="java类名" scope="作用域" />
setProperty
给已经实例化的JavaBean对象的属性赋值,一共有四种方式:
<jsp:setProperty name="JavaBean 实例名" property="*" />(跟表单关联)
<jsp:setProperty name="JavaBean 实例名" property="JavaBean属性名" />(跟表单关联)
<jsp:setProperty name="JavaBean 实例名" property="JavaBean属性名" value="BeanValue" />(手动设置)
<jsp:setProperty name="JavaBean 实例名" property="JavaBean属性名" param
="request对象中的参数名" />(跟request参数关联)
【示例】com.po下的User类
public class User {
private String username;
private String password;
public User(){
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
【页面1:index.jsp】
<form action="javabean.jsp" name="loginForm" method="post">
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="login"></td>
</tr>
</table>
</form>
【页面2:javabean.jsp 实例1】根据表单自动匹配所有的属性
<jsp:useBean id="myUser" class="com.po.User" scope="page"/>
<jsp:setProperty name="myUser" property="*"/>
用户名:<%=myUser.getUsername()%>
密码:<%=myUser.getPassword()%>
乱码处理,下同
<%
request.setCharacterEncoding("utf-8");
%>
【页面显示】
用户名:张丹阳 密码:123456
【页面2:javabean.jsp 实例2】根据表单匹配部分属性
<jsp:useBean id="myUser" class="com.po.User" scope="page"/>
<jsp:setProperty name="myUser" property="username"/>
用户名:<%=myUser.getUsername()%>
密码:<%=myUser.getPassword()%>
【页面显示】
用户名:张丹阳 密码:null
【页面2:javabean.jsp 实例3】跟表单无关,手动赋值
<jsp:useBean id="myUser" class="com.po.User" scope="page"/>
<jsp:setProperty name="myUser" property="username" value="张Sir"/>
<jsp:setProperty name="myUser" property="password" value="888888"/>
用户名:<%=myUser.getUsername()%>
密码:<%=myUser.getPassword()%>
【页面显示】
用户名:张Sir 密码:888888
【页面2:javabean.jsp 实例3】通过request赋值
<jsp:useBean id="myUser" class="com.po.User" scope="page"/>
<jsp:setProperty name="myUser" property="username" param="username"/>
<jsp:setProperty name="myUser" property="password" param="password"/>
用户名:<%=myUser.getUsername()%>
密码:<%=myUser.getPassword()%>
【页面显示】
用户名:张丹阳 密码:123456
getProperty
获取指定JavaBean对象的属性值
<jsp:getProperty name="JavaBean 实例名" property="属性名" />
【示例】
<jsp:useBean id="myUser" class="com.po.User" scope="page"/>
<jsp:setProperty name="myUser" property="*" />
用户名:<jsp:getProperty name="myUser" property="username"/>
密码:<jsp:getProperty name="myUser" property="password"/>
四个作用域范围
使用useBean的scope属性指定javabean的作用范围。
- page 仅在当前页面有效
- request 可以通过 HttpRequest.getAttribute() 取得javabean对象
- session 可以通过 HttpSession.getAttribute() 取得javabean对象
- application 可以通过 application.getAttribute() 取得javabean对象
【示例】
javabean.jsp
<jsp:useBean id="myUser" class="com.po.User" scope="application"/>
<jsp:setProperty name="myUser" property="*" />
testScope.jsp
<jsp:useBean id="myUser" class="com.po.User" scope="application"/>
用户名:<%=((User)application.getAttribute("myUser")).getUsername()%>
密码:<%=((User)application.getAttribute("myUser")).getPassword()%>
Model1
JSP 状态管理
http 协议无状态性
保存用户状态的两大机制
session、cookie
Cookie
Cookie是Web服务器保存在客户端的一系列文本信息。
【应用】
- 判断注册用户是否已经登录网站
- 购物车
【作用】
- 对特定对象的追踪
- 保存用户网页浏览记录与习惯
- 简化登录
【安全风险】
容易泄漏用户信息
创建与使用Cookie
创建Cookie对象
Cookie newCookie=new Cookie(String key,Object value);
写入Cookie对象
response.addCookie(newCookie);
读取Cookie对象
Cookie[] cookies=request.getCookies();
常用方法
- void setMaxAge(int expiry) 设置cookie有效期,以秒为单位
- void setValue(String value) 在cookie创建后,对cookie进行赋值
- String getName() 获取cookie的名称
- String getValue() 获取cookie的值
- int getMaxAge() 获取cookie的有效时间,以秒为单位
【实例:十天内记住登录状态】
index.jsp
<body>
<%
request.setCharacterEncoding("utf-8");
String username="";
String password="";
Cookie[] cookies=request.getCookies();
if(cookies!=null&&cookies.length>0){
for (Cookie c:cookies){
if (c.getName().equals("username")){
//username=c.getValue();
username= URLDecoder.decode(c.getValue(),"utf-8");
}else if(c.getName().equals("password")){
password=c.getValue();
}
}
}
%>
<form action="login.jsp" name="loginForm" method="post">
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username" value="<%=username%>"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="password" value="<%=password%>"></td>
</tr>
<tr>
<td colspan="2"><input type="checkbox" name="isUseCookie" checked="checked"/>十天内记住我的登录状态</td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="login"></td>
</tr>
</table>
</form>
</body>
login.jsp
<body>
<%
request.setCharacterEncoding("utf-8");
//判断用户是否选择记住登录状态
String[] isUseCookies=request.getParameterValues("isUseCookie");
if (isUseCookies!=null&&isUseCookies.length>0){
//把用户名和密码保存在Cookie对象里面
String username= URLEncoder.encode(request.getParameter("username"),"utf-8");
//String username=request.getParameter("username");
String password=request.getParameter("password");
Cookie usernameCookie=new Cookie("username",username);
Cookie passwordCookie=new Cookie("password",password);
usernameCookie.setMaxAge(864000);//设置最大生存期限为10天
passwordCookie.setMaxAge(864000);
response.addCookie(usernameCookie);
response.addCookie(passwordCookie);
}else{
Cookie[] cookies=request.getCookies();
if(cookies!=null&&cookies.length>0){
for (Cookie c:cookies){
if (c.getName().equals("username")||c.getName().equals("password")){
c.setMaxAge(0);//设置cookie失效
response.addCookie(c);//重新保存
}
}
}
}
%>
<a href="userinf.jsp">跳转查看保存在cookie的信息</a>
</body>
userinf.jsp
<body>
<%
request.setCharacterEncoding("utf-8");
String username="";
String password="";
Cookie[] cookies=request.getCookies();
if(cookies!=null&&cookies.length>0){
for (Cookie c:cookies){
if (c.getName().equals("username")){
//username=c.getValue();
username= URLDecoder.decode(c.getValue(),"utf-8");
}else if(c.getName().equals("password")){
password=c.getValue();
}
}
}
%>
用户名:<%=username%><br />
密码:<%=password%><br />
</body>
session 与 cookie 对比
session | cookie |
---|---|
在服务器端保存用户信息 | 在客户端保存用户信息 |
保存的是Object类型 | 保存的是String类型 |
随会话的结束而将其存储的数据销毁 | 长期保存在客户端 |
保存重要的信息 | 保存不重要的信息 |