友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
JSP入门教程(DOC格式)-第12部分
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!
生成
g。setColor(new Color(20 + random。nextInt(110); 20 +
random。nextInt(110); 20 + random。nextInt(110)));
g。drawString(rand; 13 * i + 6; 16);
}
// 将认证码存入 SESSION
request。getSession()。setAttribute(〃captcha〃; sRand);
// 图象生效
g。dispose();
// 输出图象到页面
ImageIO。write(image; 〃JPEG〃; response。getOutputStream());
}
代码最先设置 response (响应)中的头部配置,告诉浏览器不要缓存对
/captcha。jpg 的请求结果,这样才能保证每次刷新页面都看到最新生成的图片,
要是设置了缓存很可能每次看到的都是最先请求看到的图片。
中间一大段代码实现动态生成图片的功能,我们先随机获得几个数字,然后写到
BufferedImage 中,最后就可以把图片数据写到response,因为图片是二进制数
111 / 148
…………………………………………………………Page 112……………………………………………………………
据,所以我们使用了 response。getOutputStream()而不是
response。getWriter()。
为了达到验证的功能,每次生成图片之后要记得讲随机得到的数字保存到
session 中,session 中的变量可以跨越多个请求周期存在,等用户输入验证码
提交后就能与 session 中的数据做比较了,这些是在CheckServlet 中实现的。
public void doPost(HttpServletRequest request; HttpServletResponse
response)
throws ServletException; IOException {
HttpSession session = request。getSession();
String requestCaptcha = request。getParameter(〃captcha〃);
String sessionCaptcha = (String) session。getAttribute(〃captcha〃);
if (sessionCaptcha != null &&
sessionCaptcha。equals(requestCaptcha)) {
session。removeAttribute(〃captcha〃);
request。getRequestDispatcher(〃/success。jsp〃)。forward(request;
response);
} else {
request。setAttribute(〃message〃; 〃验证码输入错误〃);
request。getRequestDispatcher(〃/index。jsp〃)。forward(request;
response);
}
}
这样我们便获得了彩色图性校验码的功能,例子在 12…01 目录下。
12。2。 图片校验码 jsp 版
使用 servlet 既需要编译源代码,又要在web。xml 加入对应的请求映射。如果只
是需要简单的验证码功能,我们也可以使用 jsp 实现。
我们已经知道 jsp 就是 servlet 的另一种形式,servlet 能做的事情 jsp 也可以
实现,下面就是实现 CaptchaServlet 功能的 captcha。jsp。
255) {
fc = 255;
}
if (bc 》 255) {
bc = 255;
}
int r = fc + random。nextInt(bc fc);
int g = fc + random。nextInt(bc fc);
int b = fc + random。nextInt(bc fc);
return new Color(r; g; b);
}
%》
captcha。jsp 中的代码与 servlet 基本相同,不过需要注意两点。
1。 在定义 Color getRandColor(int fc;int bc)的时候用到了的写法,
比普通多了一个叹号,这是在 jsp 中定义方法时必要的步骤,方法必
须写到中才能正常执行,感兴趣的话可以去 tomcat 的work 下找对
应生成的 java 代码来研究,看看和的代码分别生成到哪里。
2。 在 jsp 中使用response。getOutputStream()很可能引起一个问题。
getOutputStream() has already been called for this response
114 / 148
…………………………………………………………Page 115……………………………………………………………
在 tomcat5 下 jsp 中出现此错误,一般都是在 jsp 中使用了输出流(如输
出图片验证码,文件下载等)后没有妥善处理好。
具体的原因就是在 tomcat 中,jsp 转换成 servlet 之后在函数
_jspService(HttpServletRequest request; HttpServletResponse
response)的最后有一段这样的代码
finally {
if (_jspxFactory != null)
_jspxFactory。releasePageContext(_jspx_page_context);
}
这里是在释放在 jsp 中使用的对象,会调用response。getWriter(),因
为这个方法是和 response。getOutputStream()相冲突的,所以会出现以
上这个异常。
然后当然是要提出解决的办法,其实挺简单的(并不是和某些朋友说的那
样……将 jsp 内的所有空格和回车符号所有都删除掉),在使用完输出流以
后调用以下两行代码即可:
out。clear();
out = pageContext。pushBody();
我们还需要修改 index。jsp,让其中的 img 标签请求 captcha。jsp。
这里又一次证明了 html 写的仅仅是请求而已,src=〃include/captcha。jsp〃怎么
看都不像一个图片的名称,但是它确实可以正确显示图片,因为服务器将请求交
给 captcha。jsp,处理后得到是一个图片的数据,可以在浏览器里正常显示。
captcha。jsp 放在 12…02/include 目录下,小项目中可以直接用它了。
115 / 148
…………………………………………………………Page 116……………………………………………………………
第 13 章 剖析 el 表达式
注意
这里详细讲解如何在 jsp 中使用 el 表达式。
如果你不满足以下任一条件,请继续阅读,否则请跳过此后的部分,进入下一章:
第 14 章 生命周期。
1。 了解如何在 jsp 中使用及禁用 el 表达式。
2。 了解 el 表达式的取值方式。
13。1。 再谈 el (Expression Language)
我们已经知道 el 是 jsp…2。0 规范的一部分,tomcat…5。x 版本以上都已经能够支
持 jsp…2。0 规范,但在更低版本的 tomcat 和 webphere;weblogic 中还是无法使
用这一便捷方式。
其实我们也可以选择在 jsp 中禁止使用 el 表达式,使用 jsp 指令(directive)
可以对禁用某一个 jsp 中的 el 表达式。
禁用之后的 el 表达式会以原样显示出来,如下图所示。
为了对照,我们还在 13…01 下放了一个可以正常使用 el 表达式的例子,运行效
果如下图显示。
在 13…01/index。jsp 中禁用 el 表达式,是使用了 isELIgnore=〃true〃这样一条
jsp 指令(directive),请注意大小写。
116 / 148
…………………………………………………………Page 117……………………………………………………………
{hello}
还有一种批量禁用 el 的方法,我们可以在WEB…INF/web。xml 中使用
jsp…property…group 标签批量禁用 el,我们在 13…02/WEB…INF/web。xml 中进行
如下配置。
*。jsp
true
这样就会禁用所有以。jsp 后缀的请求中的 el 表达式,使用这种方式需要注意两
点。
1。 jsp…property…group 标签是 jsp…2。0 中新增功能,如果你使用低版本的
web。xml (2。3 或以下)就不能使用这个标签了。
2。 设置 jsp…config 会影响 jsp 生成 servlet 的过程,如果程序修改时已经
有 jsp 转换成 servlet 并缓存在 work 目录下,那么修改后需要先清除缓
存,才能看到效果。
实际上还有第三种方法可以禁用掉所有 jsp 中的 el 表达式,那就是把 web。xml
定义为 2。3 版。
117 / 148
…………………………………………………………Page 118……………………………………………………………
这个就是 13…03/WEB…INF/web。xml 的定义,定义了web…app 的版本号是 2。3,这
样一来所有的 jsp 都无法使用 el 表达式了,因为 el 表达式是 2。4 版才开始支持
的功能。
注意
说了以上三种禁用 el 表达式的方法,不是希望大家抛弃 el 表达式,相反是希望
大家在自己编写 el 时出现问题时,先去考虑是否有人在这三个地方做了设置造
成 el 表达式的失效。建议大家多多使用 el 表达式,少用一些 jsp 中的 scriptlet
代码。
13。2。 作用域
使用 el 的时候,默认会以一定顺序搜索四个作用域,将最先找到的变量值显示
出来。
如果我们有{username}这样一个正则表达式,它回去依次调用
pageContext。getAttribute(〃username〃) …》
request。getAttribute(〃username〃) …》 session。getAttribute(〃username〃)
…》 application。getAttribute(〃username〃),只要找到某一个不为空的值就立
刻返回。
这样的确方便我们的操作,但是随之也出现了另外一个问题,如果 pageContext
和 request 中有同名变量,但是我想取得request 中的变量该如何是好呢?这就
需要为 el 表达式引入作用域的概念了。
{pageScope。username}
{requestScope。username}
我们可以直接访问 13…04 这个应用,看看 el 表达式支持的所有对象。
118 / 148
…………………………………………………………Page 119……………………………………………………………
下面我们分别对每个作用域对象进行讲解。
表 13。1。 el 中的作用域
el 中的作用域 对应关系
pageContext 当前页的 pageContext 对象
pageScope 把 page 作用域中的数据映射为一个 map 对象
requestScope 把 request 作用域中的数据映射为一个 map 对象
sessionScope 把 session 作用域中的数据映射为一个 map 对象
applicationScope 把 application 作用域中的数据映射为一个 map 对象
param 对应 request。getParameter()
paramValues 对应 request。getParameterValues()
header 对应 request。getHeader()
headerValues 对应 request。getHeaderValues()
cookie 对应 request。getCookies()
initParam 对应 ServletContext。getInitParamter()
119 / 148
…………………………………………………………Page 120……………………………………………………………
例子中的{pageContext。request。contextPath}返回的是
request。getContextPath()的值,在此例中就是/13…04,我们经常使用这个
来拼接 jsp 中的绝对路径。
这里的{pageContext。request。contextPath}是一种特殊用法,不能使用
{request。contextPath}的形式替代。
pageScope; requestScope; sessionScope; appliationScope 都可以看作是
Map 型变量,调用其中的数据可以使用{pageScope。name}或
{pageScope'〃name〃'}的形式,这两种写法是等价的。
在某些情况下只能使用{pageScope'〃content…type〃'},这里不能写成
{pageScope。content…type},jsp 无法解析连字符(…)会出现错误。
需要注意的是{paramValues。name}得到的是一个字符串数组,如果需要获
得其中某个值,还需要使用{paramValues。name'0'}指定数组中的索引。
这与下面的{headerValues。name}是相似的。
{header。name}会取得 http 请求中的 header 参数,现实工作中很少用到这
里的数据。
例子中使用 Host 是指请求访问的主机地址,包括 ip 和端口号。而 Referer
比较有趣,如果用户通过超链接跳转过来的,Referer 会保存上次访问页面
的地址,我们就可以通过它来统计哪些用户是从哪里转来的了。
{cookie。name}将获得对应 cookie 的对象,比如我们用 jsp 将一段 cookie
发送给客户端。
Cookie cookie = new Cookie(〃username〃; 〃Username in cookie〃);
response。addCookie(cookie);
创建一个名称为 username,值为〃Username in cookie〃的Cookie 对象,然
后发送给客户端。
然后我们就可以使用{cookie。username}获得这个 cookie 了,
{cookie。username。name}获得 cookie 名称,{cookie。username。value}获
得 cookie 值。
ServletContext。getInitParamter()指的应用的初始变量,这些变量都是定
义在 web。xml 中的。
username
username with context param
120 / 148
…………………………………………………………Page 121……………………………………………………………
{initParam。username}就会得到这里的变量值。
以上都是死记硬背的东西,建议实际用到的时候翻看一下就好了,演示代码都放
在 13…04 下,为了获得 param 和 cookie 还要点击一下最下边的连接才可以。
13。3。 运算符
el 表达式中支持 java 中所有的操作符,并且还有一些扩展,下面我们简要做一
下对照。
表 13。2。 加减乘除四则运算
符号 说明
+ 加
减
* 乘
/或 div 除
%或 mod 求余
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!