JSP

来源:互联网 发布:上海大学乐乎硬盘 编辑:程序博客网 时间:2024/04/29 08:36
  1.  状态管理:将客户端(一般是浏览器)与服务器之间的多次交互当作一个整体来看待,即将多次操作所涉及的数据记录下来。
    1)  怎样进行状态管理
     第一种方式,cookie(在客户端管理用户的状态)
     第二种方式,session(在服务器端管理用户的状态)
    2)  cookie
    a.  什么是cookie
    浏览器在访问服务器时,服务器将一些数据以set-cookie消息头的形式发送给浏览器。
    浏览器会将这些数据保存起来。当浏览器再次访问服务器时,会将这些数据以cookie消
    息头的形式发送给服务器。通过这种方式,可以管理用户的状态。
    创建cookie
    Cookie cookie = new Cookie(String name,String value);
    response.addCookie(cookie);
    查询cookie
    //如果没有cookie,则返回null。
    Cookie[] cookies = request.getCookies();
    String name = cookie.getName();
    String value = cookie.getValue();
    cookie保存时的编码问题
    cookie的值只能是ascii字符,如果是中文,需要将中文转换成ascii字符形式。
    可以使用URLEncoder.encode()方法和URLDecoder.decode()方法来进行这种转换。
    cookie的保存时间
    cookie.setMaxAge(int seconds);
     seconds > 0
    浏览器会将cookie以文件的方式保存在硬盘上。在超过指定的时间以后,会删除
    该文件。
     seconds < 0
    默认值,浏览器会将cookie保存在内存里面。只有当浏览器关闭之后,才会删除
     seconds = 0
    立即删除该Cookie
    删除cookie
    比如要删除一个name为"username"的cookie。
    Cookie c = new Cookie("username","");
    c.setMaxAge(0);
    response.addCookie(c);
    cookie的路径问题
    浏览器在向服务器上的某个地址发送请求时,
    会先比较cookie的路径不向访问的路径(地址)是否匹配,只有匹配的cookie,才会发送
    cookie的路径可以通过cookie.setPath(String path)方法来设置。
    如果没有设置, 则有一个缺省的路径,缺省的路径是生成该cookie的组件的路径。
    比如: /appname/addCookie 保存了一个cookie,
    则该cookie的路径就是/appname/addCookie。  
    规则:
    cookie的路径必须是要访问的路径的上层目录或者是不要访问的路径相等,浏览器
    才会将cookie发送给服务器。  
    一般可以设置setPath("/appname"),表示访问该应用下的所有地址,均会发送cookie。
h.  cookie的限制
 cookie可以禁止
 cookie的大小有限制(4k 左右)
 cookie的数量也有限制(浏览器大约能保存300个)
 cookie的值只能是字符串,要考虑编码问题。
 cookie不安全
3)  session  
a.  什么是session?
   浏览器访问服务器时,服务器会创建一个session对象(该对象有一个唯一的id, 一般称
   为sessionId)。服务器在缺省情况下,会将sessionId 以cookie机制发送给浏览器。当
   浏览器再次访问服务器时,会将sessionId 发送给服务器。服务器依据sessionId 就可以
   找到对应的session对象。通过这种方式,就可以管理用户的状态。
b.  如何获得session对象
   方式一:
   HttpSession session = request.getSession(boolean flag);
    当flag = true:
    服务器会先查看请求中是否包含sessionId,
    如果没有,则创建一个session对象。
    如果有,则依据sessionId 去查找对应的session对象,如果找到,则返回。
    如果找不到,则创建一个新的session对象。
    当flag = false:
    服务器会先查看请求中是否包含sessionId,
    如果没有,返回null。
    如果有,则依据sessionId 去查找对应的session对象,如果找到,则返回。
    如果找不到,返回null。
   方式二
    HttpSession session = request.getSession();
    与request.getSession(true)等价。
c.  HttpSession接口提供的一些方法
//获得sessionId。
   String session.getId();
   //绑订数据
   session.setAttribute(String name,Object obj);
   /* obj最好实现Serializable接口
* (服务器在对session进行持久化操作时,
* 比如钝化、激活,会使用序列化协议)。 */
   Object session.getAttribute(String name); 
//如果name对应的值不存在,返回null。
session.removeAttribute(String name);
session超时
服务器会将超过指定时间的session对象删除(在指定的时间内,该session对象没有
使用)。
方式一:
session.setMaxInactiveInterval(int seconds);
方式二:
服务器有一个缺省的超时限制,可以通过相应的配置文件来重新设置。
比如可以修改tomcat的web.xml(tomcat_home/conf下面)。
<session-config>
  <session-timeout>30</session-timeout>
  </session-config>
另外,也可以只修改某个应用的web.xml。
e. 删除session
session.invalidate(); 
2.保存和查询Cookie流程 
a.  浏览器向服务器发送addCookie请求
服务器中的AddCookieServlet创建了两个Cookie:cookie和cookie2
b.  服务器端执行语句response.addCookie(cookie);生成消息头“set-cookie”,
并将两个Cookie以键值对的方式(“name=aaa”、“passwd=123”)存放在消息头中发
送给浏览器
c. 浏览器将Cookie信息保存到本地内存中
d.  浏览器继续向服务器发送请求(带着消息头cookie)
服务器端的FindCookieServlet找到Cookie信息,并显示给浏览器  
4.删除 cookie 
删除name为"username"的cookie步骤
第1步:创建一个同名并且内容为空的cookie
   Cookie c = new Cookie("username","");
第2步:调用方法,参数为0
c.setMaxAge(0);
第3步:调用方法
response.addCookie(c);
 
5.cookie的路径问题 
浏览器在向服务器上的某个地址发送请求时,
会先比较cookie的路径与向访问的路径(地址)是否匹配,只有匹配的cookie,才会发送。
cookie的路径可以通过cookie.setPath(String path)方法来设置。
如果没有设置, 则有一个缺省的路径,缺省的路径是生成该cookie的组件的路径。
比如: /appname/addCookie 保存了一个cookie,
则该cookie的路径就是/appname/addCookie。
6.session验证 
Session验证可以防止非登录用户通过地址栏输入地址直接访问受保护的页面。
step1  
在登录成功之后,在session上绑订一些数据。绑定的数据是自定义的,一般情况下我们绑定
用户信息,比如: session.setAttribute("user",user);
step2 
在访问需要保护的页面或者资源时,执行Object obj = session.getAttribute("user");
  如果obj为null,说明没有登录,一般重定向到登录页面。 Obj不为null时,用户可以访问页面。
7.session验证成功
1)  Browser 从地址栏访问main.jsp
2)  服务器创建一个Session对象
3)  main.jsp 执行session.getAttribute("user");代码进行session验证,找不到user
4)  返回302和重定向地址
5)  重定向到login.jsp
6)  login.jsp 使用之前的session
因为任意的jsp都会执行request.getSession()语句
7)  login.jsp 生成登录页面并发送给浏览器
8)  用户输入“zs”"test"调用了login.do 向LoginServlet发请求
9)  LoginServlet使用Session对象,向其中绑定数据user
10)  登录成功,重定向到main.jsp
11)  当用户再次在地址栏直接访问main.jsp 时,因为Session对象中已经有了验证数据user,所
以直接可以访问 
8.Session验证正确
1)  用户通过login.do 访问LoginServlet
2)  step1 LoginServelt将user 对象绑定到Session对象上  
3)  服务器发送302状态码(包含sessionId)
4)  浏览器将sessionId 保存到内存
5)  浏览器重定向到main.jsp(包含sessionId)
6)  step2 main.jsp 从之前的Session对象中取到user 对象(验证成功) 
7)  main.jsp 将生成的页面返回给浏览器 
9.验证码流程图 
服务器部署某个应用,该应用添加了session验证,必须登录才能访问。
1)  浏览器向login.jsp 发送请求,请求获得登录页面
2)  jsp会创建一个session对象
3)  Jsp返回给浏览器一个登陆页面(html、js、css),
该页面包含一行代码<img src="checkCode">(checkCode是一个请求地址)
4)  浏览器立即给服务器发请求checkCode,访问到CheckCodeServlet
5)  CheckCodeServlet会生成一个随机数(验证数字),并绑定到Session对象上;
6)  同时,CheckCodeServlet发送给浏览器一张图片(验证数字+图片)
此时,用户在浏览器上看到完全的登录页面:表单
7)  用户填写完表单后提交,访问LoginServlet
8)  LoginServlet从Session对象中取到验证数字number1
9)  LoginServlet将number1与用户提交请求中的验证数字number2比较,如果匹配,则继续
正常的登录验证,不匹配则返回给浏览器信息“验证码不匹配”
10.过滤器  
1)  什么是过滤器
  servlet规范当中定义的一种特殊的类,用于对servlet容器的调用过程迚行拦截。 
  •   浏览器发送请求给服务器 
  •   服务器的Servlet引擎创建Request对象&&Response对象 
  •   Servlet引擎先调用过滤器的doFilter 方法,该方法有两个参数request和response,
(在过滤器中可以访问到Request对象&&Response对象)
  •   过滤器对拦截的内容进行处理 
  •   之后调用SomeServlet的service方法 
  •   service方法执行 
  •   service方法执行结束后,将结果返回到过滤器 
  •   过滤器将service方法返回的结果再次进行过滤 
  •   最后,Servlet引擎将结果返回给浏览器 
2)  怎样写一个过滤器
   step1
写一个java 类,实现一个Filter 接口。
   step2
   在doFilter 方法里,实现过滤的逻辑。
   step3
   配置(web.xml)。
3)  配置初始化参数
  step1
  web.xml中,使用<init-para>元素来配置初始化参数
  step2
  在Filter 类中,使用FilterConfig.getInitParameter(String paraName);获得初始化参数。
4)  过滤器的优先级
  当有多个过滤器都满足过滤的条件时,依据<filter-mapping>的先后顺序依次执行。
5)  过滤器的优点
a.  可以将多个web组件相同的逻辑写在一个过滤器当中,方便代码的维护
b.  可实现代码的“可插拔性"。
给一个软件增加戒者减少某个功能不会影响已经存在的功能。 
11.监听器  
1)  什么是监听器?
servlet规范当中定义的一种特殊的类,作用是监听容器当中产生的一些事件并进行相应的处
理。
  容器产生的事件指的是两大类事件:
  第一大类
生命周期相关的事件,指的是当容器创建或者销毁request,session,ServletContext对象时产
生的事件。
  第二大类
绑订事件,指的是当调用request,session,ServletContext对象的
setAttribute,removeAttribute 时产生的事件。
2)  如何写监听器
  step1
   写一个java 类,实现特定的监听器接口类(依据要监听的事件类型)。
  step2
   在接口声明的方法中,实现监听的逻辑。
  step3
配置(web.xml)。
3)  ServletContext接口
web服务器在启动时,会为每一个已经部署的应用创建唯一的一个ServletContext实例。
该实例会一直存在,除非服务器关闭或者应用被删除。
注意:每个应用对应唯一的一个ServletContext实例

a.  如何获得ServletContext实例。
  GenericServlet提供了getServletContext()方法。
  HttpSession提供了getServletContext()方法。
  ServletConfig 提供了getServletContext()方法。
b.  常用方法
 绑订数据
    setAttribute(String name,Object obj);
    getAttribute(String name);
    removeAttribute(String name);
 配置全局的初始化参数 
step1 
在web.xml中,使用<context-param>配置的参数,可以被所有的servlet共享。
step2 
使用String ServletContext.getInitParameter(String paraName);
依据逻辑路径获得实际部署时的物理路径。
String ServletContext.getRealPath(String url);  
4)  上传文件(扩展)
step1
在form中,设置method="post",设置enctype="multipart/form-data"。enctype属性用
于设置表单的编码方式,对于文件上传,必须设置成"multipart/form-data"。
step2
在servlet类当中,不能够使用request.getParameter 方法来获得参数值。要使用
InputStream request.getInputStream();分析InputStream来获得参数值。直接分析
InputStream比较复杂,一般使用一些封装好的工具(比如apache提供的
commons-fileupload.jar)来获得参数值。 
12.核心的类不接口
1)  Servlet接口
2)  GenericServlet抽象类
3)  HttpServlet抽象类
4)  ServletRequest,ServletResponse 接口
5)  ServletConfig 接口
a.  ServletContext getServletContext();
b.  String getInitParameter(String paraName);
6)  HttpServletRequest接口
a.  String getParameter(String name);
b.  String[] getParameterValues(String name);
c. setCharacterEncoding(String code);
d.  RequestDispatcher getRequestDispatcher(String url);
e.  setAttribute(String name,Object obj);
f. Object getAttribute(String name);
g.  removeAttribute(String name);
h.  String getContextPath();
i. String getRequestURI();
j. HttpSession getSession()/getSession(boolean flag);
k. Cookie[] getCookies();
7)  HttpServletResponse 接口
a.  setContentType(String str);
b.  PrintWriter getWriter();
c. sendRedirect(String url);
d.  encodeURL(String url);
e.  encodeRedirectURL(String url);
f. addCookie(Cookie cookie);
8)  ServletContext接口
a.  String getRealPath(String str);
b.  setAttribute(String name,Object obj);
c. Object getAttribute(String name);
d.  removeAttribute(String name);
e.  String getInitParameter(String name); 
13.session的常用方法
a.  String getId();
b.  String getRealPath(String str);
c. setAttribute(String name,Object obj);
d.  Object getAttribute(String name);
e.  setMaxInactiveInterval(int seconds);
f. invalidate();
g.  ServletContext getServletContext(); 
14. servlet 的线程安全问题 
1)  servlet线程安全问题产生的原因
  在默认情况下,容器只会为每一个servlet类创建唯一的一个实例,当有多个请求到达容器,
就有可能有多个线程同时访问同一个实例。
2)  解决方式
a.  加锁(可以对整个service方法加锁,或者对代码块加锁,建议使用代码块加锁)。
b.  让servlet实现SingleThreadModle接口(不建议使用)
SingleThreadModel接口是一个标识接口(没有定义任何的方法)。容器会为实现该接口
的servlet创建多个实例,即一个线程分配一个。这种方式创建了过多的servlet实例,
系统开销太多,不建议使用。
c.  servlet的属性尽量设置成可读的,不要去修改。 
15. jsp的组成
1)  html(html,css,javascript)
2)  java代码
 第一种形式
   java代码片断  <%  %>
 第二种形式
   jsp表达式 <%=  %>  
 第三种形式
   jsp声明 <%!  %>
3)  指令
  page指令
  import属性
  pageEncoding 属性
  contentType属性
  session属性     
true(缺省)/false。如果值为false,则对应的servlet代码
当中不会生成声明和创建session的代码。也就是说,
不能够使用session隐含对象了。
  isELIgnored 属性
true(缺省)/false,是否忽略el表达式,如果是true,忽略。
  isErrorPage属性
true/false(缺省),当前jsp是否是一个错误处理页面,如
果是true,是错误处理页面。
  errorPage属性
用于指定错误处理页面。
  include指令
  file属性
  taglib指令
用于导入标签
  uri属性
标签文件的命名空间
  prefix属性
命名空间的前缀
隐含对象(9个)
 out
 request
 response
 session
 application
 exception
当一个页面设置了<%@page isErrorPage="true"%>,则可以在该页
面当中,使用该隐含对象读取错误信息。
 config
就是ServletConfig,可以读取jsp的配置参数。
 pageContext
是PageContext类的实例,服务器会为每一个jsp实例(指的是jsp对
应的那个servlet对象创建唯一的一个PageContext 实例。
   作用主要有两个: 
绑订数据:
setAttribute,getAttribute,removeAttribute
获得其它几个隐含对象:
即在获得了pageContext实例之后,可以通过该实例,  
获得其它8个隐含对象。
 page   
表示jsp实例本身。
活动元素
在jsp实例已经运行了,告诉jsp引擎做一些处理。
 <jsp:forward  page=""/>
转发,page属性指定转发的地址。
 <jsp:include page=""/>
一个jsp在运行过程当中,调用另外一个jsp。
 <jsp:param name="" value=""/>
设置参数 name指定参数名 value指定参数值
 <jsp:useBean id="" scope="" class=""/>
在指定的范围绑订一个对象。
范围指的是四个对象pageContext,request,session,servletContext。
也就是说scope的值可以是"page","request","session","application"。
 <jsp:getProperty/>
 <jsp:setProperty name="" property="" value=""/>
 <jsp:setProperty name="" property="" param=""/>
  依据请求参数给属性赋值。
 <jsp:setProperty name="" property="*"/>
   使用"自省机制"给属性赋值。
注释
<!-- <%=new Date()%> -->
  注释中的代码会执行,但不会在页面上输出。
<%--xxxx--%>
注释中的代码不会执行,也不会在页面上输出。
jsp源文件如何转换成.java文件
 html       ---->   service(),使用out.write()输出。
 <%  %>  ---->    service(),照搬。
 <%= %>  ---->    service(),使用out.print()输出。
 指令    ---->    会影响源代码的生成,比如导包。
 <%! %>   ---->    jsp声明中定义的变量会变为对应的servlet类的属性,
      定义的方法会变成对应的servlet类的一个方法。
16.jsp隐藏对象访问范围从小到大 
 pageContext   只有对应的JSP实例自己可以访问,生命周期从对应的JSP对象创建到
   JSP对象消亡。
 request    一次请求能访问,生命周期在一起请求和响应期间。
 session    一次会话期间能访问,多次请求和响应期间都存在。
 ServletContext 整个应用内部所有组件都能访问,除非服务器关闭,否则一直存在。 
17.el表达式的基本语法 
${el 表达式}
1)  第一种:  访问bean的属性
a.  ${user.name}:   
jsp引擎会依次从pageContext、request、session、application查找绑订名为"user"
的对象,如果找到了,就不再向下查找,否则,继续向下查找。
找到后,调用该对象的getName(),并输出其值;找不到,则输出""(空)。
b.  或者也可以使用${user["name"]},效果相同 "name" 表示字符串
c.  或者是${user[propname]},注意propname没有引号,表示变量
d.  此外,[ ]里面还可以是0,1..这样的下标,作用是输出数组里的元素值。
e.  可以使用pageScope,requestScope,sessionScope,applicationScope 四个关键字指
定查找的范围。
f. ${requestScope.user.name}只到request中去找,不再依次到4个范围查找了
2)  第二种:  获得请求参数值
a.  ${param.username}
等价于 request.getParameter("username");
b.  ${paramValues.interest}
等价于request.getParameterValues("interest");
3)  第三种:  计算一个表达式,将结果作为标签的属性值或者直接输出
a.  算术运算 
"+" , "-" , "*" , "/" , "%" , 但是要注意,"+"号不能连接字符串。
关系运算
"==" , "!=" , ">" , "<" ,">=" , "<=" 
可以使用对应的"eq","nq","lt","gt","le","ge"代替。
逻辑运算
"&&","||","!",可以使用"and","or","not"代替。
empty运算
判断一个字符串是否为空,集合内容是否为空,以及绑订的对象是否存在。 
18.核心标签的使用 
1)  使用步骤
需要将jstl标准标签库相关的jar文件copy到WEB-INF\lib。
  D:\czh\MyEclipse 5.5.1 GA\eclipse\plugins\com.genuitec.eclipse.j2eedt.core_5.5.1\
data\libraryset\JSTL1.1\lib\
  jstl.jar standard.jar
2)  在jsp文件当中,使用taglib指令导入标签。
3)  使用标签
a.  <c:if test="" var="" scope="">
test属性:当值为true,执行标签体的内容,为false,则不执行。
var 属性:指定一个绑订名。
scope属性:指定一个绑订范围。
var 属性和scope属性用于将test的结果绑订到指定的对象(pageContext,request,session,application)上。
b.  <c:choose>
   用于分支,当某个条件满足,执行某一个分支。每一个分支条件用when标签来表示。
<c:when test="">
可出现多次,只用于<c:choose>
 test属性: 当值为true,执行标签体的内容
<c:otherwise>
只出现1次,只用于<c:choose>
当其它分支都不满足条件,则执行该标签体的内容。
c.  <c:forEach var="" items="" varStatus="">
用于遍历集合items 属性:指定要遍历的集合。
var 属性:指定一个绑订名,jsp引擎会从集合当中取一个对象,绑订到pageContext对象上。
varStatus 属性:指定一个绑订名,对应的绑订值是一个java对象,封装了遍历时的一些信息,包括当前遍历的对象的下标(index)以及是第几次(count)遍历。
d.  <c:url>
当用户禁止cookie以后,会自动在地址后面添加sessionId。
当使用绝对路径时,会自动在地址前添加应用名。
 value属性:指定地址。在表单提交、链接当中,可以使用该标签。
e.  <c:set var="" scope="" value="">
   绑订一个对象到指定的范围。
 value属性:绑订值。
f. <c:remove var="" scope="">
   解除绑订
g.  <c:catch var="">
   处理异常,会将异常信息封装成一个对象,绑订到pageContext对象上。
h.  <c:import url="">
   url指定一个jsp文件的地址,jsp会在运行时调用这个jsp。
i. <c:redirect url="">
   重定向到另外一个地址。url属性指定重定向的地址。
j. <c:out value="" default="" escapeXml="">
   用于输出el表达式的值。
 value属性:指定输出的值 
   default属性:指定缺省值。
   escapeXml属性:设置成true,会将value中的特殊字符替换成相应的实体。缺省值就是true。 







0 0