一.JSP相关技术
1.1 JSP由来
当我们需要向页面输出大量的HTML代码的时候,我们需要通过response对象写多次来输出HTML代码
response.getWriter().write("<font>文本</font>");
页面的展示和servlet密不可分,不利于后期代码维护,因此推出一种可以将java代码嵌入到HTML中的技术:JSP
JSP=HTML+CSS+JS+JAVA
1.2 JSP技术概述
JSP(Java Server Pages),JSP本质上就是一个servlet,JSP文件后缀名为.jsp
JSP的第一行有一个声明,解决中文乱码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
1.3 JSP技术作用
JSP中的HTML代码负责静态内容的展示
*JSP中的Java代码负责动态内容的展示
1.4 JSP技术原理
a.当我们访问一个jsp页面的时候,Tomcat会把.jsp文件翻译成对应的.java文件,然后在编译这个.java文件生成.class文件,最后执行.class
(Tomcat会把.jsp翻译的.java文件存放到当前服务器的work目录下)
例如:当我们访问index.jsp=翻译==>index_jsp.java==编译=>index_jsp.class=>Tomcat将index_jsp.class加载到内存中执行
b.核心代码剖析
/*
1.JSP翻译成的java文件继承了org.apache.jasper.runtime.HttpJspBase
而org.apache.jasper.runtime.HttpJspBase继承了HttpServlet
2.当我们访问JSP的时候,其实就是Tomcat去调用HttpJspBase中service方法
HttpJspBase中service中方法:
@Override
public final void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
_jspService(request, response);//最终调用的是HttpJspBase子类中的_jspService()方法
}
最终调用的就是_jspService方法3._jspService方法中的一些核心逻辑:
a.首先解决响应中文乱码问题
b.接着通过过out将jsp中的所有HTML代码输出到页面
*/
public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports {public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
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;charset=UTF-8");//<%@ page contentType="text/html;charset=UTF-8" language="java" %>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("\n");
out.write("<html>\n");
out.write(" <head>\n");
out.write(" <title></title>\n");
out.write(" </head>\n");
out.write(" <body>\n");
out.write(" <span style=\"color: red\">Hello JSP</span>\n");
out.write(" </body>\n");
out.write("</html>
1.5 JSP中嵌入java代码与JSP注释
a.声明标签
<%!java代码%>:其中声明的java代码会放在jsp对应的类的成员位置,所以可以在标签中声明成员变量,成员内部类,成员方法
b.脚本片段
<%java代码%>:其中声明的java代码会放在jsp对应类的_jspService方法中,所以是放在局部位置,可以在标签中声明局部变量,局部内部类
c.脚本表达式
<%=java表达式%>:负责向页面输出表达式执行结果,其实将表达式放在_jspService方法中的out.print(表达式)中,最终实现将内容输出到页面
注意:java表达式不能以;结尾
a.HTML代码可以用<!--注释内容-->
b.JSP中java代码注释
//注释
/*注释*/
c.JSP文件特有注释方式:<%--注释内容--%>
这种注释既可以注释JSP相关代码也可以注释HTML代码
1.6 JSP九大内置对象
a.概述:
内置对象指的是当把JSP翻译成Servlet后,自动生成的9个对象,可以直接在<%%>使用九个内置对象
b.对象名称 对象类型 对象描述
page Object 代表当前jsp翻译的servlet类的实例(本类的实例)request HttpServletRequest 请求对象
response HttpServletResponse 响应对象
session HttpSession 将会话信息保存在服务端对象
application ServletContext 代表当前应用(ServletContext域中的数据被所有Servlet共享)
config ServletConfig 可以针对某个Servlet初始化一些参数可以通过getServletConfig()获取到
out JspWriter 通过out对象的write方法或print方法向页面输出内容
exception Throwable 需要通过在jsp声明上添加属性isErrorPage="true"
pageContext PageContext 代表JSP页面的上下文,通过pageContext可以通过getXXX方法获取其它八个对象
二.EL表达式
2.1 EL表达式概述
1.EL表达式概述
EL是expression Language的缩写,它是JSP内置(可以直接使用)中的一种表达式语言
2.EL表达式作用
a.EL表达式主要用来替换jsp中<%=java表达式%>脚本
因为JSP脚本中融合了多项技术(HTML+CSS+JS+Java),如果JSP页面非常复杂,<%=%>脚本会写的非常多,导致这个页面可读性差
而且不利于后期代码维护,因此用EL表达式来代替<%=%>脚本向页面输出内容
b.EL表达式其实主要用来获取四大域(pageContext request session application)中数据并显示
3.EL表达式格式
${表达式}包含两种写法:
1.${xxScope.key}:获取指定的域中查找指定的key对应值
**2.${key}:默认会根据key去四大域中依次查找(pageContext=>request=>session=>application)
2.2 EL表达式获取四大域中的数据
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>EL表达式获取四大域中的数据</title> </head> <body> <% //向request域中存数据 request.setAttribute("username","zhangsan"); //向session域中存数据 session.setAttribute("password","123"); //向pageContext域中存数据 pageContext.setAttribute("id","456"); //向application域中存数据 application.setAttribute("gender","male"); %> <%="request域中的值:"+request.getAttribute("username")%><br> <%="session域中的值:"+session.getAttribute("password")%><br> <%="pageContext域中的值:"+pageContext.getAttribute("id")%><br> <%="application域中的值:"+application.getAttribute("gender")%><br> <hr> request域中的值:${requestScope.username}<br> session域中的值:${sessionScope.password}<br> pageContext域中的值(简化形式):${id}<br> application域中的值(简化形式):${gender} </body> </html>
2.2 EL表达式获取自定义对象
EL表达式注意事项
如果从所有域中都不能找到key对应的值,那么EL表达式将来浏览器什么都不输出
如果key的值比较特殊,我们可以通过["key"]来代替.的形式
EL表达式原理
${a.b.c.xx....}
EL表达式的每一级都是根据getXxx方法将数据取出
<%@ page import="bean.Person" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>EL表达式获取自定义对象</title> </head> <body> <% request.setAttribute("person",new Person("张三",18,"man")); request.setAttribute("001",new Person("李四",20,"male")); %> 使用脚本表达式获取自定义对象的值:<br> <%=((Person)(request.getAttribute("person"))).getName()+" "+ ((Person)(request.getAttribute("001"))).getAge()+" "+ ((Person)(request.getAttribute("person"))).getGender() %><br> 使用EL表达式获取自定义对象的值:<br> ${person.name} ${person.age} ${person.gender} ${requestScope["001"].name} <%--由于属性名不能以数字开头,直接使用${001.name}会报错--%> <%--底层默认调用get方法来获取值--%> </body> </html>
2.3 EL表达式取出集合中的数据
<%@ page import="java.util.Arrays" %> <%@ page import="bean.Person" %> <%@ page import="java.util.List" %> <%@ page import="java.util.HashMap" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>EL表达式取出集合中的数据</title> </head> <body> <% //list集合 List<Person> peoples = Arrays.asList( new Person("张三", 18, "man"), new Person("李四", 20, "male") ); request.setAttribute("peoples",peoples); //map集合 HashMap<String, Person> map = new HashMap<>(); map.put("张三",new Person(18,"man")); map.put("001",new Person(20,"male")); session.setAttribute("map",map); %> 使用脚本表达式获取集合中的值:<br> <%="list集合中的数据:"+((List<Person>)request.getAttribute("peoples")).get(0).getName()+ ((List<Person>)request.getAttribute("peoples")).get(1).getGender()%><br> <%="map集合中的数据:"+((HashMap<String,Person>)session.getAttribute("map")).get("张三").getAge()+ ((HashMap<String,Person>)session.getAttribute("map")).get("001").getGender() %><br> <hr> 使用EL表达式获取集合中的值:<br> list集合(索引): ${peoples[0].name} ${peoples[1].name}<br> map集合:${map.张三.gender} ${map["张三"].age} ${map["001"].gender} </body> </html>
2.4 EL表达式获取应用上下文
EL表达式11个内置对象:可以在EL表达式中直接使用
参照图表
我们经常使用pageContext来获取应用上下文(Application Context)
${pageContext.request.contextPath}
2.5 EL表达式中的运算符 & 非空判断
EL表达式运算符
<%--算术运算符
1.常量运算
2.从域中取出数据并计算,如果对数值字符串进行运算,会先转换为数值在做运算
--%><%--逻辑运算符
1.常量布尔表达式
2.先从域中取数据,然后进行逻辑运算
--%>
<%--三元运算符--%>
EL表达式非空判断
<%--非空判断
利用empty运算符做空判断,如果表达式的值空,表达式返回true,如果表达式的值不为空返回false
1.判断对象是否null
2.判断字符串是否为""
3.判断集合对象(List,Map)是否为null,也可以判断集合中是否元素
--%>