jsp基础

jsp 是用java + html    开发动态资源的技术, jsp本质上就是servlet

jsp特点: 由服务器运行 jsp页面既可以写html 又可以写java代码 apahce服务器的work目录存放jsp运行时的临时文件 java代码写在 <% %> 中 执行过程: 1.tomcat服务器检测到jsp文件 在work目录将jsp翻译成java源文件 2.交给jvm编译成class字节码文件 3.构造jsp类对象 4.调用相关方法 返回内容到浏览器 jsp修改或者临时文件被删除 会重新执行1,2 第n(n>1)次访问执行直接执行4

服务器翻译出来的java文件头:

public final class showTime_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports {
}

其中org.apache.jasper.runtime.HttpJspBase 这个服务器内部的类 继承HttpServlet,因此 jsp间接继承HttpServlet,故jsp就是一个sevlet程序

jsp生命周期:

  1. 翻译 .java
  2. 编译 .class
  3. 构造方法 同servlet一样 构造方法,init方法只在第一次调用
  4. init方法
  5. service方法
  6. destroy方法

servlet技术可以在jsp中使用 jsp的技术并不全部适用于servlet

Jsp 语法:

模板

jsp页面中的html代码

表达式

<%=变量或表达式 %>  向浏览器输出变量值或者表达式结果

执行原理: 翻译成java代码后为 out.print(变量表达式);

脚本

<% java代码%>  执行java代码 实质是把脚本中的java代码拷贝到翻译后的servlet类中的_jspServive 方法中执行 可以在其中穿插html代码 <% for(int i = 0; i < 5; i++){ %> <h<%=i %» 标题<%=i %></h<%=i %» <% } %>

声明: <%! 声明变量或者方法 %>    翻译成java代码后为类的成员变量或成员方法,不能重复声明定义已有的方法 脚本中的变量为service方法中局部的,脚本中不能声明方法

注释: <!–html注释 – >  <%–jsp注释 –%> jsp注释的内容不会翻译到java文件  html注释内容会翻译执行

Jsp的三大指令:

  1. include:   在当前页面包含其它页面在当前页面包含其它页面

原理: 将被包含页面的代码拷贝到当前页面相应位置合并为一个文件, 再翻译为java文件 ———  这种包含叫静态包含          (由于被包含页面全部被拷贝,所以只需要写body的内容即可) 2.page:       告诉服务器如何翻译jsp文件  包含常用属性如下:

<%@page
import="java.util.* , java.text.*"   ---导包语句,多个包逗号分隔
language="java"          ---使用什么动态语言翻译(只支持java)
contentType="text/html; charset=utf-8"
---服务器发送给浏览器的数据类型和编码 //默认参考pageEncoding的值
(翻译成:response.setContentType();)
pageEncoding="utf-8"     ---告诉服务器页面的编码,eclipse中默认保存编码参考这个
errorPage="error.jsp"    ---指定错误处理页面
isErrorPage="false"      ---指定当前页面是否错误页面错误信息会封装到exception中,
默认false。 指定为true后,可以使用 <% exception.getMessage() %> **exception**内置对象
可在web.xml  配置全局错误页面  <<error-page> <error-code></error-code><location/></error-page>>
errorPage="error.jsp" 优先
buffer="8kb"              ---jsp页面的缓存大小
session="true"            ---是否开启session功能 false 不能用session内置对象 true可以使用
isELIgnored="false"   是否忽略EL表达式
%>
  1. taglib** –引入标签库,后面介绍

jsp的内置对象:

jsp加载翻译时会自动声明并创建好这些对象,开发者可以直接使用这些内置对象

九大内置对象 对象名 所属类

  1. request HttpServletRequest
  2. response HttpServletResponse
  3. config ServletConfig
  4. application ServletContext
  5. session HttpSession
  6. exception Throwable

7.out              JspWriter JspWriter 类 相当于带缓存的 PrintWriter,它有write() 方法向浏览器写出数据,向jsp缓冲区写出内容 buffer指定大小默认8kb 缓冲区满 、 flush刷新缓冲区 、关闭缓冲区(buffer=0kb)、 jsp页面执行完毕 、 缓冲区内容都会写向页面 out.getRemaining()  查看缓冲区剩余大小  out.getBufferSize()查看缓冲区大小

8.page               Object(this)   //等价servlet中的this

9.pageContext   PageContext

jsp上下文对象,可以获取其它八个内置对象,它们都封装到了pagecontext对象中 由于这八个对象都是jspservcice 内的局部变量,如果在其他方法使用就需要将pageContext传入,由pageContext取得。 自定义标签时使用此对象较多pageContext本身也是一个域对象 可以在不同资源间共享数据 setAttribute() getAttribute() 保存到page域中,其作用范围只在本页面 也可以指定参数保存到其它域中: setAttribute(“message”,”hello world”, PageContext.REQUEST_SCOPE); 其它页面中request.getAttribute(“message”) 取得 或 getAttribute(“message”, PageContext.REQUEST_SCOPE); 可以指定常量,表示保存到相应的域中

 pageContext.findAttribute(“key”)  可以自动在所有域中搜索查找key的value 搜索顺序:page域 –> request域 –>   session域 –> context域

servlet 与jsp结合,各取所需 servlet: 接收数据 处理数据 跳转页面 jsp:     显示数据

**EL表达式:

** 因为jsp开发尽量少些java代码,可以用EL表达式简化。

  1. 替换jsp表达式<%= %>语法:${变量或表达式},向浏览器输出 域对象 中的变量值或表达式的结果.因此值应先保存到域对象中: pageContext.setAttribute(“name”,name); 取值: ${name}  等价于: pageContext.findAttribute(“name”);

  2. 从指定域中获取数据: ${requestScope.name}

  3. 取对象的属性值 ${student.name} 本质上等价于 ((Student)pageContext.getAtrribute(“student”)).getName(); 使用类的getName方法取值

  4. 获取集合对象值 ${list[0]}   等价调用list.get()  方法 ${map[‘key’]}  等价调用map.get(key)方法

el表达式中的运算:  比较运算 算术运算 逻辑运算 判断字符串的简写: ${empty string}   等价于– ${string == null   string == “”}

jsp标签:

标签用来替换jsp中的java脚本 .达到减少java代码,简化书写效果 ·内置标签(动作标签) ·

转发标签: ·参数标签: 例:

·包含标签: 包含其它页面  原理与include指令不同 会单独将其他页面翻译编译,然后在运行时在java代码中通过一个include方法在合并, —–动态包含 与静态包含不同的是动态包含可以传递参数,然后在被包含页面通过getParameter获取参数值

·外置jstl标签      -外置需要导入标签库 java standard tag library  标准标签库 1.使用需要导入jstl.jar包  myeclipse新建javaee项目时已自动导入 2.需要导入标签库通过:    <%@taglib uri=”tld文件名字” prefix=”简写”%> tld名字在jstl包中web-inf文件内 ·核心标签库(c标签库) 保存数据 默认保存数据到pageContext域中,可以使用scope指定。 用EL表达式获取值 获取数据 从域中获取数据,当${name} 为空时,使用默认值default.  escapeXml设置为false会对值进行转义 条件判断   _ _    条件成立_ _  多条件判断 __

    _ _      条件成立_ _        _ _      条件成立_ _        _ _      条件不成立_ _     </c:choose> 循环   <c:forEach  begin=”” end=”” step=”” items=”” var=”” varStatus=”“> begin开始     end结束    step步长          items var同增强for循环     varStatus当前遍历元素状态属性(varStatus.count表示当前位置)     </c:forEach> forTokens  分割及遍历字符串: String str=”hello-wrold-ggbond”     pageContext.setAttribute(“str”,str);     _ _          ${s}_ _   

重定向 自定义标签:

       当标签库中没有满足需求的标签时,可以自定义标签 例:用户需要一个显示ip的标签 1.写一个继承标签处理类SimpleTagSupport的类

 
       public class ShowIp extends SimpleTagSupport{
        
        @Override
        public void doTag() throws JspException, IOException {
            // TODO Auto-generated method stub
            
            //通过pageContext域对象取得其它域对象
            PageContext pc = (PageContext)getJspContext();
            HttpServletRequest request = (HttpServletRequest) pc.getRequest();
            
            JspWriter out = pc.getOut(); 
            out.write(request.getRemoteHost());
        }
        
    }

2.在web项目的WEB-INF目录下建立.tld后缀的标签库声明文件(参考核心标签库写法)

<?xml version="1.0" encoding="UTF-8" ?>
       
       <taglib xmlns="http://java.sun.com/xml/ns/j2ee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary\_2\_0.xsd"
           version="2.0">
           
         <description>my own tag</description>
         <display-name>test tag</display-name>
         
         <!\-\- 标签库版本 -->
         <tlib-version>1.1</tlib-version>  
         <!\-\- 使用标签库的简写 -->
         <short-name>mytag</short-name>
           <!\-\- tld文件的唯一标记 -->
         <uri>http://com.ctguggbond.mytag</uri>
       
         <!\-\- 一个标签的声明 -->
         <tag>
           <name>showip</name>
          <!\-\- 处理标签类的全名   刚才自定义的类全名-->
          <tag-class>com.ctgu.taglib.ShowIp</tag-class>
         <!\-\- 输出内容的格式 --> 
           <body-content>scriptless</body-content>
         </tag>
         
         
         </taglib>

3.在jsp头部导入自定义标签库 <%@ taglib uri=”http://com.ctguggbond.mytag” prefix=”mytag”%>

4.使用自定义标签     自定义标签执行过程: 在将jsp翻译成java源文件时,会将标签形成对应的一个方法,调用该方法 方法内部通过uri声明找到标签对应的处理类全名,然后构造对象, 依次调用该类的setJspConext(设置pageContext) – setParent(设置父标签对象) – setJspBody(设置标签体内容) –doTag(执行自定义标签的功能) 自定义标签可以自行控制标签的内容及标签体后面的内容输出.以及自定义属性,操作如下:


   public class tagTest extends SimpleTagSupport{
        /\*
        \* 自定属性就是定义此类的成员变量并提供setter方法
        */      
       private Integer num;
       public void setNum(Integer num) {
           this.num = num;
       }
   
       /\*
       \* 控制标签体及标签后面的内容输出
       */
       @Override
       public void doTag() throws JspException, IOException {
           System.out.println("执行了标签");
           
           /\*\*
            \* 1 .通过调用invoke()控制标签内容输出   
            */
           JspFragment jspBody = this.getJspBody();
           
           /\*\*
            \* 执行invoke方法 把标签体内容输出到指定的Writer对象中
            \* 若writer对象指定为null  就默认为out内置对象
            */
           JspWriter out = this.getJspContext().getOut();
           jspBody.invoke(out);
           //jspBody.invoke(null);等价于上面的代码
           
           /\*\*
            \* 循环控制重复输出标签体内容 
            */
           for(int i=1;i<=num;i++){
               jspBody.invoke(null);
           }
           
           /\*\*
            \* 改变标签体内容
            \* 通过自定义传入writer对象将标签体内容取出再作处理后通过out输出到浏览器
            *
            */
           StringWriter sw = new StringWriter();
           jspBody.invoke(sw);
           String content = sw.toString();
           content = content.toLowerCase();
           this.getJspContext().getOut().write(content);*/
           
           
        
         /*
         *  2控制标签余下内容是否输
   *   抛出SkipPageException异常将停止执行后面的内容
   */
  throw new SkipPageException();
  
         }
    }
0

Powered by Jekyll and Theme by solid