友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
富士康小说网 返回本书目录 加入书签 我的书架 我的书签 TXT全本下载 『收藏到我的浏览器』

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  求余  


返回目录 上一页 下一页 回到顶部 9 9
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!