[TOC]
0x00 JSP基础
1.介绍
什么是JSP?它有什么用?
简介:Java Server Pager -> 从用户的角度来说就是一个网页(java html的结合体),而从程序的角度来说最终会翻译成一个类实际就是一个Servlet及(JSP = Servlet) 作用:由于HTML在多数的情况下是显示的静态网页,但是在实际应用场景中常常需要在网页上显示一些动态数据,实际就是采用JSP访问数据库读取数据,然后再呈现给用户端网页上
Tomcat 最后会将 jsp 文件编译后的(.class-字节码文件/.java-类)存放在目录/work/Catalina/localhost/项目名/org/apache/jsp 里面:
代码语言:javascript复制//E:Developmentapache-tomcat-9.0.31workCatalinalocalhostWeborgapachejsp
$ ls
login_jsp.class login_jsp.java
在Eclipse建立的JSP文件默认的编码格式是IISO-8859-1,我们可以从 Windows->penferences->jsp Files
修改编码为UTF-8则后面建立的文件默认格式就是UTF-8了
JavaEE 架构
- 客户层 (Web 浏览器 、Applet)
- Web (Severlet、 Jsp)
- 业务逻辑 (EJB)
- 数据持久层 (数据库 MySQL , Oracle)
2.基础语法
描述:主要记录学习的JSP的基础指令写法和变量声明定义与使用;
(1) 变量定义和调用
代码语言:javascript复制
//全局变量
<%! int a = 99; %>
//局部变量
<% int a = 1024; %>
//调用输出变量
<%=a %>
//JSP代码注释:
<%-- <jsp:forward page="./Demo1/forward.jsp"></jsp:forward> --%>
(2) JSP指令语法格式: JSP的三大指令:
代码语言:javascript复制<%@ 指令名称 %>
<%@ page %>
<%@ include %>
<%@ taglib %>
page 指令进行设置当前页面的一些信息: 实例解释:
代码语言:javascript复制<%@ page %>
<!-- JSP File 文件头部 -->
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" session="true" errorPage="error.jsp" %>
<!-- error.jsp 文件头部 -->
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" session="true" isErrorPage="true" %>
- language : 表示JSP文件中使用的JAVA代码
- contentType : 表示JSP文件显示的类型以及使用什么编码,我们可以在Tomcat的web.xml看到定义的MIME-type;
- pageEncoding : JSP文件编码格式
- extends : 用于指定JSP翻译成为JAVA文件后继承的父类是谁(常规默认即可)
- import : 导入指定包使用其方法;
- session : 控制jsp页面中是否能够直接使用Session对象(即session.getAttribute(‘’) ),值可选true(默认)或者false,具体区别是翻译的.Java文件在Tomcat的Work目录之中;
- errorPage : 指定错误的页面值需要给错误的页面路径;
- isErrorPage : 声明某一个页面到底是不是错误页面,即errorPage指定包含isErrorPage 参数的JSP页面
<%=exception.toString();%>
;
include 指令进行包含嵌套另外一个JSP的内容进来,即将另外一个文件读取包含进来(所有的标签元素) 实例解释:
代码语言:javascript复制//假如是在A页面上使用 <%@ include file="B.jsp" %>
//从页面上看 , 确实是两个 jsp 的内容组合到一起了。但是从背后翻译成的 java 文件看, 里面做了很多重复的标签输出。 其实就是既输出 A.jsp , 也输出了 B.jsp
<%@ include file="page.jsp" %>
taglib 指令:用于导入标签库 ,多用于引入 JSTL标签库
代码语言:javascript复制<%@ taglib prefix='' url="" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
- url : 表示标签库路径地址
- prefix : 标签别名表示别名或者称之为前缀也可以。
(3) 动态标签 描述:在JSP页面进行动态加载的标签;
代码语言:javascript复制<jsp:include page=""></jsp:include>
<jsp:forward page=""></jsp:forward>
<jsp:param value="" name=""/>
详细讲解: jsp:include 动态包含指定页面,将指定页面其中body主体中的运行结果拿到本页面进行显示(即body中的内容文本);
代码语言:javascript复制<h1>这是Error.jsp页面body元素内的内容:</h1>
<jsp:include page="error.jsp"></jsp:include>
实际运行编译的java源码:D:apache-tomcat-7.0.100workCatalinalocalhostJspDemoorgapachejspjsp_005faction_jsp.java
// 在 public void _jspService 方法里面
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "./Demo1/include.jsp", out, false);
补充知识:
- 1.jsp:include 与 include 指令有何区别? 答:我们上面看到jsp:include编译后可以看见java文件,前者是先解析该include.jsp后再执行拿取里面的内容,而include指令是直接将文件进行包含输出;
jsp:forward 进行请求转发到指定页面,URL还是原URL不变化; 补充:如果想关心到底底层是如何走的,可以去看jsp翻译成的那个java文件,里面有具体的翻译后的代码,再配合servlet源代码,即可找到最终的答案,就是:请求转发
代码语言:javascript复制<h2>请求转发到/Demo1/forward.jsp页面</h2>
<jsp:forward page="./Demo1/forward.jsp"></jsp:forward>
实际运行编译的java源码:D:apache-tomcat-7.0.100workCatalinalocalhostJspDemoorgapachejspjsp_005faction_jsp.java
if (true) {
_jspx_page_context.forward("./Demo1/forward.jsp");
return;
}
//实际调用类和方法
javax.servlet.jsp.PageContext _jspx_page_context = null;
request.getRquestsDispatcher("./Demo1/forward.jsp").forward(request,response);
jsp:param 在进行包含页面或者进行请求转发设置时带的请求参数与值;
代码语言:javascript复制// jsp_action.jsp
<h3>请求转发携带指定参数到/Demo1/forward.jsp页面</h3>
<jsp:forward page="./Demo1/forward.jsp">
<jsp:param value="WeiyiGeek" name="name"/>
<jsp:param value="18" name="age"/>
<jsp:param value="Computer" name="Love"/> <%-- 注意这里如果是中文会在输出时候乱码,在后面的课程之中进行改进 --%>
</jsp:forward>
// /Demo1/forward.jsp
<h1>Forward.jsp?<%=request.getQueryString() %></h1>
<p>显示转发请求的参数:</p>
Name:<%=request.getParameter("name") %>
<br>
Age:<%=request.getParameter("age") %>
<br>
喜好:<%=new String(request.getParameter("Love").getBytes("ISO-8859-1"),"UTF-8") %>
实际运行编译的java源码:D:apache-tomcat-7.0.100workCatalinalocalhostJspDemoorgapachejspjsp_005faction_jsp.java
if (true) {
_jspx_page_context.forward("./Demo1/forward.jsp" "?" org.apache.jasper.runtime.JspRuntimeLibrary.URLEncode("name", request.getCharacterEncoding()) "=" org.apache.jasper.runtime.JspRuntimeLibrary.URLEncode("WeiyiGeek", request.getCharacterEncoding()) "&" org.apache.jasper.runtime.JspRuntimeLibrary.URLEncode("age", request.getCharacterEncoding()) "=" org.apache.jasper.runtime.JspRuntimeLibrary.URLEncode("18", request.getCharacterEncoding()));
return;
}
//执行结果:
Forward.jsp?name=WeiyiGeek&age=18&Love=Computer
显示转发请求的参数:
Name:WeiyiGeek
Age:18
喜好:Computer
3.内置对象
描述:我们在JSP页面中无需进行创建以及手动导包,就直接在jsp页面中使用这些对象。
(1)内置对象说明 九大内置对象:
代码语言:javascript复制page [Object] //实际就是该jsp翻译成为Java类的实例对象;
exception [Throwable] //需要在page指令中加上isErrorPage的页面上显示使用
config [Servlet]
out [JspWriter]
response [HttpServletResponse]
//#后四个是作用域对象
pageContext [PageContext]
request [HttpServletRequest]
session [HttpSession]
application [ServletContext]
实际案例jsp_inner.java与java文件对照:
代码语言:javascript复制<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isErrorPage="true" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>内部对象</title>
</head>
<body>
<h1>九大内置对象</h1>
<%=page.toString() %>
<br>
<%--=exception.toString() --%>
<%=config.toString() %>
<br>
<% out.write("n 其次输出jspWriter 对象输出 <br>"); %>
<br>
<% response.getWriter().write("n 首先输出 Response 对象输出 <br>"); %>
<h2>内置作用域对象设置</h2>
<% pageContext.setAttribute("name", "pageContext"); %>
<% request.setAttribute("name", "request"); %>
<% session.setAttribute("name", "session"); %>
<% application.setAttribute("name", "application"); %>
<hr>
<p>四大内置作用域对象输出</p>
<%=pageContext.getAttribute("name") %>
<%=request.getAttribute("name") %>
<%=session.getAttribute("name") %>
<%=application.getAttribute("name") %>
</body>
</html>
<!--
Tomcat 封装后的 isp_005finner_jsp.java 文件
内置对象定义的原型
-->
final java.lang.Object page = this; //该JSP翻译成.java的实例对象this
final javax.servlet.ServletConfig config;
final javax.servlet.http.HttpServletRequest request
java.lang.Throwable exception = org.apache.jasper.runtime.JspRuntimeLibrary.getThrowable(request);
javax.servlet.jsp.JspWriter out = null;
<!-- 内置对象的作用域 -->
final javax.servlet.http.HttpServletResponse response
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
执行效果:
WeiyiGeek.内置对象
注意事项及其补充:
- 1.response与out内置对象的输出比较,我们从上面可以看出虽然
response.getWrite.write()
放在了out.Write()后面但是在输出的时候任然输出在前;
//我们可以翻看Servlet源码进行查看或者工程封装的jsp java文件中查看
out.write("n 其次输出jspWriter 对象输出 <br>");
out.write("rn");
out.write("<br>rn");
out.write("rn");
response.getWriter().write("n 首先输出 Response 对象输出 <br>");
WeiyiGeek.response与out内置对象的输出
2) 四个作用域对象
0.对应的类型是 PageContext . 该对象是四个作用域之一, 一般使用该对象来存取值 以及 获取其他八个内置对象(但是由于其他内置对象都可以直接使用,所以该作用一般比较少用了)
- 存取值:setAttribute 和 getAttribute
- 注意:该对象所存的值只能在该页面上取出来,也就是说它的作用域值能是当前页面。
1.request:该对象是 HttpServletRequest 的实例, 在这里的使用手法与java 代码中的使用手法是一样的。 该对象是四个作用域之一 , 通常在 jsp 页面用来存取值 和 跳转。
- 跳转:request.getRequestDispatcher(“”).forward(request, response);
- 存取值:使用的方法是 setAttribute 和 getAttribute . 注意:该对象的作用域 ,仅限于一次请求中。当服务器对该请求做出响应后,就无法在其他的地方获取里面存的值了。
2.Session: 默认情况下jsp 翻译成 java 文件后,会在里面的方法调用 request.getSession().那么咱们可以直接在 jsp 里面使用 session 对象, 我们一般使用这个对象来存取值。
- 在顶部的 page 指令里面有一个属性叫做 session=”true” 默认即是 true, 如果是 true 那么就会创建 session 对象。如果 session 属性 的值 是 false , 那么我们在 jsp 页面上,将无法使用 session 对象。因为翻译成的 java 类中,根本没有创建这个对象。
- 存取值其实就是setAttribute 和 getAttribute 而已。
- 注意:该对象存的值是在一次会话后(多次请求和响应)内有效。
3.application:该对象是 ServletContext 类的实例, 可以做ServletContext的事情。 但是一般在jsp页面里面,我们使用该对象,多数情况都是来进行存值和取值。
- 我们使用该对象最多的两个方法是: setAttribute(”name” ,”weiyigeek.top”)和 getAttribute(“name”);
- 注意:该对象的作用域是最大的,直到服务器停止。也就是说在A.jsp页面中使用该对象存值, 在任何一个jsp页面上,都可以取值。
四个作用域的区别
- pageContext 【PageContext】 作用域仅限于当前的页面否则返回NULL,还可以获取到其他八个内置对象。
补充:
代码语言:javascript复制${pageContext.request.contextPath} #Web项目根路径(即项目上下文路径)
- request 【HttpServletRequest】 作用域仅限于一次请求, 只要服务器对该请求做出了响应,转发是可以获取请求的参数值,而重定向不得到重定向网页前的参数返回为NULL
- session 【HttpSession】 作用域限于一次会话(多次请求与响应) 当中,如果在每有设置该Sesssion属性前访问打印该属性值的页面则返回NULL;
- application 【ServletContext】 整个工程都可以访问, 服务器关闭后就不能访问了。
2.JSP 进阶
1.EL表达式
什么是EL表达式?它有什么作用?
答:全称是 Expression Language , 作用是为了简化咱们的 jsp 中的 java 代码 答:获取4个内置对象(域)中的数据,或自定义对象中的数据,或数组、集合容器中的数据。可以完成非常简单的运行技术,但它不能完成复杂的循环、复杂的判断等功能。
EL表达式写法格式:
代码语言:javascript复制${ 表达式}
//常用的EL表达式基础(可以查看文档)
${ a [ - * / ] b } //算术运算符表达式
${ a [> < == >= <= != | gt lt ] b } //条件运算符
${ empty u } //判断是否为空
${ u.name } //常用属性取值
注意事项:
- 1.它与JSP文件变量的调用输出不一致需要学习其语法,并且不想在写 <% %> jsp代码时候会提醒;
- 2.EL表达式查找变量的顺序先从page->request->session->application等四大作用域一个一个查找key并输出其值(先查到先输出);
(1)EL表达式取出变量 描述:EL表达式可以简化JSP代码输出内置对象定义的变量值,可以输出变量、数组、集合、MAP、等变量中的值;
代码语言:javascript复制<%@page import="java.util.ArrayList"%>
<%@page import="java.util.Map"%>
<%@page import="java.util.HashMap"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>EL表达式</title>
</head>
<body>
<p>1) 采用EL表达式输出变量属性的值</p>
<%
int a = 1024;
String b = "Java Program";
pageContext.setAttribute("a",a);
pageContext.setAttribute("b",b);
%>
${a}
${b}
<hr>
<p>2) 采用EL表达式输出内置4大域对象定义的属性</p>
<%
pageContext.setAttribute("name", "pageContext");
request.setAttribute("name", "request");
session.setAttribute("name", "session");
application.setAttribute("name", "application");
%>
${pageScope.name}
${requestScope.name}
${sessionScope.name}
${ applicationScope.name }
<hr>
<p>3) 采用EL表达式输出数组内容</p>
<%
String[] name = {"WeiyiGeek","Weiyi","Weiye"};
pageContext.setAttribute("arrayName", name);
%>
${arrayName[0]} ,${ arrayName[1] },${ arrayName[2] }
<hr>
<p>4) 采用EL表达式输出数组集合 ArrayList 内容</p>
<%
ArrayList al = new ArrayList();
al.add("abc");
al.add("def");
al.add("1024");
pageContext.setAttribute("al", al);
%>
${al[0]},${al[1]},${al[2]}
<hr>
<p>5) 采用EL表达式输出数组集合 Map 内容</p>
<%
Map map = new HashMap();
map.put("a","map集合需要导包");
map.put("b","WeiyiGeek");
map.put("c.d",1024); //特殊部分
pageContext.setAttribute("map", map);
%>
${map.a},${map.b},${map["c.d"]}
<hr>
<p>6)获取javabean之自定义对象的数据(需要采用page指令导包)</p>
<%--
Person person=new Person();
person.setName("taoshihan");
pageContext.setAttribute("person",person);
--%>
取值的方式:${person.name}
</body>
</html>
执行结果:
WeiyiGeek.EL表达式
1.EL内置对象
描述:下面显示了11个内置对象;
代码语言:javascript复制#常用
- pageContext
- initParam #全局初始化参数
#作用域相关对象
- pageScope
- requestScope
- sessionScope
- Application
# 头信息相关对象
- header
- headerValues
#请求参数相关
- param
- params
# cookies信息相关
- cookie
基础示例:
代码语言:javascript复制<p>1) 获取URL请求参数 </p>
方式1: <%=request.getParameter("name") %>
<br>
方式2: ${param.name}
<p>2) 获取请求的Cookies的key和值 </p>
<% response.addCookie(new Cookie("name","weiyigek")); %>
${cookie.name.name} 值: ${cookie.name.value}
执行结果:http://127.0.0.1:8080/JspDemo/el_inner.jsp?name=WeiyiGeek
代码语言:javascript复制1) 获取URL请求参数
方式1: WeiyiGeek
方式2: WeiyiGeek
2) 获取请求的Cookies
获取Cookie的:name值:weiyigek