• web概述13


    Jsp

    java server page,实际上是针对Servlet生成网页比较麻烦,而且不能达到所见即所得的开发引入的新技术。就是Servlet生成网页的简化写法。究其本质实际上就是Servlet

    基础语法

    jsp页面在执行时会自动进行2次编译,首先jsp引擎对调用的jsp页面进行编译,将jsp页面转换为servlet类,然后应用servlet引用对生成的servlet类进行编译,生成对应的字节码文件,最后调用字节码文件,
    执行生命周期方法生成html文档作为响应

    原始文件test.jsp

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>首页</title>
    </head>
    <body>
    index.html
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    访问后则自动在work目录下生成test_jsp.java文件

    /*
    * Generated by the Jasper component of Apache Tomcat
    * Version: Apache Tomcat/9.0.68
    * Generated at: 2022-11-08 03:19:04 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 test_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(getServ
    letConfig());
    }
    }
    }
    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 {
    if
    (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
    final java.lang.String _jspx_method = request.getMethod();
    if ("OPTIONS".equals(_jspx_method)) {
    response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
    return;
    }
    if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) &&
    !"HEAD".equals(_jspx_method)) {
    response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
    response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP
    只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
    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");
    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("\r\n"); //静态页面部分--模板部分内容,自动生成
    out.write按照原样输出
    out.write("\r\n");
    out.write("\r\n");
    out.write("\r\n");
    out.write("馕页\r\n");
    out.write("\r\n");
    out.write("\r\n");
    out.write("index.html\r\n");
    out.write("\r\n");
    out.write("");
    } 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);
    }
    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136

    还可以看到一个test_jsp.class文件,这是test_jsp.java编译生成的字节码文件。这里强调的是jsp执行时是2次编译
    在这里插入图片描述

    注释

    jsp中的注释有html注释和jsp注释两种
    html注释: ,这里需要注意的是:html注释中的jsp语法仍旧会正常解析执行,只是不在页面中显示而已

    jsp页面代码

    <!-- 现在时间为<%=new Date().toLocaleString()%> -->
    
    • 1

    实际执行结果为
    注意:html注释内容jsp解析器仍旧会解析执行,所以不能出现jsp语法错误 HTTP ERROR 500
    javax.servlet.ServletException:
    jsp注释: <%-- 多行语句 --%> 。jsp注释会被jsp解析器所忽略

    页面组成

    包括html标签组成的静态模板部分【按照原样输出】和jsp语法
    语法1: <%=表达式%> , 在当前位置输出表达式的计算结果。注意表达式不是合法的java语句,所以不能以分号收尾。jsp编译器编译后 out.print(表达式) ,也就是说允许出现在()中的内容才能出现在表达式的位置。

    jsp页面中的内容
    <%=new java.util.Date()%>
    ---
    编译后的java文件中格式为:
    out.print(new java.util.Date());
    
    • 1
    • 2
    • 3
    • 4
    • 5

    语法2: <%合法的java代码块;%> ,编译后对应的是service【jspService】方法中的一段代码,允许出现在方法中的代码就是这里允许出现的代码

    <%
    String path = request.getContextPath(); 获取请求上下文,例如/test
    String basePath = request.getScheme()获取请求协议名称,例如http +
    "://"+request.getServerName()获取服务器名称,例如localhost + ":" +
    request.getServerPort()获取请求服务器的端口号 + path + "/"; 实际返回值为http://localhost:8080/test/
    %>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    jsp页面中的内容

    <%
    java.util.Random r=new java.util.Random();
    out.println(r.nextInt(10)); // 在jsp代码块中可以直接使用9大默认对象
    %>
    
    • 1
    • 2
    • 3
    • 4

    生成的java代码
    在 public void _jspService(final javax.servlet.http.HttpServletRequest request,final javax.servlet.http.HttpServletResponse response)throws java.io.IOException,javax.servlet.ServletException { 方法中会多出部分内容

    java.util.Random r=new java.util.Random();
    out.println(r.nextInt(10));
    
    • 1
    • 2

    为什么在代码块中可以直接使用9大默认对象

    public void _jspService(final javax.servlet.http.HttpServletRequest request,
    final javax.servlet.http.HttpServletResponse response) throws
    java.io.IOException, javax.servlet.ServletException { request和response是服
    务器调用时自动传入的
    ... ...
    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;
    // jsp引擎生成的java代码块中自动添加了生成获取9大默认对象的方法
    try {
    response.setContentType("text/html");
    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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    语法3: <%! 合法的java代码块; %> 编译后对应的是当前类内,所有方法之外的部分。这里可以定义属性、方法。这里的限制是没有9大默认对象,如果需要使用默认对象,应该作为参数进行传递

    <%!
    // 定义成员方法
    public String getError(HttpServletRequest request,String key){
    String res="";
    Object obj=request.getAttribute("errors");
    if(obj!=null && obj instanceof Map){
    Map<String,String> errs=(Map<String,String>)obj;
    if(errs.containsKey(key))
    res=errs.get(key);
    }
    return res;
    }
    %>
    调用<%=getError(request,key)%>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    jsp页面中的内容

    <%!
    private int count=0;
    public String pp(){
    System.out.println(count);
    return ""+count;
    }
    %>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    生成的java代码

    public final class test_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
    org.apache.jasper.runtime.JspSourceImports {
    //声明部分对应的编译结果为:当前类内,所有方法之外
    private int count=0;
    public String pp(){
    System.out.println(count);
    return ""+count;
    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    jsp页面的三生命周期
    jsp页面在第一次访问时会编译生成一个Servlet类文件

    public final class test_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
    org.apache.jasper.runtime.JspSourceImports {
    
    • 1
    • 2
    • 3

    其中包含3生命周期方法

    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;
    }
    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    3大页面指令

    page指令

    用于配置页面全局属性
    语法: <%@ page 属性名称=“值”%>
    相关属性

    • language="java"用于设定当前页面种所使用的脚本语言,目前属性值只有一个java,所以配置了值为java,不配置默认值也是java
    • import="java.util." 用于导入所需要的引用依赖,这个属性允许出现多次,可以导入一个类,也可以一次性导入导入 import java.util.,java.io.*
    • pageEncoding和contentType可以相互替代
      • pageEncoding="GBK"语义是设置当前页面的编码字符集,但是实际上没有设定contentType则是设定了默认编码字符集,等价于contentType=“text/html;charset=GBK”
      • contentType语义是设定当前页面的响应内容类型,基本格式为
        contentType=“text/html;charset=GBK” ,和pageEncncoding可以相互替代

    6大页面动作

    9大默认对象

    request用于封装用户请求,是HttpServletRequest类型
    response用于封装服务器响应信息
    out用于向客户端输出文档信息

    数据的4大范围

    传递数据的范围实际上有4种: page < request < session < application ,一般范围的选择依据为:满足需求,越小越好

    • page只能在当前页面的范围内有效
    • request在当前页面有效,如果请求转发,则当前页和转发跳转的目标页有效
    • session用于跟踪用户,在用户访问当前应用的所有页面上有效
    • application用于跨用户数据共享,在当前应用的范围内有效
  • 相关阅读:
    《YOLOv5:从入门到实战》报错解决 & 专栏答疑
    LeetCode 73. 矩阵置零(java实现)
    工业线上赛(2022省赛)
    威联通NAS进阶玩法之使用Docker搭建个人博客教程
    Linux下的多线程编程:原理、工具及应用(2)
    SpringMVC(Rest+映射请求数据+模型数据+视图和视图解析器)
    R语言统计与绘图:生存率的比较
    SpringBoot
    JAVA算法练习(10):绳圈
    为什么我在领英上搜到的客户都是显示领英会员(Linkedin Member)?
  • 原文地址:https://blog.csdn.net/weixin_44251806/article/details/127756674