介绍
- JSP、EL(Expression Language)、JSTL(JavaServer Pages Standard Tag Library)是 Java Web 应用程序中常用的三种技术,它们的关系如下:
- JSP 是一种动态网页技术,它允许在 HTML 页面中嵌入 Java 代码,以便在 Web 服务器上动态生成页面内容。
- EL 是一种表达式语言,它可以在 JSP 页面中直接访问 Java 对象和变量,以便更方便地处理数据和执行业务逻辑。
- JSTL 是一种标签库,它提供了一组常用的自定义标签,可以在 JSP 页面中使用,以便更方便地处理数据和控制页面输出。
- 在 Java Web 应用程序中,通常会同时使用 JSP、EL 和 JSTL 这三种技术,以便更方便地完成 Web 应用程序的开发和维护。具体来说,JSP 页面可以使用 EL 表达式访问 Java 对象和变量,以便更方便地显示和处理数据;同时,JSTL 标签库可以使用 EL 表达式作为参数,以便更方便地控制标签的行为和输出结果。综合使用 JSP、EL 和 JSTL 这三种技术,可以大大提高 Java Web 应用程序的开发效率和维护性。
- 注释区别
- HTML 注释
<!-- HTML注释,静态资源,浏览器显示 --> - JSP 注释
<%-- JSP注释,动态资源,浏览器不显示 --%>
- JSP 的组成
- 静态资源
- Java 脚本
- Java 脚本
<% 逻辑代码 %> - 表达式
<%=输出 %> - 声明
<%! 类中的代码 %>
- JSP 标签:
- 动作
<jsp:include page="/footer.jsp"/>
- 指令
- EL
- 用于简化输出操作
- el 函数库需要导入
/jstl/function 标签库
- JSTL
- 用于逻辑代码的书写
- jstl 需要导入
/jstl/core 标签库
Jsp
<%@ page import="java.util.Date" %><%-- <%@ %>表示指令,引入java的包 --%><%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"
language="java" errorPage="ExceptionNote.jsp" %><%--该jsp的页面编码解码格式为utf-8,支持的脚本语言为java--%>
<%--errorPage="ExceptionNote.jsp"表示异常后跳转的页面--%>
<html>
<head>
<title>JspNote</title>
</head>
<body>
<%--动作,在jsp中引入其他页面,路径为服务器路径,同步方式--%>
<%--<jsp:include page="/HeaderAndFooterServlet?method=getHeader"/>--%>
<%--动作,在jsp中引入其他页面,路径为服务器路径,异步方式--%>
<jsp:include page="/footer.jsp"/>
<br>
<%--jsp本质上为一个servlet类,其java源代码位于target\tomcat\work\Tomcat\localhost\jsp\org\apache\jsp\JspNote_jsp.java--%>
<%--java脚本,里面存放java代码(java方法中的代码书写方式)--%>
<%
//java的对象需要使用page指令的import属性导包
Date date = new Date();
//response为jsp的内置对象
response.getWriter().write(String.valueOf(date) + "<br/>");
System.out.println("java对象" + date);
//region jsp九大内置对象(JSP中特有的域:Page、PageContext)
//page 就是this
response.getWriter().write("page==this:" + (page == this) + "<br/>");
//request
request.setAttribute("requestAttr", "request内置对象");
//response
response.getWriter().write("response内置对象<br/>");
//session
session.setAttribute("sessionAttr", "session内置对象");
//application ServletContext
application.setAttribute("applicationAttr", "application内置对象");
//out JspWriter 字符流
out.write("out内置对象<br/>");
//config ServletConfig
out.write(config.getServletName() + "<br/>");
//exception
if (false) {
throw new RuntimeException("出现异常");
}
//pageContext 其他的八个jsp内置对象都可以通过pageContext对象操作(只演示了5个)
// page,request,session,ServletContext 为jsp的域属性
// request,session,ServletContext 为servlet的域属性
pageContext.setAttribute("pageContextAttr", "pageContext内置对象");
pageContext.setAttribute("pageContextAttr", "pageContext内置对象 PAGE_SCOPE", PageContext.PAGE_SCOPE);
pageContext.setAttribute("pageContextAttr", "pageContext内置对象 REQUEST_SCOPE", PageContext.REQUEST_SCOPE);
pageContext.setAttribute("pageContextAttr", "pageContext内置对象 SESSION_SCOPE", PageContext.SESSION_SCOPE);
pageContext.setAttribute("pageContextAttr", "pageContext内置对象 APPLICATION_SCOPE", PageContext.APPLICATION_SCOPE);
//page和request域可通过该方式调用,page>request的顺序查找
out.write(pageContext.getAttribute("pageContextAttr").toString() + "<br/>");
out.write(pageContext.getAttribute("pageContextAttr", PageContext.REQUEST_SCOPE).toString() + "<br/>");
out.write(pageContext.getAttribute("pageContextAttr", PageContext.SESSION_SCOPE).toString() + "<br/>");
out.write(pageContext.getAttribute("pageContextAttr", PageContext.APPLICATION_SCOPE).toString() + "<br/>");
//全域查找,通过 page>pageContext>request>session>application 的顺序查找
out.write(pageContext.findAttribute("pageContextAttr").toString());
%>
<%--声明,相当于该JspNote_jsp类的成员变量与成员方法(java类中的代码书写方式)--%>
<%!
private static int count = 1;
public static int getCount() {
return count++;
}
%>
<%--表达式,主要用于页面的输出操作--%>
<%=
"<h1>第 " + getCount() + " 次访问页面</h2>"
%>
<%--静态资源和java脚本嵌套使用--%>
<table>
<%
for (int i = 1; i <= 3; i++) {
%>
<tr>
<td>
<%="times" + i %>
</td>
<td>
<%=i %>
</td>
</tr>
<%} %>
</table>
</body>
<%--这是一个同步的复用页面,需要来自servlet的转发--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>header.jsp</title>
<link rel="stylesheet" href="css/bootstrap.min.css">
<script src="js/jquery.min.js"></script>
<script src="js/popper.min.js"></script><%--用于下拉菜单--%>
<script src="js/bootstrap.min.js"></script>
</head>
<body>
${info}
</body>
</html>
<%--这是一个异步的复用页面,直接调用该页面,无需先接收servlet转发--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>footer</title>
<script>
$(function () {
$.get("HeaderAndFooterServlet",
{"method":"getFooter"},
function (result) {
$("#footer").append(result);
})
})
</script>
</head>
<body>
<div id="footer"></div>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true" %><%--错误跳转的目标页面必须使用isErrorPage="true"属性--%>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>这是错误跳转的目标页面</h1>
<%out.write(exception.getMessage());%>
</body>
</html>
package priv.noby.jsp.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
public class BaseServlet extends HttpServlet {
@Override
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
request.setCharacterEncoding("UTF-8");
String methodName = request.getParameter("method");
Method method;
try {
method = this.getClass().getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
} catch (Exception e) {
throw new RuntimeException(methodName + "方法未定义!", e);
}
try {
String result = (String) method.invoke(this, request, response);
if (result != null && !result.trim().isEmpty()) {
int index = result.indexOf(":");
if (index == -1) {
request.getRequestDispatcher(result).forward(request, response);
} else {
String start = result.substring(0, index);
String path = result.substring(index + 1);
if (start.equals("f")) {
request.getRequestDispatcher(path).forward(request, response);
} else if (start.equals("r")) {
response.sendRedirect(request.getContextPath() + path);
}
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
package priv.noby.jsp.servlet;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/HeaderAndFooterServlet")
public class HeaderAndFooterServlet extends BaseServlet {
public String getHeader(HttpServletRequest request, HttpServletResponse response) {
request.setAttribute("info","---------这是一个同步的复用页面header----------");
return "f:/header.jsp";
}
public String getFooter(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.getWriter().write("---------这是一个异步的复用页面footer----------");
return null; }
}
EL
<%--EL表达式主要用于简化JSP中的各种输出操作--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--taglib 为引入第三方标签库的指令,prefix为该标签指定别名(在调用时使用),uri为该标签的使用具体规则,使用前必须同时引入jstl--%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%--/jstl/core为jstl核心--%>
<%--/jstl/function为el函数库--%>
<html>
<head>
<title>ELNote</title>
</head>
<body>
<%--模拟来自servlet的域对象--%>
<%
request.setAttribute("info", "requestInformation");
session.setAttribute("info", "sessionInformation");
application.setAttribute("info", "applicationInformation");
%>
<%--EL的11个内置对象--%>
${info}<br><%--全域查找:会按照四大域从小到大查找该属性 注意${"info"}表示的是输出字符串"info"--%>
\${info}表示转译<br>
${requestScope.info}<br><%--${}即为EL的输出方式,等用于jsp中的<%= %>标签}--%>
${sessionScope.info}<br>
${applicationScope.info}<br>
<hr>
<%--EL运算符--%>
${not empty info}
<%--
/或div
%或mod
==或eq
!=或ne
<或lt
>或gt
<=或le
>=或ge
&&或and
!或not
||或or
empty--%>
<hr>
<%--EL一共11个内置对象。这11个内置对象中有10个是Map类型的,最后一个是pageContext对象--%>
<%--
pageScope 取page域中的值
requestScope 取request域中的值
sessionScope 取session域中的值
applicationScope 取servletContext域中的值
${xxxScope.key} 查找指定域
${key} 全域 查找
param 获取请求参数的值
paramValues 一个请求参数key有多个值
header 获取请求头的值
headerValues 获取请求头的值,一个头名对应多个头值
initParam 获取SerlvetContext初始化参数
cookie 获取Cookie的值
pageContext 获取其它内置对象
--%>
<a href="ELNote.jsp">ELNote.jsp</a><br/>
<%--jsp中不建议直接使用绝对路径--%>
<a href="/jsp/ELNote.jsp">ELNote.jsp</a><br/>
<!-- 绝对路径的灵活写法 -->
<a href="<%=request.getContextPath() %>/ELNote.jsp">ELNote.jsp</a><br/>
<a href="<%=((HttpServletRequest)pageContext.getRequest()).getContextPath()%>/ELNote.jsp">ELNote.jsp</a>
<a href="${pageContext.request.contextPath}/ELNote.jsp">ELNote.jsp</a>
<%--利用jstl--%>
<a href="<c:url value='/ELNote.jsp'/>">ELNote.jsp</a><br/>
<hr>
<%--EL函数库(使用前导入jstl的jar包和jsp标签库)--%>
${fn:toUpperCase("java")}<%--表示使用fn标签中的toUpperCase()方法--%>
<%--
String toUpperCase(String input):
String toLowerCase(String input):
int indexOf(String input, String substring):
boolean contains(String input, String substring):
boolean containsIgnoreCase(String input, String substring):
boolean startsWith(String input, String substring):
boolean endsWith(String input, String substring):
String substring(String input, int beginIndex, int endIndex):
String substringAfter(String input, String substring):
substringBefore(String input, String substring):
String escapeXml(String input) 对标签转义,显示原样字符,不显示标签效果
String trim(String input):
String replace(String input, String substringBefore, String substringAfter):
String[] split(String input, String delimiters):
int length(Object obj):
String join(String array[], String separator): 拼接
--%>
<hr>
</body>
</html>
JSTL
<%--JSTL主要用于if条件判断,循环等--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--/jstl/core为jstl核心--%>
<%--/jstl/function为el函数库--%>
<html>
<head>
<title>JSTLNote</title>
</head>
<body>
<hr>
<%--通过jstl实现条件判断及循环--%>
<%--模拟来自servlet的request域--%>
<%
String[] names = {"noby", "kace", "july"};
request.setAttribute("names", names);
%>
<%--条件判断语句--%>
<c:if test="${not empty names}">
<%--增强for循环语句--%>
<c:forEach var="name" items="${names}">
${name}
</c:forEach>
</c:if>
<hr>
<%--for循环--%>
<c:forEach var="i" begin="0" end="2" step="1">
${names[i]}
</c:forEach>
<hr>
<%--赋值语句--%>
<c:set var="score" value="56"/>
<%--删除域中属性--%>
<%--<c:remove var="score" scope="page"/>--%>
<%--out输出语句--%>
<c:out value="${score}"/><br/>
<hr>
<%--选择语句--%>
<c:choose>
<c:when test="${100 >= score and score > 90}">优秀</c:when>
<c:when test="${90 >= score and score > 70}">良好</c:when>
<c:when test="${70 >= score and score > 60}">及格</c:when>
<c:when test="${score < 60 and score >= 0}">不及格</c:when>
<c:otherwise>无效成绩</c:otherwise>
</c:choose>
<hr>
<%--c:url路径--%>
<a href="<c:url value='/JSTLNote.jsp'/>">JSTLNote.jsp</a><br/>
</body>
</html>