JSP(Java Server Pages)是JavaWeb服务器端的动态资源。它与html页面的作用是相同的,显示数据和获取数据。
JSP = html + Java脚本(代码片段) + JSP动态标签
3.1 JSP脚本
JSP脚本就是java代码片段,分为三种:
(1)<%...%>:Java语句;
java代码片段(常用),用于定义0~N条Java语句!方法内能写什么,它就可以放什么!
(2)<%=…%>:Java表达式;
java表达式,用于输出一条表达式(或变量)的结果。response.getWriter().print( ... );这里能放什么,它就可以放什么!
(3)<%!...%>:Java定义类成员;
声明,用来创建类的成员变量和成员方法(基本不用)
3.2 多个<%...%>可以通用
在一个JSP中多个<%...%>是相通的。例如:
out.jsp
<%
String s = "hello";
%>
<%
out.print(s);
%>
循环打印表格:
表格
序号
用户名
密码
<%
for(int i = 0; i < 10; i++) {
%>
<%=i+1 %>
user<%=i %>
<%=100 + 1 %>
<%
}
%>
JSP是一种特殊的Servlet,当JSP页面首次被访问时,容器(Tomcat)会先把JSP编译成Servlet,然后再去执行Servlet。所以JSP其实就是一个Servlet!
格式:<%-- ... --%>
JSP是需要先编译成.java,再编译成.class的。其中<%-- ... --%>中的内容在JSP编译成.java时会被忽略的,即JSP注释。
也可以在JSP页面中使用html注释:,但这个注释在JSP编译成的.java中是存在的,它不会被忽略,而且会被发送到客户端浏览器。但是在浏览器显示服务器发送过来的html时,因为是html的注释,所以浏览器是不会显示它的。
* JSP:
作为请求发起页面,例如显示表单、超链接。
作为请求结束页面,例如显示数据。
* Servlet:
作为请求中处理数据的环节。
小案例演示:
客户端请求该jsp页面,输出数字求和
该jsp将请求页面发送到AServlet中,AServlet进行数据的处理,然后转发到showSum.jsp中
public class AServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获取请求的参数
String num1 = request.getParameter("num1");
String num2 = request.getParameter("num2");
//把字符串转成Integer类型
Integer num11 = Integer.valueOf(num1);
Integer num22 = Integer.valueOf(num2);
int sum = num11 + num22;
//把相加的结果保存到request域对象中
request.setAttribute("sum", sum);
//转发到showSum.jsp中
request.getRequestDispatcher("/sum/showSum.jsp").forward(request,
response);
}
}
showSum页面获取到request传递过来的sum值,并输出在客户端中
<%Integer sum=(Integer)request.getAttribute("sum"); %>
和为<%=sum %>
Cookie就是一个键和一个值构成的,随着服务器端的响应发送给客户端浏览器。然后客户端浏览器会把Cookie保存起来,当下一次再访问服务器时把Cookie再发送给服务器。
Cookie是由服务器创建,然后通过响应发送给客户端的一个键值对。客户端会保存Cookie,并会标注出Cookie的来源(哪个服务器的Cookie)。当客户端向服务器发出请求时会把所有这个服务器Cookie包含在请求中发送给服务器,这样服务器就可以识别客户端了!
Cookie大小上限为4KB;
一个服务器最多在客户端浏览器上保存20个Cookie
一个浏览器最多保存300个Cookie;
注意,不同浏览器之间是不共享Cookie的。也就是说在你使用IE访问服务器时,服务器会把Cookie发给IE,然后由IE保存起来,当你在使用FireFox访问服务器时,不可能把IE保存的Cookie发送给服务器。
Cookie是通过HTTP请求和响应头在客户端和服务器端传递的:
Cookie:请求头,客户端发送给服务器端;
格式:Cookie: a=A; b=B; c=C。即多个Cookie用分号离开;
Set-Cookie:响应头,服务器端发送给客户端;
一个Cookie对象一个Set-Cookie:
Set-Cookie: a=A
Set-Cookie: b=B可以通过setMaxAge(int)来设置Cookie的有效时间。
cookie.setMaxAge(-1):cookie的maxAge属性的默认值就是-1,表示只在浏览器内存中存活。一旦关闭浏览器窗口,那么cookie就会消失。
cookie.setMaxAge(60*60):表示cookie对象可存活1小时。当生命大于0时,浏览器会把Cookie保存到硬盘上,就算关闭浏览器,就算重启客户端电脑,cookie也会存活1小时;
cookie.setMaxAge(0):cookie生命等于0是一个特殊的值,它表示cookie被作废!也就是说,如果原来浏览器已经保存了这个Cookie,那么可以通过Cookie的setMaxAge(0)来删除这个Cookie。无论是在浏览器内存中,还是在客户端硬盘上都会删除这个Cookie。
现在有WEB应用A,向客户端发送了10个Cookie,这就说明客户端无论访问应用A的哪个Servlet都会把这10个Cookie包含在请求中!但是也许只有AServlet需要读取请求中的Cookie,而其他Servlet根本就不会获取请求中的Cookie。这说明客户端浏览器有时发送这些Cookie是多余的!
可以通过设置Cookie的path来指定浏览器,在访问什么样的路径时,包含什么样的Cookie。
(1)Cookie路径与请求路径的关系
当浏览器访问服务器某个路径时,需要归还哪些Cookie给服务器呢?这由Cookie的path决定。
浏览器访问服务器的路径,如果包含某个Cookie的路径,那么就会归还这个Cookie。
例如:
aCookie.path=/day11_1/; bCookie.path=/day11_1/jsps/; cCookie.path=/day11_1/jsps/cookie/;
<> 访问:/day11_1/index.jsp时,归还:aCookie
<> 访问:/day11_1/jsps/a.jsp时,归还:aCookie、bCookie
<> 访问:/day11_1/jsps/cookie/b.jsp时,归还:aCookie、bCookie、cCookie
> Cookie的path默认值:当前访问路径的父路径。例如在访问/day11_1/jsps/a.jsp时,响应的cookie,那么这个cookie的默认path为/day11_1/jsps/
(2)设置Cookie路径
设置Cookie的路径需要使用setPath()方法,例如:
cookie.setPath(“/cookietest/servlet”);
如果没有设置Cookie的路径,那么Cookie路径的默认值当前访问资源所在路径,例如:
访问http://localhost:8080/cookietest/AServlet时添加的Cookie默认路径为/cookietest;
访问http://localhost:8080/cookietest/servlet/BServlet时添加的Cookie默认路径为/cookietest/servlet;
访问http://localhost:8080/cookietest/jsp/BServlet时添加的Cookie默认路径为/cookietest/jsp;
Cookie的name和value都不能使用中文,如果希望在Cookie中使用中文,那么需要先对中文进行URL编码,然后把编码后的字符串放到Cookie中。
向客户端响应中添加Cookie
public class BServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) {
String name;
try {
name = URLEncoder.encode("姓名", "UTF-8");
String value = URLEncoder.encode("张三", "UTF-8");
Cookie c = new Cookie(name, value);
c.setMaxAge(3600);
response.addCookie(c);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
从客户端请求中获取Cookie
public class CServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
Cookie[] cs = request.getCookies();
if (cs != null) {
for (Cookie cookie : cs) {
String name = URLDecoder.decode(cookie.getName(), "UTF-8");
String value = URLDecoder.decode(cookie.getValue(), "UTF-8");
String s = name + ":" + value + "
";
response.getWriter().print(s);
}
}
}
}
* HttpSession是由JavaWeb提供的,用来会话跟踪的类。session是服务器端对象,保存在服务器端!!!
* HttpSession是Servlet三大域对象之一(request、session、application(ServletContext))。
* HttpSession底层依赖Cookie,或是URL重写!
* 会话范围:会话范围是某个用户从首次访问服务器开始,到该用户关闭浏览器结束!
会话:一个用户对服务器的多次连贯性请求!所谓连贯性请求,就是该用户多次请求中间没有关闭浏览器!
* 服务器会为每个客户端创建一个session对象,session就好比客户在服务器端的账户,它们被服务器保存到一个Map中,这个Map被称之为session缓存!
Servlet中得到session对象:HttpSession session = request.getSession();
Jsp中得到session对象:session是jsp内置对象之下,不用创建就可以直接使用!
* session域相关方法:
void setAttribute(String name, Object value);
Object getAttribute(String name);
void removeAttribute(String name);
需要的页面:
login.jsp:登录页面,提供登录表单;
succ1.jsp:主页,显示当前用户名称,如果没有登录,退回到login页面;
LoginServlet:在login.jsp页面提交表单时,请求本Servlet。在本Servlet中获取用户名、密码进行校验,如果用户名、密码错误,显示“用户名或密码错误”,如果正确保存用户名session中,然后重定向到succ1.jsp;
login.jsp
<%
String uname="";
Cookie[] cookie=request.getCookies();
if(cookie!=null){
for(Cookie coo:cookie){
if("username".equals(coo.getName())){
uname=coo.getValue();
}
}
}
%>
登陆界面
<% String message="";
String judge=(String)request.getAttribute("judge");
if(judge!=null){
message=judge;
}
%>
<%=message%>
loginServlet
public class loginServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
// 获取表单提交的参数
String username = request.getParameter("username");
String password = request.getParameter("password");
// 对帐号进行校验,成功的话
if (!username.equals("hello")) {
// 将帐号作为Cookie保存在浏览器中
Cookie cookie = new Cookie("username", username);
cookie.setMaxAge(60 * 60);
response.addCookie(cookie);
// 将获取的参数存在session域中,方便succ1获取
HttpSession session = request.getSession();
session.setAttribute("username", username);
session.setAttribute("password", password);
// 重定向到登陆成功页面
response.sendRedirect("/4.29/Login/succ1.jsp");
// 失败的话
} else {
// 保存错误信息到request域中
request.setAttribute("judge", "用户名或密码错误。请重新输入。");
// 转发到login.jsp
request.getRequestDispatcher("/Login/login.jsp").forward(request,
response);
}
}
}
succ1.jsp
<%
String username = (String) session.getAttribute("username");//获取用户名
/*
如果用户名为null,向request域中保存错误信息,转发到login.jsp
*/
if (username == null) {
request.setAttribute("judge", "您还没有登陆");
request.getRequestDispatcher("/Login/login.jsp").forward(
request, response);
return;
}
%>
欢迎回来,<%=username%>
* request.getSession()方法:
> 获取Cookie中的JSESSIONID:
<> 如果sessionId不存在,创建session,把session保存起来,把新创建的sessionId保存到Cookie中
<> 如果sessionId存在,通过sessionId查找session对象,如果没有查找到,创建session,把session保存起来,把新创建的sessionId保存到Cookie中
<> 如果sessionId存在,通过sessionId查找到了session对象,那么就不会再创建session对象了。
<> 返回session
> 如果创建了新的session,浏览器会得到一个包含了sessionId的Cookie,这个Cookie的生命为-1,即只在浏览器内存中存在,如果不关闭浏览器,那么Cookie就一直存在。
> 下次请求时,再次执行request.getSession()方法时,因为可以通过Cookie中的sessionId找到session对象,所以与上一次请求使用的是同一session对象。* 服务器不会马上给你创建session,在第一次获取session时,才会创建!request.getSession();
* request.getSession(false)、request.getSession(true)、request.getSession(),后两个方法效果相同
> 第一个方法:如果session缓存中(如果cookie不存在),不存在session,那么返回null,而不会创建session对象。
session保存在服务器,而sessionId通过Cookie发送给客户端,但这个Cookie的生命不-1,即只在浏览器内存中存在,也就是说如果用户关闭了浏览器,那么这个Cookie就丢失了。
当用户再次打开浏览器访问服务器时,就不会有sessionId发送给服务器,那么服务器会认为你没有session,所以服务器会创建一个session,并在响应中把sessionId中到Cookie中发送给客户端。
你可能会说,那原来的session对象会怎样?当一个session长时间没人使用的话,服务器会把session删除了!这个时长在Tomcat中配置是30分钟,可以在${CATALANA}/conf/web.xml找到这个配置,当然你也可以在自己的web.xml中覆盖这个配置!从客户端请求中获取Cookie。
10
如果你打开网站的一个页面开始长时间不动,超出了10分钟后,再去点击链接或提交表单时你会发现,你的session已经丢失了!
String getId():获取sessionId;
int getMaxInactiveInterval():获取session可以的最大不活动时间(秒),默认为30分钟。当session在30分钟内没有使用,那么Tomcat会在session池中移除这个session;
void setMaxInactiveInterval(int interval):设置session允许的最大不活动时间(秒),如果设置为1秒,那么只要session在1秒内不被使用,那么session就会被移除;
long getCreationTime():返回session的创建时间,返回值为当前时间的毫秒值;
long getLastAccessedTime():返回session的最后活动时间,返回值为当前时间的毫秒值;
void invalidate():让session失效!调用这个方法会被session失效,当session失效后,客户端再次请求,服务器会给客户端创建一个新的session,并在响应中给客户端新session的sessionId;
boolean isNew():查看session是否为新。当客户端第一次请求时,服务器为客户端创建session,但这时服务器还没有响应客户端,也就是还没有把sessionId响应给客户端时,这时session的状态为新。
我们知道session依赖Cookie,那么session为什么依赖Cookie呢?因为服务器需要在每次请求中获取sessionId,然后找到客户端的session对象。那么如果客户端浏览器关闭了Cookie呢?那么session是不是就会不存在了呢?
其实还有一种方法让服务器收到的每个请求中都带有sessioinId,那就是URL重写!在每个页面中的每个链接和表单中都添加名为jSessionId的参数,值为当前sessionid。当用户点击链接或提交表单时也服务器可以通过获取jSessionId这个参数来得到客户端的sessionId,找到sessoin对象。
URL重写
也可以使用response.encodeURL()对每个请求的URL处理,这个方法会自动追加jsessionid参数,与上面我们手动添加是一样的效果。
主页
使用response.encodeURL()更加“智能”,它会判断客户端浏览器是否禁用了Cookie,如果禁用了,那么这个方法在URL后面追加jsessionid,否则不会追加。