Cookie
为了将数据保存到客户端,以备下次客户再次访问服务器时,能够提供更个性化的服务,可以使用 Cookie 技术。
在 JSP 中,Cookie 实际就是一个 Java 的类(Javax.servlet.http.Cookie
)。在 JSP 中插入 Java 脚本,创建该对象实例,设置 Cookie 的名称及值,而后需要使用 response 将其写到客户端。
<%
String userName = request.gerParameter(name);
Cookie userNameCookie = new Cookie("cookie_username",username);
response.addCookie(usernameCookie);
%>
如此,便可以将用户名保存到客户端,下次客户再访问服务端时,便可以读取客户端的 Cookie 值,从而填充用户名。
Cookie 中最重要的方法除了设置其值外,还有一个设置 Cookie 有效期的方法 setMaxAge(int expiry)
,如果参数为负值,那么 Cookie 在浏览器关闭后失效,如果是 0 则表示该条 Cookie 无效,或者表示从客户端删除该条 Cookie 。
在使用 request.getCookies()
获取客户端的 Cookie 数组时,如果返回值为 null 则表示客户端没有写入 Cookie ,而如果 cookies.length==0
则说明客户端不支持 Cookie 的写入。虽然通过 session 可以在不同的 JSP 页面中识别客户,但是 sessionId 同样保存在 Cookie 中,即使该 Cookie 是在内存中,但同样受禁用 Cookie 设置的影响。此时,就需要通过将 sessionId 传递给不同的 JSP 页面来保证用户的识别。不同于普通的 GET 请求,sessionid 不是是通过 ?
同 url 相连接,而是使用 ;
连接。但是,不必自己进行判断拼接,可以直接使用 response 的 encodeURL(url)
或 encodeRedirectURL(url)
方法,然后再使用 sendRedirect(url)
进行客户端跳转。
JavaBean
所谓组件化开发,就是将一些常用的功能,抽象到一个或多个对象中,并提供一个统一的公共接口,以供调用。
一般情况下使用 jsp:userBean 动作元素,进行 bean 的声明赋值和使用,也可以把 JavaBean 当作一个普通的类导入 JSP 中,使用 Java 脚本声明类实例并调用相关方法。
定义一个 JavaBean ,实际就是一个普通的类。
public class Test {
private int count = 0;
public int getCount() {
return count++;
}
public void setCount(int count) {
this.count = count;
}
}
index.jsp 部分片段,如下:
<%@ page import="main.Test" %>
<jsp:useBean id="countBean" scope="page" class="main.Test"></jsp:useBean>
<br>
countBean.count = <%=countBean.getCount() %>
<br>
<%!
Test countBean1 = new Test();
%>
<br>
countBean1.count = <%=countBean1.getCount() %>
<br>
不断刷新 index.jsp 页面,发现,countBean.count 始终为 0 ,而 countBean1.count 则不断增加。
可见,countBean 的有效范围为 JSP 页面的一次请求,countBean1 则作为 JSP 编译而成的类成员属性一直有效。
实际 index.jsp 被编译成了 index_jsp 类,可以在自己的工作空间查看该文件,路径类似:
eclipse-workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/work/Catalina/
localhost/TestDynnamicWeb/org/apache/jsp/index_jsp.java
部分代码如下:
main.Test countBean = null;
countBean = (main.Test) _jspx_page_context.getAttribute("countBean",
javax.servlet.jsp.PageContext.PAGE_SCOPE);
if (countBean == null){
countBean = new main.Test();
_jspx_page_context.setAttribute("countBean", countBean,
javax.servlet.jsp.PageContext.PAGE_SCOPE);
}
而如果修改 bean 的 scope 属性为 session 时,代码会有如下变化:
synchronized (session) {
countBean = (main.Test) _jspx_page_context.getAttribute("countBean",
javax.servlet.jsp.PageContext.SESSION_SCOPE);
if (countBean == null){
countBean = new main.Test();
_jspx_page_context.setAttribute("countBean", countBean,
javax.servlet.jsp.PageContext.SESSION_SCOPE);
}
}
其中 _jspx_page_context
实际就是 pageContext
,那么最终执行 _jspxFactory.releasePageContext(_jspx_page_context);
时,标记为 javax.servlet.jsp.PageContext.PAGE_SCOPE
的变量会被清除。