记录下JSP学习内容,以免老年痴呆

JSP的执行原理

  • 浏览器访问的路径虽然是以.jsp结尾,访问的是某个jsp文件,其实底层执行的是jsp对应的java程序
    Tomcat服务器负责将.jsp文件翻译生成.java源程序,并将这个源程序编译生成.class字节码文件,访问.jsp,其实底层还是执行了.class文件中的程序
  • Tomcat内置了一个jsp翻译引擎,专门负责jsp翻译文件,编译java源文件
  • index.jsp文件被翻译成index_jsp.java文件,编译生成index_jsp.class源文件
    index_jsp这个类继承HttpJspBase,而HttpJspBase继承了HttpServlet
  • Tomcat目录下的work文件就是存放jsp转化成的.java文件
  • JSP文件后缀,默认是.jsp,JSP后缀可以通过修改CATALINA_HOME/conf/web.xml中修改
  • jsp就是servlet,只不过职责不同,jsp的强项是做页面展示
  • 在jsp文件中编写的所有html,css,JavaScript,对jsp来说,只不过是普通的字符串
    翻译成out.write(“翻译成这里”);

jsp文件第一次访问的时候为什么这么慢?

  • 启动jsp引擎,需要一个翻译的过程,需要一个编译的过程,需要servlet对象的创建过程
    init方法调用,service方法调用
  • 修改jsp文件不需要部署重启Tomcat文件
    第二次访问jsp文件,底层直接调用service方法
  • jsp也是单实例多线程环境下运行的一个servlet对象

JSP语法

1,jsp注释
2,jsp的小脚本
3,jsp的声明语法格式
4,jsp的九大内置对象
5,jsp表达式
6,jsp的指令
7,jsp的动作

1,jsp注释

<%-- jsp专业注释,使用这种注释方式,不会被翻译到java源文件中 --%>

2,jsp的小脚本
<% 在这里编写jsp脚本语句 %>

  • 小脚本中的java语句被翻译到servlet的“service方法”中,所以小脚本内必须编写java语句,java语句以分号结尾
  • <%%>中的Java代码是在service方法中,service方法中不能定义实例变量,方法,静态语句块

所谓的jsp规范,就是sun制定好的一些翻译规则,按照翻译规则进行翻译,生成对应的java源程序,不同的web服务器翻译的结果是完全相同的,因为这些服务器翻译的时候,都遵守了jsp翻译规范

3,jsp的声明语法格式
<%! 这里的Java语句是写在service方法之外的,可以写实例变量,静态变量,方法,静态语句块,构造函数,不能写Java语句,除非是变量声明 %>
4,jsp的九大内置对象

  • 什么是内置对象啊
    可以直接在jsp文件中拿来使用的对象引用

  • 九大内置对象有哪些?

    内置对象名称			对应servlet类名
    PageContext         javax.servlet.jsp.PageContex        页面范围
    request             javax.servlet.http.HttpServletRequest   请求范围
    session             javax.servlet.http.HttpSession          会话范围
    application         javax.servlet.ServletContext            应用范围
    out                 javax.servlet.jsp.JspWriter(与PrintWriter类似)
    response            javax.servlet.http.HttpServletResponse
    config              javax.servlet.ServletConfig
    exception           java.lang.Throwable
    page                java.lang.Object(page=this,就是指向本身)
  • 以上内置对象只能在service方法中“直接”使用,在其他方法中无法“直接”使用,可以间接使用

  • 四个作用域对象/范围对象
    pageContext:在同一个jsp页面中共享数据,不能跨jsp页面
    request:在同一个请求中共享数据
    session:在同一个会话中共享数据
    application:所有用户共享的数据可以放到应用范围

5,jsp表达式
登录成功,欢迎<%=username%>回来,这种格式就是jsp表达式
6,jsp的指令

  • 指令的作用是指导jsp的翻译引擎如何翻译jsp代码

  • jsp中共三个指令:
    page 页面指令
    include 包含指令
    taglib 标签库指令

  • 指令的语法格式:<%@指令名 属性名=属性值 属性名=属性值%>

  • 关于jsp中page指令,page指令中常用的属性

    • contentType 设置JSP的响应内容类型,同时在响应的内容类型后面也可以指定响应的字符编码方式
      <%@page contentType=”text/html;charset=utf-8”%>
      和<%@page contentType=”text/html” pageEncoding=”UTF-8”%>一样

    • pageEncoding 设置jsp响应时的字符编码方式

    • import 组织导入,导java类

    • session 设置当前jsp页面中是否可以直接使用session内置对象

      • session=”true”,表示在当前jsp中可以直接使用内置对象session,程序在执行的时候获取当前session会话对象,若获取不到则新建session对象
      • session=“false”,表示在当前jsp中不可以直接使用内置对象session,有时候并不想新建session,只是想获取当前session,就可以使用session=”false”,若想用session,可以自己创建一个
        HttpSession session = request.getSession(false),获取当前session,获取不到返回null
        若session属性不写,则默认session=”true”
    • errorPage 错误页面,当程序出错时,跳转到指定的错误页面,跳转使用转发技术,

    errorPage="/index4.jsp",路径不包括项目名
    • isErrorPage 是否是错误页面,如果为true,表示当前页面为错误页面,可以使用exception对象,exception引用指向了抛出的异常

    • isELIgnored 是否忽略EL表达式

  • include指令
    <%@include file=””%>, 导入其他jsp文件内容,include指令只有一个file属性,一个jsp文件可以使用多个include指令,include指令是静态联编,即两个文件组成一份java源代码

7,jsp的动作

  • 语法格式:

    <jsp:动作名 属性名=属性值 属性名=属性值></jsp:动作名>
  • 转发动作,达到页面转发技术效果

    <jsp:forward page="index2.jsp"></jsp:forward>
  • include动作,动态联编

    <jsp:include page="/index2.jsp"></jsp:include>

    与静态联编不同的是,动态联编是生成两个java文件,两个servlet对象,所以两个文件可以存在同名变量

EL表达式

  • 在EL表达式中,jsp四大域对象都有相应的别名
    application applicationScope
    session sessionScope
    request requestScope
    pageContext pageScope

  • EL表达式的作用:将作用域中的数据写到响应体中,即输出用的

  • 使用EL表达式的语法格式:${作用域.关键字}

  • 输出高级对象中的数据:
    ${作用域.user.name},前提,user类中一定要提供get,set方法

  • 简化版EL表达式:
    ${作用域.关键字}中的作用域可以省略,EL表达式会自己去域对象中挨个找数据
    查找顺序是从小到大的范围,先从pageScope中找,最后到applicationContext中查找

  • EL表达式中除了以上四种内置对象,还有以下内置对象

    • param
      使用:${param.请求参数名}
      作用:读取请求协议包参数内容,即读取表单数据
      代替:String value = request.getParameter(“请求参数名”);
      out.write(value);

    • paramValues
      使用:${paramValues.请求参数名}
      作用:读取请求协议包中关联多个值的请求参数,将参数内容保存到数组
      代替:String[] array = request.getParameterValues(“hobby”);

      表单提交的数据会被自动封装到request对象中,request对象中有map集合存储这些数据
      map集合的key是name,字符串类型,value是一个字符串类型的一维数组
      通过map集合的key获取value,适合取复选框数据
      例如:${paramValues.hobby[0]} //取爱好数组中第一个值

    • initParam
      使用:${initParam.共享数据名}
      代替:String value = application.getInitParameter(“driver”);
      out.write(value);

JSTL

标签的使用

  • <c:set>:
    作用:在jsp文件上设置域对象中共享的数据
    使用:<c:set scope=”session” var=”key” value=”10”/>
    代替:<% session.setAttribute(“key”,”10”); %>

    • 属性:scope:指定操作的域对象别名
    • var :指定域对象中的key
    • value:设置value值
  • <c:if>:
    作用:在jsp文件中控制哪些内容可以写到响应体中
    使用:

    <%
    	<c:if test="通过EL表达式进行判断">
    		内容
    	</c:if>
    %>
  • <c:choose>:
    作用:在jsp文件上实现多分支选择判断,决定哪一个内容能写到响应体
    使用:

    <c:choose>
    	<c:when test="EL表达式进行判断">内容1</c:when>
    	<c:when test="EL表达式进行判断">内容2</c:when>
    	<c:otherwise>内容3</c:otherwise>
    </c:choose>
  • <c:foreach>
    作用:循环遍历

    • 第一种使用方式:

      <c:foreach var="声明循环变量名称" begin="初始化循环变量" 
      end="循环变量可以接收的最大值" step="循环变量的递增值或递减值">
      	在jstl标签中,var变量被自动写入到pageContext中,
      	所以可以直接用EL表达式取值,${pageScope.i}或者${i}
      </c:foreach>
    • 第二种使用方式List集合:

      <c:foreach items="通过EL表达式获得的域对象集合" var="声明循环变量">
      	取值:${循环变量.对象属性名}
      </c:foreach>
    • 第三种使用方式Map集合:

      <c:foreach items="通过EL表达式获得的域对象集合" var="声明循环变量">
      	var变量代表Map集合的键值对,EntrySet
      	${var.key},代表map集合一个键值对的key值
      	${var.value.属性名}   代表map集合一个键值对的value值的属性值
      </c:foreach>

过滤器

  • 作用:
    一般用于完成通用的操作,如:登录验证,统一编码获取,敏感字符过滤

  • 执行流程,
    请求在访问服务器上的资源时,会先执行过滤器的dofilter方法,在请求返回时也要经过过滤器

      public void doFilter(ServletRequest servletRequest,
      ServletResponse servletResponse, FilterChain filterChain)  {
      	System.out.println("过滤器在此执行");
      	servletResponse.setContentType("text/html;charset=UTF-8");
      	//doFilter方法之前,对request进行操作
      	filterChain.doFilter(servletRequest,servletResponse);
      	//doFilter方法之后,对response进行操作
      	//也就是说,一个访问的请求和访问都会经过doFilter方法,doFilter方法执行完,
      	//代表一次访问结束
    }
  • 生命周期:

    • init方法:服务器启动时,tomcat会创建filter对象,并调用init方法,init方法里一般会加载资源
    • doFilter方法:每次请求都会被调用
    • destroy方法:服务器关闭时,filter对象被销毁,如果服务器是正常关闭,则会执行destroy方法,destroy方法一般会释放资源
  • 过滤器配置:

    • 拦截路径配置
      1,具体资源路径:/index.jsp 只有访问index.jsp资源时,过滤器才会被执行
      2,拦截目录:/user/* 访问/user下所有资源时,过滤器都会被执行
      3,后缀名拦截:*.jsp 访问所有后缀名为jsp资源时,过滤器都会被执行
      4,/* 访问项目所有资源都会执行拦截器
    • 拦截方式配置:资源被访问的方式:普通的请求或者服务器内部servlet之间的转发
      • 注解配置:
        @WebFiler中设置dispatcherTypes属性
        REQUEST,默认值,浏览器直接请求资源
        FORWARD,转发访问资源
        INCLUDE,包含访问资源
        ERROR,错误跳转资源
        ASYNC,异步访问资源
      • web.xml:
        filter-mapping标签中有dispatcher标签
  • 过滤器链(配置多个过滤器)

    • 执行顺序:如果有两个过滤器,过滤器1,过滤器2
      • 1,请求时,执行过滤器1,再执行过滤器2
      • 2,执行资源文件
      • 3,响应时,执行过滤器2,再执行过滤器1
    • 过滤器先后顺序问题:什么时候让过滤器1先执行,什么时候让过滤器2先执行呢?
      • 1,注解配置:按照字符串比较规则比较,值小的先执行
        如:AFilter和BFilter两个过滤器类名,则AFilter先执行
      • 2,web.xml配置:谁先定义,谁先执行

监听器Listener

概念:web三大组件之一
事件监听机制:

  • 事件:一件事情
  • 事件源:事件发生的地方
  • 监听器:一个对象
  • 注册监听:将事件源,事件,监听器绑定在一起,当事件源上发生某个事件后,执行监听器代码