JSP页面 - 学习1

165 阅读3分钟

文章目录

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文件时

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YkDLGK8g-1572857649725)(en-resource://database/7515:1)]


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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PDrBkY9z-1572857649740)(en-resource://database/7517:1)]



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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tFAAUv3j-1572857649753)(en-resource://database/7523:1)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jw274ug1-1572857649754)(en-resource://database/7521:1)]

1.1.2 基本结构


1.2 三种JSP元素

1.2.1 脚本元素

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AHODsCG7-1572857649770)(en-resource://database/7905:1)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XKxUPvbI-1572857649777)(en-resource://database/7907: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引擎如何处理其他页面其他部分

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

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OCvQ151u-1572857649782)(en-resource://database/7909: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代码),而开发了具有逻辑功能的标签

示例代码
//  将该相对路径?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>


运行结果图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wMXFcou1-1572857649794)(en-resource://database/8029: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()函数源码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j670ainN-1572857649802)(en-resource://database/8031:1)]

1.3 内置对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zVil85o2-1572857649809)(en-resource://database/8037:1)]

1.3.1 四大作用域对象

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

1.3.2 其他内置对象

代码示例 - 注意使用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页面的脚本表达式



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

2.2 隐含对象 - Map类型

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>


效果图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Sx9SUa7L-1572857649813)(en-resource://database/8141:1)]