欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JSP页面 - 学习1

程序员文章站 2022-05-19 16:13:51
...

Servlet的替代品

1. JSP

JSP编译后的Java文件在: Tomcat目录\work\Catalina\localhost

1.1 概念、执行原理、基本结构

JSP( Java Server Page ): Java服务端页面 – 最终编译依然为Servlet

HTML、JSP区别:

  1. HTML只能使用静态数据、显示静态页面
  2. JSP源码:大量HTML + 少量Java代码 → 提供动态数据


1.1.1 执行原理图

根据流程图可知JSP比Servlet运行效率是低的

     ① 执行流程图 - 服务器没有该JSP的二进制class文件时

JSP页面 - 学习1


     ② JSP文件执行流程图 - 服务器已经存有该JSP的二进制class文件时

JSP页面 - 学习1



     可看到JSP文件 →最终编译成Servlet.Java文件

JSP页面 - 学习1
JSP页面 - 学习1

1.1.2 基本结构
JSP页面结构
非JSP元素 → 任何文本
JSP元素
脚本元素
指令元素
动作元素


1.2 三种JSP元素

1.2.1 脚本元素
脚本元素
脚本:<% %>
在成员方法Servlce()内写逻辑代码
表达式:<%= %>
页面内容输出-打印语句 -- 可进行简单逻辑运行结果输出、调用具有返回值的方法
声明:<%! %>
成为当前页面Servlet的属性、类方法
注释:<%-- --%>
注意:不会出现在客户端页面源码中

JSP变量
声明变量:<%! %>
脚本变量:<% %>
Servlet中的_jspService()方法中的局部变量
成为Servlet的成员属性

JSP页面 - 学习1
JSP页面 - 学习1


  1. 代码示例 - <% %>

<body>
    
    <h1>你好,小老弟</h1>
     <%-- <% if(5 != 0) { --%>        
     
     <% if(5 > 0) {  %>
           <h1>嗯,你好</h1>
     <%  } else { %>
           <h1>好个锤子</h1>
     <% } %>

</body>


  2. 代码示例 - <%= %>

<body>  
   <%= "Hello World" %>      
</body>


  3. 代码示例 - <%! %>

<body>  
    <%! Integer a %>
    <%= a %>                   // 页面输出:  null
    
    <%! 
        public String getStr() {
                return "牛脾"
        }
    %>
    <%= getStr() %>          // 页面输出: 牛脾
    
</body>

1.2.2 指令元素

此元素为JSP引擎(Servlet容器)设计的,不会产生任何输出,只告诉JSP引擎如何处理其他页面其他部分

指令有多种属性类型、可以分开写、也可以写在一行指令上

语法:<%@ 指令类型 属性名=“值” %>

指令元素
<%@ page %>
页面编码设置、Java类导入、JSP文件编码、异常页面设置、是否可以用Exception
<%@ include %>
静态引入页面内容(JSP、HTML)、先将包含文件与当前JSP融合,在进行Java编译 → 不能定义同名变量
<%@ taglib %>
引入标签库(由Java编写)
引入格式:<%@ tablib uri='标签库uri' prefix='标签前缀' %>

JSP页面 - 学习1


  代码示例:<%@ page %>

<%@ page language="java" ContentType="text/html; charset=utf-8" import="java.util.Data" pageEncoding="utf-8" %> 


  代码示例:<%@ include %>

<%@ include file="文件地址" %> 



  代码示例:<%@ taglib %>

// 引入标签库
<%@ taglib uri="tld文件对应的uri识别字符串" prefix="前缀名" %>

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


// 使用标签库标签
<前缀名:标签   属性="属性值"  />

<c:out value="兄弟们胸哭" />


1.2.3 动作元素

背景:JSP是视图页面、尽量在JSP使用少的逻辑的代码,而Sun公司,为了减少逻辑代码(Java代码),而开发了具有逻辑功能的标签

动作元素
动态引入包含:引入静态、动态页面
包含的是普通文件,无需服务器处理,直接发给客户端显示
包含JSP文件,发给服务器进行处理,再发给客户端显示
完全等价于表单的input元素 - request传参
请求分派
写Class时必须完全限定名
等于于 <%= Bean对象.get属性名( ) %>

示例代码
//  将该相对路径?name1=value1 合并到   当前JSP文件
<jsp:include page="相对路径" flush="true">
    <jsp:param name="name1" value=""value1"></jsp:param>
</jsp:include>


// 请求分派到  相对路径?name1=value1 
<jsp:forward page="相对路径" flush="true">
    <jsp:param name="name1" value=""value1"></jsp:param>
</jsp:include>


// 实例化一个JvaBean对象,修改,并且输出属性到页面中
<jsp:useBean id="student1" class="top.linruchang.TestServlet.Student">
           <jsp:setProperty property="name" value="lrc" name="student1"</jsp:setProperty>
           <jsp:getProperty property="name" name="student1"></jsp:getProperty>
 </jsp:useBean>

<%-- 上下两段语句是一样的 --%>

<%@ page import="top.linruchang.TestServlet.Student" %>
     <%  
            Student student1 = new Student(); 
            student1.setName("lrc");
     %>
 <%=  student1.getName() %> 
1.2.3.1 <jsp: include page=“相对文件路径” >

实质就是:request.getRequestDispatcher( page路径 ).include( request, response )

  Test.jsp

<body>
	
    <%--  
        <jsp:include page="./Test2.jsp" flush="true">
		        <jsp:param name="number" value="10"></jsp:param>
        </jsp:include> 
    --%>
	
    <%-- 上下两个语句的作用是一模一样的,自行测试 --%>
    
	 <%
		request.getRequestDispatcher("./Test2.jsp?number=10").include(request, response);
	%>
   
   <br>
    
	你好
</body>

  Test2.jsp

<body>
     <%
           String n = request.getParameter("number");
           Integer count = Integer.valueOf(n);
     %>
     HttpServletRequest
     Test传入的数字:<%= count %>
</body>


  运行结果图
JSP页面 - 学习1

1. <% jsp:Include>原理解析 - 查看Test_jsp.class反编译源码

//  <% jsp:Include> 等价于 下面的函数
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "./Test2.jsp" + "?" + org.apache.jasper.runtime.JspRuntimeLibrary.URLEncode("number", request.getCharacterEncoding())+ "=" + org.apache.jasper.runtime.JspRuntimeLibrary.URLEncode("10", request.getCharacterEncoding()), out, true);


// .JspRuntimeLibrary.include ()   第三个参数等于 ./Test2.jsp?number=10

// 上面一大串等价于下面这条语句
JspRuntimeLibrary.include(request, response, "./Test2.jsp?number=10", out, true);

2. 查看JspRuntimeLibrary.include()函数源码
JSP页面 - 学习1

1.3 内置对象

JSP页面 - 学习1

1.3.1 四大作用域对象

注意:
1. session:存储用户状态
2. request:页面之间传递、交换信息 – 利用请求分派

作用域对象 - Map对象
page:保存page域的属性 - 即是JSP → Servlet自身即this,Object类型,实际压根不用
request:保存请求域的属性
session:保存会话域的属性
application:保存当前项目公用域的属性 - 只有容器关闭才会被销毁
1.3.2 其他内置对象
其他对象
out:输出流、等价于printWriter对象
response:等价于HttpServletResponse对象
pageContext:当前JSP页面的相关信息、获取八大内置隐藏对象以及属性
config:JSP页面配置信息 -- 等价于当前页面的ServletConfig
exception:当前JSP页面中的异常处理 - 使用须设置<% page isErrorPage='true' %>
PageContext
get内置对象() --- 获取八大内置对象
操纵四大范围属性
getAttribute(属性名, 范围指示数)
setAttribute(属性名, 属性值, 范围指示数)
removeAttribute(属性名, 范围指示数)
范围指示符 - PageContext类内的静态常量属性
1=PAGE_SCOPE
2=REQUEST_SCOPE
3=SESSION_SCOPE
4=APPLICATION_SCOPE

代码示例 - 注意使用pageContext内置对象获取、修改属性时必须传入范围指示符的实参
<body>
     <%
           request.setAttribute("year", "request2019");
     %>
       
      <%--下面两条语是一样的 --%>
     <%= pageContext.getAttribute("year", 2) %>
     <%= pageContext.getAttribute("year", PageContext.REQUEST_SCOPE) %>
</body>

2. EL表达式 - 只能写单条语句

2.1 基本使用

EL: Expression Language

书写基本语法: ${ 表达式 } → 返回空时为空字符串

背景: 用于替换JSP页面的脚本表达式


作用
1. 检索四大作用域对象中的属性数据:page、request、session、Web(application)
2. 访问JavaBean(信使)、数组、容器、map
3. 可以执行基本的运算
含有隐式对象,轻松获得对象数据
可自定义EL函数 → 调用Java类的方法


  查找属性,先从最近的作用域开始查找,查找不到才向下继续查找

查找
查找
查找
查找
${属性名}
pageScope作用域
requestScope作用域
sessionScope作用域
applicationScope作用域

2.2 隐含对象 - Map类型

value → String[]对象
value - String[]对象
11大EL隐含对象
作用域对象 - Map对象
pageScope:保存page域的属性
requestScope:保存请求域的属性
sessionScope:保存会话域的属性
applicationScope:保存公用域的属性
其他对象 - Map对象
pageContext
param - 请求参数对象
paramValues - 请求参数值
header - 请求字段对象
headerValues - 请求求的字段值
cookie - 所有Cookie
initParam - web应用初始化参数

2.3 代码示例

  1. 语法规范

// 不可进行字符串的拼接
${ "a" + "b" }



$ { 属性名 }     // 直接寻找四大范围,从page → application四大范围的属性


// 这四大是等价的 -- 任何一种写法都可以
${ 属性名 } 
${ 四大范围.属性名 } 
${ 四大范围["属性名"] }  
${ 四大属性.get( "属性名" ) }



// 等价于 printWriter.print( String )   
//          printWriter.print( 2+3 )
//          printWriter.print( 2> 3)
$ { "字符串" }   
$ { 2+3 }
$ { 2>3 }


// 对象是否为 null 或者 ""空字符
<% String a = ""; %>
<% String b; %>
${ empty a }
${ empty b }
// 上面两个语句都浏览器页面中输出   true


  2. param、paramValues两EL内置对象区别

  Test.jsp页面代码

<%@ page import="java.util.Arrays" %>
<body>
     ${ param.a }
     <br>     
     ${ Arrays.toString(paramValues.a) }
</body>


  效果图

JSP页面 - 学习1