一、JSP基础
1、JSP的创建位置
在WEB-INF外创建。
2、JSP实际上就是一个Servlet
1、xxxx.jsp文件访问的时候,会自动翻译成xxxx_jsp.java,会自动编译生成,xxxx_jsp.class,index_jsp这就是一个类。
2、xxxx_jsp类继承HttpJspBase,而HttpJspBase类继承的是HttpServlet,所以xxxx_jsp类就是一个Servlet类。
3、JSP的生命周期和Servlet的生命周期完全相同,并且都是单例的(假单例)
3、JSP文件第一次访问的时候都比较慢
1、第一次访问时,要先把jsp文件翻译生成java源文件,然后再将java源文件编译成字节码文件,然后通过class创建servlet对象,然后调用servlet对象的init方法,最后调用servlet的service方法。
2、第二次比较快了,因为第二次直接调用单例Servlet对象的service方法即可。
4、JSP是什么
1、JSP是java程序。(本质上是一个Servlet)
2、JSP是:JavaSevlet Pages缩写。(基于Java语言实现的服务器端的页面)
3、Servlet是JavaEE的13个子规范之一,那么JSP也是JavaEE的13个子规范之一。
4、JSP是一套规范,所有的Web容器/Web服务器都是遵循这套规范的,都是按照这套规范进行“翻译”
5、每一个web容器/web服务器都会内置一个JSP翻译引擎。
5、对JSP进行错误调试
打开JSP文件对应的java文件,检查java代码
6、JSP的基础语法
(1)在JSP文件中直接编写文字,会被自动翻译到哪里?
1、翻译到servlet类的service方法的out.write("翻译到这"),直接翻译到双引号里,被java程序当成普通字符串打印输出到浏览器。
2、在JSP中编写的HTML、CSS、JS代码,这些代码对于JSP来说只是一个普通字符串,但是JSP将这些字符串一旦输出到浏览器中,浏览器就对这些代码进行解释执行,展现效果。
(2)JSP的page指令
<%@page %>
1、通过page指令设置响应的内容类型:
<%@page contentType="text/html;charset=UTF-8" %>
2、通过page指令导包
<%@page import="java.util.List, java.util.ArrayList"%>
(3)在JSP中编写Java程序
(1)
语法:<% java语句; %>
说明:
1、在这个符号当中编写的被视为java程序,被翻译到Servlet类的service方法中
2、在<% %>中编写java代码时,要记住这是在方法体内编写代码,只能编写允许在方法体内编写的内容。
3、同一个JSP中可以编写多个<% %>。
(2)
语法:<%! %>
说明:
1、在这中间编写的java代码,会被自动翻译到service方法外。
2、这种方法很少用,因为在service方法外编写静态变量和实例变量,都会存在线程安全问题,JSP是Servlet,而Servlet是单例的,多线程并发的情况下,这个静态变量和实例变量一旦有修改操作,必然存在线程安全问题。
(5)JSP中的注释
<%--注释信息--%>
说明:
1、使用<!--这种会被翻译到java源文件中-->
(6)JSP和Servlet的区别
1、Servlet:收集数据(Servlet的强项是逻辑处理,业务处理,然后链接数据库,获取/收集数据)
2、JSP:展示数据(JSP的强项是做数据的展示)
(7)JSP的输出语句
1、怎么向浏览器上输出一个java变量。
例子:<% String name = "jack"; out.write("name = " + name); %>
说明:以上代码中的out是JSP的九大内置对象之一,可以直接用,但是只能service方法内使用。
2、如果向浏览器上输出的内容中没有“java”语句,可以直接在jsp中编写,不用写到<%%>中
3、如果输出的内容中含有Java代码,可以使用以下语法格式
语法:<%= %>
说明:
(1)在=的后面编写输出的内容,注意这个内容后面不能加分号
(2)这个语句会被翻译成service方法中的out.write();
(3)输出固定的字符串时,可以直接写不用<%=%>,当输出的内容中有java变量,不是固定字符串时,使用这条语句。
7、JSP注意事项
(1)JSP文件的扩展名
1、JSP文件的扩展名不一定是.jsp,在CATALINA_HOME/conf/web.xml中可以配置jsp文件的扩展名,源码如下图。
2、jsp文件对于web服务器来说只是一个普通的文本文件,因为会将xxx.jsp文件编译成java源程序,最终调用的是java对象的相关方法,真正执行时,与jsp无关了。
二、JSP指令
1、指令
(1)指令作用
指导JSP的翻译引擎如何工作【指导当前的JSP翻译引擎如何翻译JSP文件】
(2)指令包括哪些
1、include指令
(1)包含指令,在JSP中完成静态包含,很少使用。
2、taglib指令
(1)引入标签库的指令。
3、page指令
(3)指令的使用语法
<%@指令名 属性名=属性值 属性名=属性值...%>
2、page指令
(1)启用或禁用JSP的内置对象session
<%@page session="true"%>
说明:
(1)true为启用,false为禁用。
(2)如果没有设置,默认为true
(2)指定响应的内容类型
<%@page contentType="text/json" %>
说明:(1)contentType用来指定响应的内容类型
(3)设置响应时的字符集
1、<%@page pageEncoding="UTF-8" %>
2、<%@page contentType="text/json;charset=UTF-8" %>
说明:
(1)以上两种方法的作用相同都可以设置响应时的字符集
(4)导包
1、<%@page import="java.util.List, java.util.Date" %>
2、<%@page import="java.util.List"%><%@page import="java.util.Date"%>
说明:
(1)以上两种写法都可以导包
(5)指定出错后的跳转路径
<%@page errorPage="xxxx.jsp"%>
说明:
(1)当前页面出错后,跳转到xxxx.jsp页面
(6)启用或禁用JSP的内置对象exception
<%@page isErrorPage="true" %>
说明:
(1)可以通过这个指令,在错误页面启用JSP九大内置对象之一exception,而exception就是刚刚发生的异常,使用java语句exception.printStackTrace();可以在后台获取错误信息。
(2)默认值是false
(7)忽略EL表达式
<%@page isELIgnored="true"%>
说明:
(1)使用这个指令,可以忽略EL表达式,${}以字符串的形式在浏览器输出
(2)默认为false,true表示不忽略。
(3)这种方式不建议用,如果只忽略其中某个或几个EL表达式,可以使用\,例如【\${}】
三、JSP的九大内置对象
1、jakarta.servlet.jsp.PageContext pageContext【页面作用域】
2、jakarta.servlet.http.HttpServletRequest request【请求作用域】
3、jakarta.servlet.http.HttpSession session【会话作用域】
4、jakarta.servlet.ServletContext application【应用作用域】
(1)作用域的大小排序:pageContext<request<session<application
(2)以上四个作用域都有:setAttribute、getAttribute、removeAttribute方法
(3)以上作用域的使用原则:尽可能使用小的域
5、java.lang.Throwable exception
6、jakarta.servlet.ServletConfig config
7、java.lang.Object page【当前的Servlet对象,通过this获取】
8、jakarta.servlet.jsp.JspWriter out【负责输出】
9、jakarta.servlet.http.HttpServletResponse response【负责响应】
四、EL表达式
1、说明
1、Expression Language(表达式语言)
2、EL表达式可以代替JSP中的java代码,让JSP文件中的程序看起来更加整洁、美观。
3、JSP中夹杂着各种java代码,导致JSP代码很混乱,不好维护,才有了EL表达式
4、EL表达式可以算是JSP语法的一部分
2、作用
1、从某个作用域中取数据,然后将其转换成字符串,然后将其输出到浏览器,三大功效:
(1)第一功效:从某个域中取数据
(2)第二功效:将取出的数据转成字符串【若是java对象,则调用toString()方法】
(3)第三功效:将字符串输出到浏览器
3、语法格式
${表达式}
例子:
${username}
①说明
(1)如果表达式是某个java对象【存储到域对象当中的name,会通过这个name获取对应对象】则会调用其toString方法,然后输出到浏览器
(2)要访问对象的属性,其实是与对象对应的get方法有关,${username.username} 或者${username["username"]} 使用这个语法的前提是:User对象有对应的getUsername()方法【必须是驼峰命名方式】。【如果没有对应的get方法,则出现异常,会报500异常】
(3)表达式不能加双引号,如果加双引号,则直接将该字符串输出到浏览器
(4)EL表达式优先从小的域中取数据【就近原则】
(5)EL表达式有4个隐含的隐式的范围对象:pageScope、requestScope、sessionScope、applicationScope,可以指定范围${pageScope.username}【注意:但是在实际开发中,一般都不指定,因为往域中存储的name不会相同】
(6)如果在4个域中未取到对应的name,最终不会报错,不会返回null,而是什么都不输出到浏览器上
②从Map集合中取数据
${map.key}
③从数组中取数据
${Array[index]}
④从List集合中取数据
${List[index]}
⑤从Set集合中取数据
${set}
⑥通过EL表达式获取应用的根
${pageContext.request.contextPath}
说明:
(1)在EL表达式中有隐含对象pageContext,因为pageContext有getRequest()方法,而request有getContextPath方法,故可以这样使用。
(2)不能直接使用request进行调用,因为EL表达式中没有request隐含对象。
4、EL表达式中的隐含对象
①pageContext
${pageContext.request.contextPath}
说明:
(1)在EL表达式中有隐含对象pageContext,因为pageContext有getRequest()方法,而request有getContextPath方法,故可以这样使用。
(2)不能直接使用request进行调用,因为EL表达式中没有request隐含对象。
(3)可以通过pageContext获取JSP九大内置对象。
②param
${param.username}
说明:
(1)获取的是请求参数一维数组当中的第一个元素,等同于request.getParamter("username")
(2)不适合多个相同name的checkbox提交
③paramValues
${paramValues.username[0]}
说明:
(1)获取请求参数一维数组,通过下标获取一维数组中的每个值
④initParam
${initParam.username}
说明:
(1)获取初始化参数
(2)对应java代码:application.getInitParameter("username");
⑤其他【非常用】
5、EL表达式中的运算符
①算术运算符【+ - * / %】
(1)在EL表达式中,运算符“+”只能做求和运算,不会进行字符串拼接操作。
(2)如果“+”两边都不是数字,一定会转成数字,如果转不成数字,则会报错。
②关系运算符【== != > >= < <= eq】
(1)“==”调用了equals方法,“eq”调用的也是equals方法
(2)“!=”也会调用equals方法【对象进行比较】
(3)!使用的时候需要注意优先级
③逻辑运算符【! && || not and or】
④条件运算符【? :】
使用方法:${empty param.username ? "成功" : "失败"}
⑤取值运算符【[] 和 .】
⑥empty运算符
使用方法:${empty param.username}
(1)判断是否为null,如果是null则返回true,不是则返回false
(2)可以联合使用,例如${!empty param.username}、${not empty param.username}