WEB-11-JSP-cookie session 作用域 标签技术

一、JSP01
1.概述
jsp其实是java的动态页面技术
HTML可以用来组织页面但是HTML是一种静态web资源技术 无法嵌入动态数据。
Servlet是动态web资源技术 但是本质上是一段java代码 不方便在其中组织页面结构。
于是jsp技术被提出来 写起来就像在写一个html,但是内部可以嵌入java代码,本质上是一种动态web资源 但是可以直接写html标签 非常便于组织页面结构。
jsp解决了 动态页面开发的问题。
真正的开发中 往往使用Servlet来处理业务逻辑 将处理好的结构 带到jsp页面 由jsp页面负责展示。


2.原理
jsp会在第一次被访问的时候 被翻译成一个Servlet 之后对这个jsp的访问 本质上都是这个Servlet在执行。
所以眼睛里看的是个jsp 心里要明白其实是个Servlet在执行。


3.JSP基本组成结构
(1)模版元素
在jsp页面中直接编写的HTML内容 组成了jsp的结构 这些html内容称之为jsp的模版元素
在被翻译成Servlet的过程中 被 直接 out.write 原样输出到浏览器页面


(2)脚本表达式 <%= java表达式 %>
在jsp页面中可以通过脚本表达式 来将一个java表达式计算的结果输出到中
在被翻译成Servlet的过程中 直接被out.print()输出 表达式计算完的结果


(3)脚本片段 <% 若干java语句 %>
在jsp页面中可以通过脚本片段直接写入一段java代码
在被翻译成Servlet的过程中 脚本片段原样 被复制粘贴到对应位置 直接执行


注意:同一个页面中 多个脚本片段 后面的可以看到前面定义的变量
注意:一个脚本片段可以不完整 但是要保证整个页面 翻译过来的Servlet中 语法要完整


(4)JSP声明 <%! %>
可以通过JSP声明为翻译过来的Servlet增加类的成员。
在jsp声明中声明的内容 会在被翻译成Servlet的过程中 被放置到和Service方法同级的位置 成为类的成员。




(5)JSP注释 <%-- --%>
可以通过JSP注释将jsp中的部分内容注释掉 
被注释的内容不会被翻译到Servlet中


注意:在jsp页面中可能出现如下三种注释
jsp注释  <%-- --%>  不会被翻译到Servlet
java注释 <% //String str = "abc"; %> 被翻译到Servlet中 但是java代码被注释 不会被执行
html注释 <!-- --> 被翻译到Servlet中当作模版元素直接输出到浏览器


Servlet擅长写java代码处理业务逻辑但是不擅长输出页面 Jsp擅长输出页面但是不擅长处理业务逻辑
所以在真正的开发中 往往 将请求提交到Servlet中 进行业务处理 通过请求转发利用request域将结果发给 JSP ,JSP负责展示。




一、会话技术
1.会话概述
一个浏览器 为了实现某一个功能  对服务器产生了多次请求响应。从第一个请求开始访问服务器,会话开始,到最后一个页面访问结束 关闭所有页面,这个过程中的所有的请求响应加在一起称之为 浏览器和服务器之间产生了一次会话。


会话技术中 最重要的问题就是会话产生的数据 如何保存。


request域 - 不行 - 太小了 - 每次请求响应都是一个新的request 后续的请求中无法看到之前请求request里存放的数据
servletContext域 - 不行 - 太大了 - 所有的会话 看到的都是同一个ServletContext域 所有会话的数据混杂在一起 必然混乱


cookie - 将会话产生的数据存放在客户端


session - 将会话产生的数据存放在服务器端



2.Cookie
Cookie是客户端技术 将会话产生的数据保存在客户端中
当浏览器访问服务器 服务器可以通过在响应中增加set-Cookie的响应头 命令浏览器保存一段cookie信息
浏览器会将cookie信息保存在本地 之后再去访问服务器时 会自动在请求中 通过cookie请求头 带着cookie信息
服务器可以通过解析请求中的cookie请求头 获取信息 从而获取到了之前保存的会话相关的数据


案例:
展示上一次访问时间




为了方便cookie的开发,java专门提供了一套和cookie相关的api


Cookie类的基本方法
//Cookie没有无参的构造 cookie创建时就必须指定好cookie的名字和cookie的值
Cookie cookie = new Cookie(String name,String value);


//Cookie的名字只能获取 不能修改
String getName()
String getValue(String name)
String setValue(String name ,String value)


//向响应中加入cookie
response.setCookie(Cookie c);


//从请求中获取cookie
Cookie [] request.getCookies();

Cookie保存的时长
如果不设置 默认Cookie会被保存在浏览器的内存中 浏览器什么时候关 Cookie什么时候消失 这种cookie称之为会话级别的cookie
也可以通过代码来设置cookie的保存时长


//指定浏览器 将cookie保存到什么时候 浏览器收到的cookie信息中如果包含了 指定的超时时间 浏览器就会cookie信息以文件的形式保存到浏览器的临时文件夹中 保存到指定的时间 这段时间内该文件一直存在 即使多次开关浏览器 仍然能够看到此cookie
setMaxAge(int time)
int getMaxAge()


Cookie在访问哪些路径时携带cookie
如果不设置 则在访问发送cookie给浏览器的Servlet的父一级目录及其子孙目录时 会携带这个cookie
http://localhost/Day12/servlet/LastTimeServlet2
-->
http://localhost/Day12/servlet/




//可以通过方法设置浏览器在访问哪些路径时携带此cookie
setPath(String path)
String getPath()



删除cookie
如果想要删除cookie 需要发送一个 和要删除的cookie的名字相同 path相同 但是maxAge被设置为0的 cookie
这样一来 名字相同 path也相同 浏览器收到cookie后 覆盖原来的cookie 只有 立即超时 自动被浏览器删除掉
从而间接的实现了删除cookie的操作




cookie其他
一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)。
一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie。
浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。
如果创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除。若希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。
注意,删除cookie时,path必须一致,否则不会删除(浏览器通过cookie的name+path来标识一个cookie)


案例:EasyMall登陆功能记住用户名



3.Session
Session是服务器端会话数据保存技术
服务器在需要时 可以为每个用户创建独一无二专为该用户服务的session对象 在其中保存该用户会话相关的数据
之后该用户再来访问服务器时 可以找到之前创建的属于他的session 从中找到之前存入的数据 从而实现会话数据的保存
由于每个用户各自有各自的session 每个session只为对应的用户服务 数据不会混乱。


Session是一个域对象
生命周期
当第一次调用request.getSession()方法时表明 会话中需要用到session了,此时服务器创建session对象,一直驻留在内存中为当前会话服务。


自杀 - 可以明确的调用session.invalidate()立即杀死session。
超时 - 如果一个session超过30分钟 没人用 则 服务器认为会话超时 杀死会话对应的session
意外身亡 - 当前web应用销毁时,session跟着被销毁。
作用范围
整个会话
主要功能
在会话范围内共享数据


创建、获取Session
request.getSession()
操作域
session.setAttribute()
session.getAttribute()
session.removeAttribute()
杀死session
session.invalidate()






案例:利用session实现登录 注销
所谓的登录,其实就是根据用户提交 的用户名和密码 检查数据库 
如果不正确就提示 如果正确 就创建session 保存该用户的登录标记
之后的访问中可以通过检查登录标记 获知当前用户是否登录 如果登录过 该用用户是谁


所谓的注销其实就是杀死session 使session中的登录标记失效

案例:验证码校验 数据的回显
ValiImgServlet --> 生成验证码时 将验证码的内容 存入 session中备用
regist.jsp --> 注册时填写了注册表单 其中有验证码 跟着被提交
RegistServlet -> 从请求参数中获取用户提交的验证码 从session中获取当初发给他的验证码 两个进行比较 如果不一致 中止注册过程 提示用户 验证码不正确 如果两个一致 验证码正确 继续注册流程
regist.jsp --> 如果验证码校验不通过 回到注册页面 要从request域中获取错误消息 进行提示
如果验证码校验不通过 回到注册页面 进行数据的回显 -- 将之前提交的表单的数据 显示回来 


原理
session是基于一个叫做jsessionid的cookie工作的


当浏览器访问服务器 调用到 request.getSession时 此方法会检查请求中是否 有叫做jsessionid的cookie
如果没有 则说明这时这是第一次用到session 创建session使用 并将session id 作为jsessionid cookie 发送给浏览器保存
浏览器在后续的访问中 就会带着这个jsessionid 来访问
后续再调用到 request.getSession 时 此方法检查请求中 是否有叫做jsessionid的cookie 发现有 则在内存中倒找id对应的session使用
如果找不到 说明session 已经被销毁 则创建新的session使用个 并在响应中再通过cookie发送新的jsessionid

**了解即可**如果禁用了cookie session也就用不了了 - 可以通过URL重写来解决
如果禁用了cookie 浏览器不再基于cookie来保存jsessionid 在服务器无法获取到jsessionid 也就无法找对应的session 
所以想解决这个问题 就需要想办法 将jsessionid的值 带给服务器
此时可以使用URL重写的技术来实现
所谓的URL的重写 就是 将地址 改写 在地址后使用特殊的参数 携带jsessionid的技术 
虽然cookie用不了了 但是 通过地址 仍然可以携带jsessionid的信息 从而使用session


这个技术 需要将应用中所有的地址都要进行URL重写 相对来说非常麻烦
而这么麻烦带来的唯一的好处是 禁用cookie后仍然可以使用session 似乎并不值得这么麻烦
所以 现在很多网站 都不会去做URL重写 对于禁用cookie的情况 不处理 或者 检测到用过户禁用cookie就引导用户 打开浏览器的cookie 再来使用网站


response.encodeURL(String url);
//--如果是普通的地址用这个方法
response.encodeRedirectURL(String url);
//--如果地址是用来进行重定向的,用这个方法


4.cookie和session的区别
cookie将会话相关数据保存在客户端 session将会话相关的数据保存在服务器端
cookie可以保存的时间比较长 session超过30分种没人用就销毁
cookie有可能随着用户的操作被清除 session只要不手动删除 在存活期间可以可靠的访问
cookie将信息保存在浏览器中 可以通过翻临时文件夹 查看cookie中的数据 不安全 session将会话相关的数据保存在服务器内存中 安全性高很高。


如果需要将会话数据保存的很久 -- cookie
如果希望会话数据不会因为用户的操作丢失 -- session

如果会话数据比较在意安全性 -- session


========================================================================================================================================
路径专题:
相对路径:不以/开头的路径称为相对路径,相对路径是基于当前路径进行计算得到的一个路径。其中可以通过../表示上一级目录。
绝对路径:以/开头的路径称为绝对路径,绝对路径是在一个参考路径上直接拼接而得到的路径。
盘符开始的绝对路径(硬盘路径):直接从盘符开始,说是哪就是哪。


WEB阶段路径编写:
虚拟路径:
写绝对路径,不到万不得已不要用相对路径。
写绝对路径的情况下,如果路径是个浏览器用的则参考路径是当前虚拟主机,一定要写应用名。如果路径是给服务器用的则参考路径是当前web应用,应用名层一定不要写。
request.getRequestDispatcher("/index.jsp").forward();
request.getRequestDispatcher("/index.jsp").include();
response.setHeader("refresh","1;url=/Day08/index.jsp");
response.setHeader("Location","/Day08/index.jsp");
response.sendRedirect("/Day08/index.jsp");
<a href="/Day08/index.jsp">
<img src="/Day08/index.jsp">
<form action="/Day08/index.jsp">
<link href="/Day08/index.jsp">
<script srce="/Day08/index.jsp">




真实路径:
具体问题具体分析

File file = new File("");//如果写相对路径到程序的启动目录下找资源(tomcat/bin),如果写觉对路径就到程序启动目录的根目录下找资源。如果写硬盘路径,可以找到资源,但是通常一旦换了一个环境,路径很可能需要修改。
servletContext.getRealPath("");//此方法在传入的路径前拼接当前web应用的硬盘路径,拼接出当前资源的硬盘路径,所以给一个相对于当前web应用根目录的路径即可。
classLoader.getResource("");//类加载器在哪里加载类就在哪里加载资源,所以要给一个相对于类加载位置的路径。







*------------------------------------------------------------------------------------------------------------------------------------------------------------------------***

一、jsp
1.jsp概述
sun公司提供的动态web资源开发技术。
Servlet本质上是一段java程序,非常适合于编写逻辑处理,但是不便于对外输出html格式的页面。
为了解决这样的问题,sun提供了jsp这样的技术,改变了原来Servlet在java中编写html的过程,变为了jsp在html中编写java的过程。
jsp看起来就像一个html页面一样,但是其中可以嵌入java代码,本质上是一种动态web资源开发技术。
jsp在第一次被访问到时被翻译成一个Servlet,对这个jsp的访问其实是翻译过来的Servlet在执行

2.jsp语法
模板元素:直接写在jsp中的html内容称为模版元素。模版元素组成了jsp页面的基本骨架。
在翻译过来的Servlet中直接被out.write输出到了页面


脚本表达式:<%= java表达式%> 其中可以编写java表达式,注意是表达式而不是语句,所以后面不能有分号
在翻译过来的Servlet中,计算了表达式的值后被输出到浏览器页面。


脚本片段:<% 若干java语句 %> 其中可以编写若干java语句,注意是语句,必须有分号。
在翻译过来的Servlet中被复制粘贴到了对应位置执行。
一个jsp页面中可以有多个脚本片段,多个脚本片段之间可以互相访问。
某个脚本片段中的代码可以不完整,但是要保证在翻译过来的Servlet中java代码要完整。


jsp声明:<%! 若干java语句%> 可以为翻译过来的Servlet来增加类的成员
写在其中的代码将会在翻译过来的Servlet中被放置到和service方法同级的位置成位类的一个成员。


jsp注释:
<%-- 注释的内容 --%>  被jsp注释注释的内容,不会被翻译到Servlet中,在翻译过程中就被丢弃了。
// /**/ /** */ 被java注释注释的内容,在翻译时当做java代码原样复制粘贴到对应位置,但是被注释了,不会执行,在被编译为class时被丢弃
<!-- --> 被html注释注释的内容,被当做模版元素,原样输出给了浏览器,浏览器认识该标签,当做html注释不予显示。
jsp指令:<%@ 指令名 若干属性 %> 不直接产生任何的输出,是用来只会解析引擎工作的标签
page指令
声明当前jsp的基本属性,指挥解析引擎如何翻译jsp页面中的其他部分内容。
可以写在jsp页面的任意位置,但是通常为了提高可阅读性,通常会写在jsp页面的第一行。


[ language="java" ] 当前JSP使用的开发语言
[ extends="package.class" ] 当前jsp翻译成servlet后要继承的类,注意此值必须是一个servlet的子类,一般情况下不要改
!![ import="{package.class | package.*}, ..." ] 导入需要使用到的包 java.lang.*;javax.servlet.*;javax.servlet.jsp.*;javax.servlet.http.*;
!![ session="true | false" ] 用来指定当前页面是否使用session,如果设置为true,则翻译过来的servlet中将会有对session对象的引用,于是可以直接在jsp中使用session隐式对象。但是这将导致一旦访问jsp就会调用request.getSession()方法,可能导致不必要的空间浪费。如果确定jsp中不需要session可以设为false
[ buffer="none | 8kb | sizekb" ] out隐式对象所使用的缓冲区的大小
[ autoFlush="true | false" ] out隐式对象是否自动刷新缓冲区,默认为true,不需要更改
!![ errorPage="relative_url" ] 如果页面出错,将要跳转到的页面,除了在jsp中使用此属性指定错误页面外也可以在web.xml中配置整个web应用的错误页面,如果两个都设置则jsp中的此属性起作用
!![ isErrorPage="true | false" ] 如果设置此属性为true,翻译过来的servlet中将含有Exception隐式对象,其中封装的就是上一个页面中抛出的异常对象
[ contentType="mimeType [ ;charset=characterSet ]" | "text/html ; charset=ISO-8859-1" ] 和jsp乱码相关的指令,用来指定jsp输出时,设置的Content-Type响应头用来指定浏览器打开的编码
!![ pageEncoding="characterSet | ISO-8859-1" ] 服务器翻译jsp时使用的编码集.如果向防止jsp乱码,应该保证文件的保存编码和jsp翻译成servlet用的编码以及输出到浏览器后浏览器打开的编码一致.此属性一旦设置好,翻译引擎会间接帮我们设置content-type属性.
[ isELIgnored="true | false" ] 当前页面是否使用el表达式,设置为false时表示启用el,j2ee4.0开始默认支持,j2ee4.0一下做开发时,如果要使用el表达式,需将此属性设置为false
include指令
实现页面包含的指令


静态包含:多个组件被翻译到一个Servlet中,时源文件级别的合并。
<%@inlucde file="" %>
动态包含:多个组件各自翻译成各自的Serlvet,被访问时各自执行,最终输出时再输出流上进行合并。
request.getReqeustDispatcher("").include();
只有page指令实现的包含是静态包含,其他方式实现的包含都是动态包含。
静态包含的效率略高于动态包含,所以推荐使用静态包含。


taglib指令
引入标签描述库文件
3.jsp中的九大隐式对象:jsp翻译引擎在将jsp翻译成Servlet的过程中,自动创建出来的九个对象,由于翻译过来的Servlet中自动就有,所以在jsp页面的java代码中可以直接使用。
page
request
response
config
application
session
out
exception
pageContext


4.PageContext -- 代表当前jsp页面的运行环境
做为入口对象,获取其他八大隐士对象
getException方法返回exception隐式对象 
getPage方法返回page隐式对象
getRequest方法返回request隐式对象 
getResponse方法返回response隐式对象 
getServletConfig方法返回config隐式对象
getServletContext方法返回application隐式对象
getSession方法返回session隐式对象 
getOut方法返回out隐式对象


是一个域对象,还可以作为入口对象操作四大作用域

作用范围:当前jsp页面
生命周期:访问jsp页面开始时创建,访问jsp结束后销毁
主要功能:在当前jsp页面中共享数据


setAttribute(String,Object)
getAttribute(String)
removeAttribute(String)
getAttributeNames()




setAttribute(String name, Object value,int scope)
getAttribute(String name,int scope)
removeAttribute(String name,int scope)
findAttribute(String name)//可以在四大作用域中按照由小到大的顺序搜寻指定名称属性的值,找到就返回,找不到就返回null


其中pageContext中代表域的常量:
PageContext.APPLICATION_SCOPE
PageContext.SESSION_SCOPE
PageContext.REQUEST_SCOPE
PageContext.PAGE_SCOPE 


可以实现便捷的转发和包含
request.getRequestDispatcher("xxxx").forward(request,response);
request.getRequestDispatcher("xxxx").include(request,response);


pageContext.forward("xxxx");
pageContext.include("xxxx");


=========================================================================================================================
二、JSP标签技术 -- 利用jsp中的标签技术,将jsp页面中的java代码替换为具体功能的标签。sun在jsp2.0开始已经不再推荐在jsp中出现任何一行java代码了。


1.jsp标签:sun提供的jsp2.0中原生的标签,不需要导入任何开发包就可以直接使用。
<jsp:inclue>用来替代request.getRequestDispatcher().include()
<jsp:forward>用来替代request.getRequestDispatcher().forward()
<jsp:param>配合前两个标签使用,可以在包含或转发时,带一些参数过去

2.el表达式:表达式语言,可以替换掉jsp中的脚本表达式


${el表达式}
el只能获取不能遍历
el只能获取不能设置
使用中括号的地方都可以通过点号进行替换。除了中括号中是数字或包含特殊字符.-的情况除外。
~1.获取数据
获取常量数据
获取变量数据
获取数组中的数据
获取集合中的数据
获取Map中的数据
获取javabean的属性

~2.执行运算
算数运算
el在进行算数运算时,会将参与运算的非数组试图转换为数字参与运算。如果转换不成功,报错。
关系运算

逻辑运算


三元运算符
3>2? "yes" : "no"
empty运算符
判断对象是否为空,判断字符串是否是一个空串,判断集合数组是否没有任何内容,判断作用域中是否没有任何域属性
~3.获取常用开发对象
el中的预先定义了11个常用对象,这11个对象不需要预先存入域中就可以直接在el中使用


!!!!pageContext -- 有了它意味着就有了9大隐式对象


!!pageScope -- 代表四大作用域的对象,要注意的是不是代表对象,而是代表作用域
!!requestScope
!!sessionScope
!!applicationScope


!!param -- 所有请求参数组成的Map<String,String> 
paramValues -- 所有请求参数组成的Map<String,String[]>


header -- 所有请求头组成的Map<String,String>
headerValues -- 所有请求头组成的Map<String,String[]>


!!cookie -- 所有cookie信息组成的Map<String,Cookie>
initParam -- 所有当前应用初始化参数组成的Map<String,String>


~4.调用java方法 仅作了解
写一个类包含被调用的方法,方法必须是静态公有方法


写一个tld文件(标签描述库文件),描述被调用的方法,注意tld文件必须放置在WEB-INF目录下除了classes和lib以外的目录中


在jsp页面中引入tld,使用该方法




jstl标签库:提供给开发人员使用的标准的标签库,利用它配合el可以将jsp页面中的绝大部分java代码替代掉。
javaee4及之前的版本如果需要使用jstl要导入开发包。
而javaee5以后内置了jstl开发包,不需导入可以直接使用。


核心标签库 (core)  --- c
国际化标签 fmt
数据库标签 sql 
XML标签  xml
JSTL函数(EL函数) el
fn函数库:提供了很多操作字符串的方法,可以按照el调用方法的方式直接使用

c:out
!!!c:set
!c:remove
c:catch
!!!!!c:if
!!!!c:choose c:when c:otherwise
!!!!!c:foreach
c:fortokens
c:import
c:redirect
c:param
c:url




4.自定义标签技术:可以是开发人员开发特定功能的标签
自定义标签的继承结构:
SimpleTag
|
|--SimpleTagSupport
在开发自定义标签时可以自己实现SimpleTag接口,也可以继承默认实现类SimpleTagSupport类

想要开发一个自定义标签:
~1.写一个类实现SimpleTag接口(继承SimpleTagSupport类),在类中编写自定义标签要实现的功能
当jsp被访问遇到自定义标签时,每次都会创建出自定义标签的处理类对象。
创建出来后,立即调用setJspContext()将当前页面的PageContext对象传入。
如果当前标签具有父标签,将会调用setParent方法将父标签对象传入,如果没有父标签则这个方法不会被调用。
如果当前标签具有标签体,则将标签体封装到JspFragment对象中,通过调用setJspBody()方法将标签体传入,如果当前自定义标签没有标签体,则该方法不会被调用。
如果当前标签具有属性,则调用属性的setXxx方法将属性传入。
最后调用doTag()方法,执行自定义标签要处理的逻辑。


~2.写一个tld文件(必须放置在WEB-INF目录下除classes和lib以外的其他目录中),描述自定义标签类
<tag>
<name>TagDemo1</name> -- 标签的名字
<tag-class>com.tarena.tag.TagDemo1</tag-class> -- 标签的处理类
<body-content>scriptless</body-content> -- 标签体的类型
empty 没有标签体
scriptless 当前标签的标签体可以是任意内容,处理java源代码
JSP 当前标签的标签体可以是任意内容,包括java源代码,但是从jsp2.0开始sun已经不再推荐在jsp页面中包含java代码了,所以在简单标签开发技术中,这个值已经无法使用了。
tagdependent 当前标签的标签体不对外产生任何输出,该标签体是为后台使用的。
<attribute> -- 声明一个属性
<name>attr</name> -- 属性名
<required>true</required> -- 是否是一个必须存在的属性
<rtexprvalue>true</rtexprvalue> -- 该属性是否支持el表达式
<type>java.lang.String</type> -- 属性的java类型
</attribute>
</tag>
~3.在jsp页面中引入tld文件,再使用其中定义好的标签


自定义标签的基本功能实现:
控制标签体是否执行 c:if
//--不執行:什么都不做,默认标签体就不执行
//--执行:通过调用JspFragment对象的invoke方法可以将标签体进行输出

控制标签体之后的内容是否执行 c:redirect
//--执行:什么都不做默认标签之后的内容执行
//--不执行:抛出一个特殊的异常SkipPageException就可以阻止标签之后的内容执行了

控制标签体重复执行 c:foreach
//for(int i = 0;i<5;i++){
// getJspBody().invoke(null);
//}

修改标签体后输出 ...
//StringWriter writer = new StringWriter();
//getJspBody().invoke(writer);
//String str = writer.toString();
//str = str.toUpperCase();
//getJspContext().getOut().write(str);


开发带有属性的标签
在类中定义一个javabean属性,并对外提供setXxx方法
在tld文件中描述改属性


打包标签库:





案例:开发一个输出来访者ip的标签
案例:pTag:if
案例:pTag:for
案例:pTag:choose pTag:when pTag:otherwise


<c:choose>
<c:when test="">
</c:when>
<c:when test="">
</c:when>
<c:when test="">
</c:when>
<c:when test="">
</c:when>
<c:otherwise>
</c:otherwise>
</c:choose>







=====四大作用域总结================================


pageContext域 --- pageScope -- page域
生命周期:访问jsp开始创建,结束时销毁
作用范围:当前jsp页面
主要功能:在当前jsp页面中共享数据
request域 --- requestScope 
生命周期:请求开始时创建,请求结束后销毁
作用范围:整个请求链
主要功能:在整个请求链中共享数据
session域 -- sessionScope
生命周期:第一次调用request.getSession()时创建。超时、自杀、意外身亡
作用范围:整个会话
主要功能:在整个会话范围内共享数据
ServletContext域 -- applicationScope -- application域
生命周期:服务器启动应用加载后立即创建,服务器关闭或web应用移除出容器时销毁
作用范围:整个web应用
主要功能:在整个应用范围内共享数据




什么时候用什么域?
如果数据只在jsp页面中使用,用page域
如果数据需要在转发包含时传递,用request域
如果数据现在我需要用,过一会我还需要用,用session域
如果数据现在我需要用,过一会别人也需要用,存ServletContext域中


=============================================

==============================================================================================
EasyMall重构:
jsp中的java代码用标签技术替代
配置虚拟主机,实现www.easymall.com访问
在[tomcat]/conf/server.xml配置虚拟主机<Host name="www.easymall.com" />
修改Hosts文件增加 127.0.0.1 www.easymall.com
在[tomcat]/conf/www.easymall.com/ROOT.xml 中编写<Context docBase="工程的WebRoot目录"/>直接让tomcat中的www.easymall.com虚拟主机管理工程目录下的WebRoot,好处是不用发布,直接修改工程中的文件立即可以起作用。
**此种方式下没有了发布过程,myeclipse就不会自动帮我们加入jstl开发包了,需要自己导入。


用javabean保存信息


整理代码结构,实现软件分层


注册用户:
RegistServlet
解决请求响应乱码
验证验证码
获取用户提交的数据
校验数据
将数据封装到bean中,调用Service的方法注册用户
注册成功后回到主页
UserService
注册用户的方法:
检查用户名是否存在
注册用户到数据库
UserDao
根据用户名查找用户
加入用户数据到数据库中
登录用户:
LoginServlet
处理乱码
获取用户名密码
记住用户名的处理
调用Service根据用户名密码查找用户
找不到就提示用户名密码不正确
找到就登录用户回到主页
UserService
登录用户的方法
调用到根据用户名密码查找用户
UserDao
根据用户名密码查找用户的方法


AJAX校验用户名:
解决乱码
获取用户名
检查用户名是否已经存在





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值