概念
Java Server Pages: java服务器端页面
它由Java的原公司’sun’开发.跟java属于亲兄弟
可以理解为:能够一个特殊的页面(.jsp文件)上,不仅可以写html代码,又可以写java代码,当访问该jsp文件时,就会运行其文件中包含java代码以及html代码的部分.
它是一个能够当作网页用,并具有servlet功能(服务器功能)的东西.
目的:用于简化书写!!!
原理
一.如果web模块下存在名为’index.jsp’的文件,将会转换为java文件(index_jsp.java),并输出在临时目录(C:\Users\1.IntelliJIdea2018.2\system\tomcat_basic-code\work\Catalina\localhost\ROOT\org\apache\jsp)
二.将该java文件转换为字节码文件(index_jas.calss)并输出在该临时目录下
三.在web项目启动时,加载该字节码文件(index_jsp.class)
注意:其中,java文件(index_jps.java)不仅仅包含你在jsp文件中写的java代码,还有一些自带的成员方法和变量.
JSP文件中,你输入的JAVA代码是会定位在其被转换的’index_jsp.java"文件中,而且是依照你(定义)方式不同而位置不同
注意:
一.一个jsp页面中可以存在多个不同定义方式,且可以存在多个重复的定义方式(称之为标签截断)
二.定义格式可以被html标签包围
格式:<% JAVA代码 %>
列如:
<%
System.out.println("我是在jsp页面被运行的哦~");
%>
对于该格式的’<%'和"%>'内所写的代码,在WEB项目启动将其转换为java文件(index_jsp.java)时,会对应到其java文件(index_jsp.java)内的’jspService"方法内.
在该种格式下,你能在写什么样的代码,要取决于该’jspService’方法内能写什么样的代码
比如,jspService方法内有个’out’对象(用于输出语句),那么我们就可以拿来用在’<% %>'中用
格式:<%! JAVA代码 %>
列如:
<%!
int variable = 5;
%>
该方式种的代码,同样是对应java文件中的代码,它的位置在成员变量或者成员方法.
也就是说,该方式内的JAVA代码,多为变量或方法,但用得不多
格式:<%= 欲输出的字符 %>
列如:
<%=
"你好~,变量'variable'的数值为"+variable
%>
该方式用于向页面输出内容,可以是自己自定义的字符串,也可以将整个jsp页面中存在的变量作为内容输出.
指令用于配置当前JS页面的,作用类似于’web.xml’中的标签所带来的作用.
使用方法:在jsp文件的最上方定义(如果存在其它指令,不分先后顺序).
page指令的定义格式<%@ page 属性名1="属性值1" 属性名2="属性值2" 等更多的属性值和其名称 %>
当前页面发生异常后,会自动跳转到指定的错误页面
格式:<%@ page errorPage="错误页面的相对路径" %>
列如:
<%@ page contentType="text/html;charset=UTF-8" errorPage="erro.jsp" language="java" %>
用于标识当前页面是否为错误页面。
如果值为’false’,则视作正常页面,如果为’true’则视作错误页面,默认值为false
注意:
一.仅仅用于标识是否为错误页面,
二.如果存在'erro'属性,但没有异常代码存在,那也不会因为isErroePage属性为true的存在而跳转.
格式:<%@ page isErrorPage="属性值" %>
列如:
<%@ page contentType="text/html;charset=UTF-8" errorPage="erro.jsp" isErrorPage="true" language="java" %>
import属性用于导包,具体格式目前还不清楚,日后补充.
该属性等同于response.setContentType()
<%@ page contentType="mime类型/编码名称" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
使用方法:在jsp文件的最上方定义(如果存在其它指令,不分先后顺序)
用途: 导入其它jps文件的资源文件,跟css或者js中的导入概念一样,不常用
它只有一个属性,那就是’file’,用于指向某个jsp文件的相对路径
格式:<%@include file="其它jsp文件的相对路径"%>
列如:
<%@include file="top.jsp"%>
使用方法:
1.导入jay包,分别为’javax.servlet.jsp.jstl.jar’,和’jstl-impl.jar’
2.在jsp文件的最上方定义(如果存在其它指令,不分先后顺序)
用途:用来导入Sun公司为其提供的代码标签库'JSTL', JSTL标签库可以用来干嘛呢?JSTL标签库中包含一些if,for循环这样的流程控制资源(语句),这可以用来进行MVC开发
.
使用步骤一:定义指令
定义格式:<%@ taglib prefix="自定义资源前缀名" uri="自定义sun公司给出的资源引用链接" %>
列如:
* <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
使用步骤二:选择,并定义JSTL提供的标签资源
格式:<自定义资源前缀名:对应的标签资源> 标签体 自定义资源前缀名:对应的标签资源>
列如:
<c:catch>
</c:catch>
注意:是’uri’,不是’url’
用于指向sun公司提供的jsp资源链接,常用的资源链接为:http://java.sun.com/jsp/jstl/core
在概念中我提到过,jsp具有’servlet功能(服务器功能)’.
这是因为它的java文件(index_jsp.java)继承了’HttpJspBase’.
因此,HttpJspBase的一些方法,被该java文件继承了下面.
这也就存在了"内置对象"
比如Servlet的’request’对象和’response’对象.
也就是说在jsp页面中不需要获取和创建,可以直接使用的对象
jsp一共有9个内置对象。
内置有request对象,和平时使用没区别
内置有response对象,和平时使用没区别
out为字符输出流对象。可以将数据输出到页面上。和response.getWriter()类似
格式:out.write(String字符串内容);
列如:
<%
System.out.println("我是在jsp页面被运行的哦~");
String servletPath = request.getServletPath();
out.write(servletPath);
%>
response.getWriter()和out.write()的区别:
无论代码的先后顺序,response.getWriter()的数据输出永远在out.write()之前
建议用out替代response对象的输出功能
原因:在tomcat服务器真正给客户端做出响应之前,会先找response缓冲区数据,再找out缓冲区数据。
用于在当前页面的共享数据,还可以获取其他八个内置对象
步骤一:设置当前JSP页面的数据共享(在共享发起处)
格式:pageContext.setAttribute("自定义数据共享名",自定义任意类型的共享数据);
步骤二:获取当前JSP页面的数据共享(在共享获取处)
格式:Object 自定义共享结果接收名 = pageContext.getAttribute("欲获取的数据共享名");
列如:
<%
// pageContext 设置当前JSP页面的数据共享
pageContext.setAttribute("param","你好~" );
%>
<%
// pageContext 获取当前JSP页面的数据共享
String param = (String) pageContext.getAttribute("param");
System.out.println(param);
%>
作用于一次会话的多个请求间
步骤一:设置共享内容并发送
格式:session.setAttribute("自定义数据共享名",自定义任意类型的共享数据);
步骤二:获取共享内容
格式:Object 自定义共享结果接收名 = session.getAttribute("欲获取的数据共享名");
列如:
<body> <!-- 内置对象 -->
<%
session.setAttribute("中国","hello~" );
%>
</body>
<%
String param = (String) session.getAttribute("中国");
System.out.println(param);
%>
application内置对象的真实类型是ServletContext
,也就是说,它的本质就是’ServletContext
'
作用于所有用户间共享数据
步骤一:设置共享内容并发送
格式:application.setAttribute("自定义数据共享名",自定义任意类型的共享数据);
步骤二:获取共享内容
格式:Object 自定义共享结果接收名 = application.getAttribute("欲获取的数据共享名");
列如:
<body> <!-- 内置对象 -->
<%
application.setAttribute("测试","12121212" );
%>
</body>
<%
String param = (String) application.getAttribute("测试");
System.out.println(param);
%>
page内置对象的真实类型为Object,用于当前页面(也就是Servlet对象,因为Jsp的本质就是Servlet)的对象 ,它相当于java语法中的’this’
它的真实类型是ServletConfig,也就是说它是Servlet的配置对象,
相当于Servlet的’getServletConfig’方法(获取Servlet的配置).
config 对象代表当前JSP 配置信息,常用的方法为’getServletName’(获取JSP配置信息)
格式:String 自定义配置信息结果接收名 = config.getServletName();
列如:
String servletName = config.getServletName();
System.out.println(servletName);
它的真实类型为Throwable,属于异常对象
使用条件:只有当'page'指令存在属性'isErrorPage',且该属性值为'true'时才可以使用.
目标:将原本Java文件中的Cookie案例代码,放在jsp文件中,用jsp文件去运行,并将在JSP文件中添加一个文本框,达到’前端代码与后端代码都放在一个jsp文件中去实现’的目的.
并将输出语句的’response.write()'方法由’out.write()'去替代.
<%@ page import="java.net.URLDecoder" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="java.util.Date" %>
<%@ page import="java.net.URLEncoder" %><%--
Created by IntelliJ IDEA.
User: 1
Date: 2020/2/21
Time: 1:36
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<%
System.out.println("已经触发");
Cookie[] cookies = request.getCookies();
//初始性质的上次访问
Boolean variable = false;
for (Cookie cookie : cookies) {
if (cookie.getName().equals("time")){
//解码
String decodeResult = URLDecoder.decode(cookie.getValue(), "utf-8");
out.write("上次访问时间为"+decodeResult);
variable=true;
}
}
if (variable==false){
out.write("当前为第一次访问");
}
//获取当前时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String formatResult = sdf.format(new Date());
//URL编码
String encoderResult = URLEncoder.encode(formatResult,"utf-8" );
//创建cookie对象,并赋值
Cookie cookieObj = new Cookie("time",encoderResult );
//共享cookie数据
response.addCookie(cookieObj);
%>
<br>
<input type="text">
</body>
</html>
JSTL是JSP的标准标签库,也就是taglib指令所带来的一些功能
我们可以根据JSTL中提供的标签增强网页的功能
要使用JSTL,就必须先定义taglib指令
JSTL中有3个标签需要掌握,分别是’if’,'choose","foreach"标签
if标签,故名思意就是java中的if,只是在jstl中的使用方式稍有不同.
但是概念不同,java中的if用于进行流程控制.jstl中的if用于判断是否在网页显示.
比如,如果为true(真),则将标签体的内容显示在网页上,如果为false(假)则不显示.
属性TEST的作用
test是if标签的一个属性,它用于存放一个Boolean结果作为值,如果结果值为true,则显示标签的标签体,如果为false,则不显示标签体的内容
定义格式:<自定义资源前缀名:if test="${自定义EL表达式}">要显示的标签体自定义资源前缀名:if>
列如:
<c:if test="${paramtest<6}">
JSTL中’choose’标签容器,相当于Java的switch流程控制语句
一个个对比,如果哪个符合条件,就显示哪个whec标签内的代码
使用步骤一: 使用choose标签声明,相当于switch声明
使用步骤二: 使用when标签做判断,相当于case
使用步骤三: 使用otherwise标签做其他情况的声明,相当于default
定义格式:<自定义资源前缀名:choose> <自定义资源前缀名:when test="${自定义EL表达式}">要显示的标签体自定义资源前缀名:when> <自定义资源前缀名:otherwise>当所有表达式条件不匹配时,要显示的标签体!自定义资源前缀名:otherwise> 自定义资源前缀名:choose>
列如:
<%
int num = 5;
request.setAttribute("paramtest",num);
%>
<c:choose>
<c:when test="${paramtest==1}">数值为1</c:when>
<c:when test="${paramtest==2}">数值为2</c:when>
<c:when test="${paramtest==3}">数值为3</c:when>
<c:when test="${paramtest==4}">数值为4</c:when>
<c:when test="${paramtest==5}">数值为5</c:when>
<c:otherwise>数字存在错误!</c:otherwise>
</c:choose>
foreach标签,相当于java中的’for循环/增强for’.
它有两个用法,第一个是当作普通for循环用
第二个是当作增强for循环用
[[[第一种应用形式 普通for循环 ]]]:
用途:用于以普通for形式重复地执行一些操作,多数为循环常量
.
属性1:begin 开始值
属性2:end 结束值
属性3:var 临时变量
属性4:step 自增自减的倍数 相当于i++/i– 区别是它可以一次自增/自减1个以上的倍数 如:step的数值为2,那么每循环一次自增2个值 也就是1 3 5 7 9… 推荐为1
属性5:varStatus 遍历过程的状态对象 index和count(不常用,省略)
定义格式:<自定义资源前缀名:forEach begin="自定义开始值" end="自定义结束值" var="自定义临时变量名" step="自定义自增/自减的倍数"> 自定义标签体 自定义资源前缀名:forEach>
列如:
<%
for (int i = 0; i < 10; i++) {
System.out.println("当前循环到了第"+i+"次");
}
%>
<c:forEach begin="0" end="10" var="i" step="1">
<h4>当前循环到了第${i}次</h4>
</c:forEach>
[[[第二种应用形式 增强for循环 ]]]
用途:用于以增强for形式执行遍历操作,多数为循环集合
属性1(重要):items 用于通过el表达式,根据集合的数据共享名,来获取某个集合
属性2(重要):var 用于存放集合中的数据元素
对象性质的属性(重要):varStatus 用于遍历过程的状态对象,它有两个方法,分别是index和count,
index方法的作用:获取集合元素的索引值,起始索引值从1开始.
count方法的作用:记录循环次数,起始循环次数值从0开始.
定义格式:<自定义资源前缀名:forEach items="自定义EL表达式" var="自定义数据元素名" varStatus="自定义过程对象名" > 自定义标签体 自定义资源前缀名:forEach>
列如:
<%
List arr = new ArrayList();
arr.add("你好~");
arr.add("我在写代码");
arr.add("但是感觉好枯燥");
arr.add("如何是好?");
arr.add("我真的不知道");
arr.add("因为我犯了烟瘾");
request.setAttribute("listparam",arr );
%>
<c:forEach items="${listparam}" var="result" varStatus="vs" >
index:${vs.index} count:${vs.count} 数据:${result}<br>
</c:forEach>