JSP核心技术笔记

    • JSP运行原理
    • 基本语法
    • JSP指令
    • JSP动作元素
    • JSP隐含对象
      • request对象
      • response对象
      • out对象
      • session对象
      • application对象
      • config对象
      • pageContext 对象
      • page 对象
      • exception 对象
    • JSP作用域
    • EL表达式
      • EL运算符
      • EL隐藏对象
      • EL数据获取
    • JSTL标签库
      • 标签库引入
      • 标签使用
        • c:if标签
        • c:forEach标签
        • 3.2.3 c:choose标签
        • c:out标签

  JSP全称Java Server Pages,是一种动态网页开发技术,是javaEE核心规范之一。它使用JSP标签在HTML网页中插入Java代码。标签通常以<%开头以%>结束。
  JSP是一种Java servlet,主要用于实现Java web应用程序的用户界面部分。网页开发者们通过结合HTML代码、XHTML代码、XML元素以及嵌入JSP操作和命令来编写JSP。

JSP运行原理

JSP的工作模式是请求/响应模式,具体运行过程如下:

  1. 客户端发出请求,请求访问JSP文件。
  2. JSP容器先将JSP文件转换成一个Java源文件,在转换过程中,如果发现JSP文件中存在语法错误,则终端转换过程,并向服务器和客户端返回出错信息。
  3. 如果转换成功,则JSP容器将生成的Java源文件编译成字节码文件,Java会向普通的程序一样处理它。

接下来可以看看JSP的转化成果,我先写一个jsp文件,如下:
JSP核心技术笔记_第1张图片
当客户端访问该jsp文件时,容器会把该文件转换成java文件,然后被编译成class文件。

打开index_jsp.java文件:

/*
 * Generated by the Jasper component of Apache Tomcat
 * Version: Apache Tomcat/8.0.53
 * Generated at: 2019-10-09 13:55:40 UTC
 * Note: The last modified time of this file was set to
 *       the last modified time of the source file after
 *       generation to assist with modification tracking.
 */
package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;

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

  private static final javax.servlet.jsp.JspFactory _jspxFactory =
          javax.servlet.jsp.JspFactory.getDefaultFactory();

  private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;

  private static final java.util.Set<java.lang.String> _jspx_imports_packages;

  private static final java.util.Set<java.lang.String> _jspx_imports_classes;

  static {
    _jspx_imports_packages = new java.util.HashSet<>();
    _jspx_imports_packages.add("javax.servlet");
    _jspx_imports_packages.add("javax.servlet.http");
    _jspx_imports_packages.add("javax.servlet.jsp");
    _jspx_imports_classes = null;
  }

  private volatile javax.el.ExpressionFactory _el_expressionfactory;
  private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;

  public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
    return _jspx_dependants;
  }

  public java.util.Set<java.lang.String> getPackageImports() {
    return _jspx_imports_packages;
  }

  public java.util.Set<java.lang.String> getClassImports() {
    return _jspx_imports_classes;
  }

  public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
    if (_el_expressionfactory == null) {
      synchronized (this) {
        if (_el_expressionfactory == null) {
          _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
        }
      }
    }
    return _el_expressionfactory;
  }

  public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
    if (_jsp_instancemanager == null) {
      synchronized (this) {
        if (_jsp_instancemanager == null) {
          _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
        }
      }
    }
    return _jsp_instancemanager;
  }

  public void _jspInit() {
  }

  public void _jspDestroy() {
  }

  public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
        throws java.io.IOException, javax.servlet.ServletException {

final java.lang.String _jspx_method = request.getMethod();
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or HEAD");
return;
}

    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session = null;
    final javax.servlet.ServletContext application;
    final javax.servlet.ServletConfig config;
    javax.servlet.jsp.JspWriter out = null;
    final java.lang.Object page = this;
    javax.servlet.jsp.JspWriter _jspx_out = null;
    javax.servlet.jsp.PageContext _jspx_page_context = null;


    try {
      response.setContentType("text/html;charset=UTF-8");
      pageContext = _jspxFactory.getPageContext(this, request, response,
      			null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write("\n");
      out.write("\n");
      out.write("\n");
      out.write("  \n");
      out.write("    $Title$\n");
      out.write("  \n");
      out.write("  \n");
      out.write("  $END$\n");
      out.write("  \n");
      out.write("\n");
    } catch (java.lang.Throwable t) {
      if (!(t instanceof javax.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try {
            if (response.isCommitted()) {
              out.flush();
            } else {
              out.clearBuffer();
            }
          } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
        else throw new ServletException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}

我们发现该文件的继承关系

打开HttpJspBase,发现它是继承Servlet的

这也证明这是一个Servlet,接下来再看index_jsp.java,
JSP核心技术笔记_第2张图片
发现jsp文件中html的内容都是通过out.write(String str)方法输出的。

下面是jsp内置的隐藏对象,可以直接在jsp中使用。
JSP核心技术笔记_第3张图片

当将项目部署到tomcat下时,该jsp编译的Java源文件会存放于tomcat/work/Catalina目录下,当使用idea时,该文件在C盘-用户(user)-用户名-.IntelliJIdea下面。

基本语法

我们如何在jsp文件中写Java代码的?

  • JSP Scriptlets
    JSP Scriptlets时一段代码段,当需要使用Java实现一些复杂操作或控制时可以用它,JSP Scriptlets的语法格式如下所示:
<% java代码 %>

在JSP Scriptlets中声明的便令时jsp页面的局部变量,调用JSP Scriptlets时会为局部变量分配内存空间,调用结束后,释放局部变量占有的内存空间。

  • JSP声明语句
    jsp的声明语句用于声明便令和方法,其语法格式如下:
<%! 定义的变量或方法 %>

别声明的Java代码江别编译到Servet的_jspService()方法之外,即在jsp声明语句中定义的都是成员方法、成员变量、静态变量、静态代码块等,在jsp声明语句中声明的方法在整个给jsp页面内有效。

  • JSP表达式
    jsp表达式用于将程序数据输出到客户端,语法格式如下:
<%= expression %>
  • JSP注释
<%-- 注释信息 --%>

JSP指令

Page指令为容器提供当前页面的使用说明。一个JSP页面可以包含多个page指令。
Page指令的语法格式:

<%@ page attribute="value" %>

下表列出与Page指令相关的属性:

属性 描述
buffer 指定out对象使用缓冲区的大小
autoFlush 控制out对象的 缓存区
contentType 指定当前JSP页面的MIME类型和字符编码
errorPage 指定当JSP页面发生异常时需要转向的错误处理页面
isErrorPage 指定当前页面是否可以作为另一个JSP页面的错误处理页面
extends 指定servlet从哪一个类继承
import 导入要使用的Java类
info 定义JSP页面的描述信息
isThreadSafe 指定对JSP页面的访问是否为线程安全
language 定义JSP页面所用的脚本语言,默认是Java
session 指定JSP页面是否使用session
isELIgnored 指定是否执行EL表达式
isScriptingEnabled 确定脚本元素能否被使用
  • Include指令
    JSP可以通过include指令来包含其他文件。被包含的文件可以是JSP文件、HTML文件或文本文件。包含的文件就好像是该JSP文件的一部分,会被同时编译执行。
    Include指令的语法格式如下:
<%@ include file="文件相对 url 地址" %>
  • taglib指令
    JSP API允许用户自定义标签,一个自定义标签库就是自定义标签的集合。Taglib指令引入一个自定义标签集合的定义,包括库路径、自定义标签。
    Taglib指令的语法:
<%@ taglib uri="uri" prefix="prefixOfTag" %>

uri属性确定标签库的位置,prefix属性指定标签库的前缀。

JSP动作元素

与JSP指令元素不同的是,JSP动作元素在请求处理阶段起作用。JSP动作元素是用XML语法写成的。
利用JSP动作可以动态地插入文件、重用JavaBean组件、把用户重定向到另外的页面、为Java插件生成HTML代码。
动作元素只有一种语法,它符合XML标准:


动作元素基本上都是预定义的函数,JSP规范定义了一系列的标准动作,它用JSP作为前缀,可用的标准动作元素如下:

语法 描述
jsp:include 在页面被请求的时候引入一个文件。
jsp:useBean 寻找或者实例化一个JavaBean。
jsp:setProperty 设置JavaBean的属性。
jsp:getProperty 输出某个JavaBean的属性。
jsp:forward 把请求转到一个新的页面。
jsp:plugin 根据浏览器类型为Java插件生成OBJECT或EMBED标记。
jsp:element 定义动态XML元素
jsp:attribute 设置动态定义的XML元素属性。
jsp:body 设置动态定义的XML元素内容。
jsp:text 在JSP页面和文档中使用写入文本的模板

jsp:include动作元素用来包含静态和动态的文件。该动作把指定文件插入正在生成的页面。语法格式如下:


前面已经介绍过include指令,它是在JSP文件被转换成Servlet的时候引入文件,而这里的jsp:include动作不同,插入文件的时间是在页面被请求的时候。

以下是include动作相关的属性列表。

属性 描述
page 包含在页面中的相对URL地址。
flush 布尔属性,定义在包含资源前是否刷新缓存区。

以下我们定义了两个文件 date.jsp 和 main.jsp,代码如下所示:
date.jsp文件代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

今天的日期是: <%= (new java.util.Date()).toLocaleString()%>

main.jsp 文件代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




菜鸟教程(runoob.com)



include 动作实例

现在将以上两个文件放在服务器的根目录下,访问main.jsp文件。显示结果如下:

include 动作实例

今天的日期是: 2016-6-25 14:08:17

JSP隐含对象

JSP隐式对象是JSP容器为每个页面提供的Java对象,开发者可以直接使用它们而不用显式声明。JSP隐式对象也被称为预定义变量。

JSP所支持的九大隐式对象:

对象 描述
request HttpServletRequest 接口的实例
response HttpServletResponse 接口的实例
out JspWriter 类的实例,用于把结果输出至网页上
session HttpSession 类的实例
application ServletContext 类的实例,与应用上下文有关
config ServletConfig 类的实例
pageContext PageContext 类的实例,提供对JSP页面所有对象以及命名空间的访问
page 类似于Java类中的this关键字
Exception Exception 类的对象,代表发生错误的JSP页面中对应的异常对象

request对象

request对象是javax.servlet.http.HttpServletRequest 类的实例。每当客户端请求一个JSP页面时,JSP引擎就会制造一个新的request对象来代表这个请求。

request对象提供了一系列方法来获取HTTP头信息,cookies,HTTP方法等等。

response对象

response对象是javax.servlet.http.HttpServletResponse类的实例。当服务器创建request对象时会同时创建用于响应这个客户端的response对象。

response对象也定义了处理HTTP头模块的接口。通过这个对象,开发者们可以添加新的cookies,时间戳,HTTP状态码等等。

out对象

out对象是 javax.servlet.jsp.JspWriter 类的实例,用来在response对象中写入内容。

最初的JspWriter类对象根据页面是否有缓存来进行不同的实例化操作。可以在page指令中使用buffered='false’属性来轻松关闭缓存。

JspWriter类包含了大部分java.io.PrintWriter类中的方法。不过,JspWriter新增了一些专为处理缓存而设计的方法。还有就是,JspWriter类会抛出IOExceptions异常,而PrintWriter不会。

下表列出了我们将会用来输出boolean,char,int,double,String,object等类型数据的重要方法:

方法 描述
out.print(dataType dt) 输出Type类型的值
out.println(dataType dt) 输出Type类型的值然后换行
out.flush() 刷新输出流

session对象

session对象是 javax.servlet.http.HttpSession 类的实例。和Java Servlets中的session对象有一样的行为。
session对象用来跟踪在各个客户端请求间的会话。

application对象

application对象直接包装了servlet的ServletContext类的对象,是javax.servlet.ServletContext 类的实例。

这个对象在JSP页面的整个生命周期中都代表着这个JSP页面。这个对象在JSP页面初始化时被创建,随着jspDestroy()方法的调用而被移除。

通过向application中添加属性,则所有组成您web应用的JSP文件都能访问到这些属性。

config对象

config对象是 javax.servlet.ServletConfig 类的实例,直接包装了servlet的ServletConfig类的对象。

这个对象允许开发者访问Servlet或者JSP引擎的初始化参数,比如文件路径等。

以下是config对象的使用方法,不是很重要,所以不常用:

config.getServletName();

它返回包含在元素中的servlet名字,注意,元素在 WEB-INF\web.xml 文件中定义。

pageContext 对象

pageContext对象是javax.servlet.jsp.PageContext 类的实例,用来代表整个JSP页面。

这个对象主要用来访问页面信息,同时过滤掉大部分实现细节。

这个对象存储了request对象和response对象的引用。application对象,config对象,session对象,out对象可以通过访问这个对象的属性来导出。

pageContext对象也包含了传给JSP页面的指令信息,包括缓存信息,ErrorPage URL,页面scope等。

PageContext类定义了一些字段,包括PAGE_SCOPE,REQUEST_SCOPE,SESSION_SCOPE, APPLICATION_SCOPE。它也提供了40余种方法,有一半继承自javax.servlet.jsp.JspContext 类。

其中一个重要的方法就是removeArribute(),它可接受一个或两个参数。比如,pageContext.removeArribute(“attrName”)移除四个scope中相关属性,但是下面这种方法只移除特定scope中的相关属性:

pageContext.removeAttribute("attrName", PAGE_SCOPE);

page 对象

这个对象就是页面实例的引用。它可以被看做是整个JSP页面的代表。

page 对象就是this对象的同义词。

exception 对象

exception 对象包装了从先前页面中抛出的异常信息。它通常被用来产生对出错条件的适当响应。

JSP作用域

JSP四大作用域:page(作用范围最小)、request、session、application(作用范围最大)

  • 存储在application对象中的属性可以被同一个WEB应用程序中的所有Servlet和JSP页面访问。
  • 存储在session对象中的属性可以被属于同一会话(浏览器打开直到关闭称为一次会话,且在此期间会话不失效,生命周期默认30分钟,也可以自行定义)的所有Servlet和JSP页面访问。
  • 存储在request对象中的属性可以被属于同一个请求的所有Servlet和JSP页面访问(在有转发的情况下可以跨页面获取属性值),例如使用PageContext.forward和PageContext.include方法连接起来的多个Servlet和JSP页面。
  • 存储在pageContext对象中的属性仅可以被当前JSP页面的当前响应过程中调用的各个组件访问,例如,正在响应当前请求的JSP页面和它调用的各个自定义标签类。

EL表达式

JSP2.0规范中提供了EL表达式,它是一种简单的数据访问语言,用于简化JSP文件的书写。格式:${代码块}

EL运算符

算术运算符 说明 示例 结果
+ ${1 + 1} 2
- ${2 - 1} 1
* ${2 * 3} 6
/ ${5 / 2} 2.5
% 取模 ${5 % 2} 1
逻辑运算符 说明 示例 结果
== 等于 ${1 == 1} true
!= 不等于 ${1 != 1} false
< 小于 ${1 < 1} false
<= 小于等于 ${1 <=1 } true
> 大于 ${ 1>1 } false
>= 大于等于 ${ 1>=1 } true
关系运算符 说明 示例 结果
&& ${true && false} false
|| ${true || false} true
${! false} true

三元运算

${a < b ? "true" : "false"}

empty (比较对象是否为null;字符串是否为“ ”;集合长度是否为0)

${empty user}
${not empty user}

EL隐藏对象

在EL表达式中,无需创建就可以使用的对象称为EL隐藏对象,在EL中一共有11个隐藏对象,分别是:
pageScope requestScope sessionScope applicationScope

header headerValues

param paramValues

pageContext

initParam

cookie

EL数据获取

字符串

<%--定义字符串s,并将其放入pageContext域中--%>
<%
	String s = "helloWorld";
	pageContext.setAttribute("s"; s);
%>

<%--从域中获取s,第二种写法可在pageScope,requestScope sessionScope applicationScope查找,直到找到为止--%>
${pageScope.s}或者${s}

数组

<%
	String[] arr = {"a","b","c","d"}
	pageContext.setAttribute("arr"; arr);
%>
${arr}
${arr[0]}

集合

<%
	List<String> list = new ArrayList<>();
	list.put("a");
	list.put("b");
	pageContext.setAttribute("list"; list);
%>
${list}
${list[0]}

map

<%
	Map<String, String> map = new HashMap<>();
	map.put("a", "a");
	map.put("b", "b");
	map.put("c","c");
	pageContext.setAttribute("map"; map);
%>

${map}
${map.a}

JSTL标签库

  JSTL(Java server pages standarded tag library,即JSP标准标签库)是由[JCP](Java community Proces)所制定的标准规范,它主要提供给Java Web开发人员一个标准通用的标签库,并由Apache的Jakarta小组来维护。开发人员可以利用这些标签取代JSP页面上的Java代码,从而提高程序的可读性,降低程序的维护难度。

JSTL提供了5个子库:

标签库 uri 前缀
core http://java.sun.com/jsp/jstl/core c
i18n http://java.sun.com/jsp/jstl/fmt fmt
sql http://java.sun.com/jsp/jstl/sql sql
xml http://java.sun.com/jsp/jstl/xml x
functions http://java.sun.com/jsp/jstl/functions fm

标签库引入

若要在JSP中使用JSTL标签库,则需要引入相应的jar包,接下来以maven的方式引入

<dependency>
    <groupId>jstlgroupId>
    <artifactId>jstlartifactId>
    <version>1.2version>
dependency>
<dependency>
    <groupId>taglibsgroupId>
    <artifactId>standardartifactId>
    <version>1.1.2version>
dependency>

下面就尝试使用targlib指令导入标签库,例如导入核心标签库,其它也是类似。

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

标签使用

c:if标签

<c:if test="${salary > 2000}" var="flag" scope="session">
   <p>我的工资为: <c:out value="${salary}"/><p>
</c:if>
<c:if test="${not flag}">
   <p>我的工资为: <c:out value="${salary}"/><p>
</c:if>

c:forEach标签

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>c:forEach 标签实例title>
head>
<body>
 <%
   String[] str={"1","2","3","4","5","6","7"}; 
   request.setAttribute("str",str);
 %>
   <c:forEach items="${str}" var="s" begin="1" end="5">
        <c:out value="${s}">c:out><br>
   c:forEach>
body>
html>

3.2.3 c:choose标签

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>c:choose 标签实例title>
head>
<body>
<c:set var="salary" scope="session" value="${2000*2}"/>
<p>你的工资为 : <c:out value="${salary}"/>p>
<c:choose>
    <c:when test="${salary <= 0}">
       太惨了。
    c:when>
    <c:when test="${salary > 1000}">
       不错的薪水,还能生活。
    c:when>
    <c:otherwise>
        什么都没有。
    c:otherwise>
c:choose>
body>
html>

c:out标签

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>c:out 标签实例title>
head>
<body>
    <h1><c:out> 实例h1>
        <c:out value="<要显示的数据对象(未使用转义字符)>" escapeXml="true" default="默认值">c:out><br/>
          <c:out value="<要显示的数据对象(使用转义字符)>" escapeXml="false" default="默认值">c:out><br/>
    <c:out value="${null}" escapeXml="false">使用的表达式结果为null,则输出该默认值c:out><br/>
body>
html>

你可能感兴趣的:(Java,Web)