JSP
java server pages:java服务端页面。
jsp本质上就是一个简化的servlet设计。
切记:不要直接在jsp页面中使用java代码完成复杂逻辑的处理,jsp应该只做对应数据的展示,复杂的逻辑代码应该使用servlet来进行处理。
执行流程:
1、用户发起请求:http://localhost:8080/index.jsp
2、由tomcat的JspServlet来拦截请求:
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>fork</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>xpoweredBy</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
<url-pattern>*.jspx</url-pattern>
</servlet-mapping>
3、JspServlet就会去读取index.jsp文件,并将之转译成一个java文件:index_jsp.java(servlet)
/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/8.5.55
* Generated at: 2021-09-13 06:20:00 UTC
* Note: The last modified time of this file was set to
* the last modified time of the source file after
* generation to assist with modification tracking.
*/
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports {
private static final javax.servlet.jsp.JspFactory _jspxFactory =
javax.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
private static final java.util.Set<java.lang.String> _jspx_imports_packages;
private static final java.util.Set<java.lang.String> _jspx_imports_classes;
static {
_jspx_imports_packages = new java.util.HashSet<>();
_jspx_imports_packages.add("javax.servlet");
_jspx_imports_packages.add("javax.servlet.http");
_jspx_imports_packages.add("javax.servlet.jsp");
_jspx_imports_classes = null;
}
private volatile javax.el.ExpressionFactory _el_expressionfactory;
private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
}
public java.util.Set<java.lang.String> getPackageImports() {
return _jspx_imports_packages;
}
public java.util.Set<java.lang.String> getClassImports() {
return _jspx_imports_classes;
}
public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
if (_el_expressionfactory == null) {
synchronized (this) {
if (_el_expressionfactory == null) {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
}
}
}
return _el_expressionfactory;
}
public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
if (_jsp_instancemanager == null) {
synchronized (this) {
if (_jsp_instancemanager == null) {
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
}
}
return _jsp_instancemanager;
}
public void _jspInit() {
}
public void _jspDestroy() {
}
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
final java.lang.String _jspx_method = request.getMethod();
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
return;
}
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");
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$</title>\n");
out.write(" </head>\n");
out.write(" <body>\n");
out.write(" 这是index.jsp\n");
out.write(" </body>\n");
out.write("</html>\n");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try {
if (response.isCommitted()) {
out.flush();
} else {
out.clearBuffer();
}
} catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
jsp的页面构成
jsp页面中能出现以下内容:
1、html
2、注释:
a html注释
b css注释
c js注释
d java注释
e jsp注释:<%–注释的内容–%>
html注释、css注释、js注释会被解析,且会被输出到浏览器,浏览器不执行注释内容
java注释也会被解析,但在生成的servlet中,注释内容不会被执行
jsp注释不会被解析。
3、jsp脚本元素
小脚本:<% 脚本内容 %>
编译后小脚本的内容出现在_jspService()方法中。
表达式:<%=要输出的内容 %>
表达式用于将某个内容展示到浏览器中。
声明:<%! 声明的内容 %>
编译后,声明中的内容会出现在类中,以成员变量或成员方法的形式出现。
4、指令
page指令:
<%@page language=“java” %>
page指令用于对当前jsp页面进行相应的一些设置。
常用属性如下:
- language:声明jsp要被转译的语言。
- import:声明转译的java文件要导入的包,不同的包使用逗号隔开。
- pageEncoding:设置jsp文件的数据编码格式。
- contentType:“text/html; charset=utf-8”,设置响应给浏览器的编码格式。
- session:设置转译的servlet中是否开启session支持,默认为true,表示开启,false表示关闭。
- errorPage:设置jsp运行错误跳转的页面。
- extends:设置jsp转译的java文件要继承的父类(包名+类名)。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
include指令:
<%@include file=“要加载的外部资源路径” %>
include指令用于加载外部资源,资源可为动态资源,也可为静态资源。
<%@include file="a.jsp"%>
taglib指令:
<%@taglib prefix=“指定引入的标签前缀” uri=“指定引入的标签包” %>
taglib指令用于引入外部标签库。
引入jstl:
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
案例:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@include file="a.jsp"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>$Title$</title>
<style>
a{
/*css注释*/
}
</style>
<script>
//js注释
</script>
</head>
<body>
<%--
小脚本:语法 <% 脚本内容 %>
--%>
<%
//java注释
int i=100;
System.out.println("今天天气真不错");
%>
<%--
表达式:语法 <%=要输出到浏览器的内容 %>
--%>
<%=i %>
<%--
声明:语法 <%! 声明的内容 %>
--%>
<%!
String username="tom";//成员变量
public int sum(int x,int y){
return x+y;
}
%>
<%=sum(5,6) %>
这是index.jsp
<!--html注释-->
<%--jsp注释--%>
</body>
</html>
jsp九大内置对象
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
final java.lang.String _jspx_method = request.getMethod();
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
return;
}
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;
pageContext:页面上下文对象,封装了其余的8大内置对象
session:session对象
application :web应用上下文对象
servletconfig:servlet配置对象
out:输出对象
page:页面对象
request:请求对象
response:响应对象
异常对象:ServletException
jsp四大作用域对象
pageContext对应的作用域对象pageScope 影响范围:当前页面
request对应的作用域对象requestScope 影响范围:本次请求
session对应的作用域对象sessionScope 影响范围:同一用户的所有请求
application对应的作用域对象applicationScope 影响范围:整个web应用
EL表达式
<!-- EL表达式 替代:脚本表达式-->
expression language:表达式语言
作用:用于获取域对象中保存的数据。
语法:
${指定作用域中保存的key}
使用EL表达式时,如果指定了作用域去查找内容,则只会在指定的作用域中查找,如果没有找到,返回""
如果不指定作用域查找内容,会默认从最小的作用域起,逐层向上查找,直到找到为止,如果在最大的作用域中都没有找到,返回""
案例:
<%@ page import="com.woniuxy.model.User" %>
<%@ page import="java.util.Arrays" %>
<%@ 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>
<%
request.setAttribute("username","tom");
session.setAttribute("username","张飞");
request.setAttribute("user",new User("tom","111"));
//集合
List<User> users = Arrays.asList(new User("tom", "111"),
new User("jack", "222"));
session.setAttribute("userList",users);
HashMap<String, User> map = new HashMap<>();
map.put("user1",new User("tom","111"));
map.put("user2",new User("jack","222"));
request.setAttribute("map",map);
%>
<hr>
${sessionScope.username}
<hr>
${username}
<hr>
${user.username}
${user.getUsername()}
<hr>
${userList.get(0).username}
<hr>
${userList[0].username}
<hr>
${map.user1.password}
<hr>
${map["user2"].username}
</body>
</html>
JSTL
java server pages standard tag library:jsp 标准标签库。
使用JSTL可以在jsp页面中,将复杂的程序结构简化,可读性高。
使用JSTL的前提:
1、导入jar包 jstl.jar standard.jar
2、使用taglib指令引入jstl的核心标签库。
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
实现使用中,jstl一定配合EL表达式来使用。
案例-1:
servlet
@WebServlet("/user")
public class UserServlet extends BaseServlet {
public String findAll(HttpServletRequest request, HttpServletResponse response){
//向请求对象中保存数据
request.setAttribute("user",new User("tom","111"));
return "f:/JSTL.jsp";
}
}
jsp
<%--
jstl
c:out 作用:将内容写出到浏览器中
c:set 作用:用于赋值
target指定操作的是哪个对象
property指定操作的是对象的哪个属性
value要赋的值是什么
c:remove 作用:从作用域中移除一个key
--%>
<c:out value="${user.username}"/>
<hr>
<c:set target="${user}" property="username" value="jack"/>
<c:remove var="user"/>
<c:out value="${user.username}"/>
案例-2
servlet
package com.woniuxy.servlet;
import com.woniuxy.commons.BaseServlet;
import com.woniuxy.model.User;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
@WebServlet("/user")
public class UserServlet extends BaseServlet {
public String findAll(HttpServletRequest request, HttpServletResponse response){
//向请求对象中保存数据
request.setAttribute("user",new User("tom","111"));
request.setAttribute("userList",
Arrays.asList(new User("tom","111")
,new User("jack","222")
,new User("rose","333")
,new User("jerry","444")));
return "f:/JSTL.jsp";
}
}
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>jstl的使用</title>
</head>
<body>
<%--
jstl
c:out 作用:将内容写出到浏览器中
c:set 作用:用于赋值
target指定操作的是哪个对象
property指定操作的是对象的哪个属性
value要赋的值是什么
c:remove 作用:从作用域中移除一个key
c:catch 作用:相当于try...catch
c:if 作用:相当于java中的if结构
test指定进行判断的条件
c:import 作用:导入外部资源 类似于jsp:include
url指定要导入的资源路径
c:choose 作用:相当于java中的switch结构,它必须配合c:when 和 c:otherwise使用
c:when 相当于 switch结构中的case
c:otherwise 相当于switch结构中的default
c:url 作用:指定一个url
c:redirect 作用:相当response.sendRedirect()
该标签一般和c:if或c:choose配合使用。
c:foreach 作用:相当于java中for
--%>
<c:out value="${user.username}"/>
<hr>
<c:set target="${user}" property="username" value="jack"/>
<%-- <c:remove var="user"/>--%>
<c:out value="${user.username}"/>
<c:catch var="e">
<% int i=1/0; %>
</c:catch>
<c:if test="${e!=null}">
<c:out value="${e.message}"/>
</c:if>
<c:import url="a.jsp"/>
<hr>
<c:choose>
<c:when test="${user.username=='tom'}">tom</c:when>
<c:when test="${user.username=='jack'}">jack</c:when>
<c:otherwise>jacky</c:otherwise>
</c:choose>
<hr>
<a href="<c:url value="http://www.baidu.com"/>">百度</a>
<hr>
<%-- <c:redirect url="a.jsp"/>--%>
<hr>
<%--
c:foreach 作用:相当于java中for
items :指定要进行遍历的集合,EL表达式从域中获取对应的集合
var :每次遍历时,从集合中取到的对象
begin :指定从集合的哪个位置开始
end :指定遍历到集合的哪个位置结束
step :步长 循环变量的增量
varStatus :用于指定当前遍历的对象相关属性 index:下标,从0开始 count:第几个,从1开始
一般使用varStatus来完成隔行变色的操作
--%>
<table>
<c:forEach items="${userList}" var="user" varStatus="v">
<tr <c:if test="${v.index%2==0}">
style="background: red"
</c:if>>
<td>${user.username}</td>
<td>${user.password}</td>
</tr>
</c:forEach>
</table>
</body>
</html>