JSP
一、简介
JSP(全称JavaServer Pages)java服务器⻚⾯。 是⼀种动态⽹⻚技术标准。JSP部署于⽹络服务器上,可以响应客户端发送的请求,并根据请求内容动态地⽣成HTML、XML或其他格式⽂档的Web⽹⻚,然后返回给请求者。
JSP技术以Java语⾔作为脚本语⾔,为⽤户的HTTP请求提供服务,并能与服务器上的其它Java程序共同处理复杂的业务需求,是简化版的Servlet。执⾏的过程为 xxx.jsp---->xxx.java---->xxx.class
二、使用策略
1、纯碎的HTML使⽤
语法和使⽤HTML的⽤法完全⼀样,可以包含css,javaScript,Jquery等
2、纯粹的Servlet使⽤
以<% java代码⽚段 %>写法显示在jsp⻚⾯,相当于Servlet中的service⽅法 如果是Java代码写成什么样显示什么样
3、HTML + Servlet使⽤
如果写的html代码 相当于 out.write("")
但是我们需要注意:
jsp 只⽤来显示数据 不处理业务
Servlet 只处理业务
三、核心内容、
3.1、三大指令
3.1.1、page指令
<%@page 属性名="值" 属性名="值" %> 控制整个jsp⻚⾯的配置信息
language="java" ⽀持的语⾔
contentType="text/html; charset=UTF-8" 内容类型
pageEncoding="UTF-8" ⻚⾯的编码格式
import="java.util.List,java.util.ArrayList" 导⼊jar
autoFlush="true" ⾃动刷新
errorPage="03-error.jsp" 如果当前⻚⾯抛异常 跳转指定⻚⾯
session="true" 当前⻚⾯中可以直接使⽤该对象
isELIgnored="false" 是否忽略EL表达式
3.1.2、include指令
⻚⾯包含说的是⼀个⻚⾯可以包含另⼀个⻚⾯的内容,并且能正常加载。
语法:<% @include file=”被包含的⻚⾯名称” %>
作⽤:include指令的主要作⽤:可以将⻚⾯公共的部分提取出来,让每个⻚⾯包含这个公共的⻚⾯,⼀是为了减少代码量,⼆是易于⼿续的维护。
3.1.3、taglib指令
后⾯使⽤JSTL标准标签库时使⽤。
语法:<%@taglib prefix=“前缀” uri=“引⼊外部标签库的路径” %>
3.2、六大动作
【作⽤】: JSP动作标签利⽤XML语法格式的标记来控制Servlet引擎的⾏为。利⽤JSP动作可以动态地插⼊⽂件、重⽤JavaBean组件、把⽤户重定向到另外的⻚⾯、为Java插件⽣成HTML代码。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>六大动作</title>
</head>
<body>
<h2>六大动作</h2>
<%-- 1. 完全转发--%>
<%--6. 转发携带参数--%>
<jsp:forward page="/myServlet">
<jsp:param name="xx" value="haha"/>
</jsp:forward>
<%--2. 不完全转发--%>
<jsp:include page="01-three.jsp"></jsp:include>
<%--3. 使用JavaBean对象--%>
<jsp:useBean id="user" class="com.ujiuye.bean.User"></jsp:useBean>
<%-- 4. 对象属性赋值--%>
<jsp:setProperty name="user" property="username" value="小天天"></jsp:setProperty>
<%-- 5. 获取对象属性值--%>
<jsp:getProperty name="user" property="username"/>
</body>
</html>
【面试题:】
⾯试题:动态包含和静态包含有什么区别?
1、写法不同:
静态包含是指令包含<% @include file= ”***” %>
动态包含是JSP动作标签包含< jsp: include page= “***” > < / jsp:include >
2、编译⽅式不同:
静态包含:编译过程中将被包含的⻚⾯先整合到包含⻚⾯再编译。所以只有⼀个⽂件
动态包含:编译过程中包含的⻚⾯与被包含的⻚⾯都编译,运⾏后内容再通过servlet整合
3、参数传递:
静态包含不能向被包含⻚⾯传递参数
动态包含可以使⽤jsp:param标签向被包含⻚⾯传递参数
4、运⾏效率:
静态包含快,当成了⼀个⻚⾯;动态包含是多个⻚⾯,运⾏慢
3.3、九大内置对象
内置对象:也称隐式对象,在jsp中,已经初始化好并且给我们封装好了,不需要程序员创建,可以直接使⽤的对象就是内置对象。
对象名 功能 类型
Out ⻚⾯输出对象 JspWriter
Exception 异常处理对象 Throwable
Page 描述⻚⾯的对象 Object
PageContext ⻚⾯的全局对象【作⽤域】 PageContext
Request 请求对象【作⽤域】 HttpServletRequest
Response 响应对象 HttpServletResponse
Session 会话对象【作⽤域】 HttpSession
Config 配置 ServletConfig
Application 服务器对象【作⽤域】 ServletContext
这些内置对象在Jsp⻚⾯都是存在的,我们可以直接使⽤;
这⾥默认能显示的内置对象共8个,还有⼀个特殊的对象Exception关于异常的,只有在page指令中设置
isErrorPage="true"时才会显示。
可以通过以下⽅式获取:
pageContext.getException() //获取异常对象
3.3.1、对象详解
-
application 对象可将信息保存在服务器中,直到服务器关闭,否则application对象中保存的信息会在
整个应⽤中都有效。该对象的类型是SevletContext类型,它的⽣命周期在tomcat服务器启动时创建,关闭时
销毁。其作⽤范围为整个Web应⽤。
// 最大域对象中保存数据
application.setAttribute("sc", "最大域对象中的数据!");
// 获取最大域对象数据
Object sc = application.getAttribute("sc");
-
request 对象是 javax.servlet.HttpServletRequest类型的对象。该对象代表了客户端的请求信
息,主要⽤于接受通过HTTP协议传送到服务器的数据。request对象的作⽤域为⼀次请求。
// 一次请求域对象中保存数据
request.setAttribute("req", "一次请求的域对象数据");
// 获取一次请求中的域对象数据
Object req = request.getAttribute("req");
-
response 对象是 javax.servlet.HttpServletRsponse类型的对象。该对象代表客户端的响应信息,
主要是将JSP容器处理过的对象信息返回到客户端。
-
config 对象的主要作⽤是取得服务器的配置信息。通过 pageConext对象的 getServletConfig() ⽅
法可以获取⼀个config对象。当⼀个Servlet 初始化时,容器把某些信息通过 config对象传递给这个
Servlet。 开发者可以在web.xml ⽂件中为应⽤程序环境中的Servlet程序和JSP⻚⾯提供初始化参数。
-
page:当前jsp⻚⾯的实例,相当于this关键字。
-
session:会话对象。session 对象是由服务器⾃动创建与⽤户请求相关的对象。服务器为每个⽤户都⽣成
⼀个session对象,⽤于保存该⽤户的信息,跟踪⽤户的操作状态。其作⽤范围为⼀次会话。
// 会话域对象中保存数据
session.setAttribute("se", "一次会话的域对象数据");
// 获取一次会话的域对象数据
Object se = session.getAttribute("se");
-
exception对象的作⽤是显示异常信息,只有在包含 isErrorPage=“true” 的⻚⾯中才可以被使⽤,在⼀
般的JSP⻚⾯中使⽤该对象将⽆法编译JSP⽂件。excepation对象和Java的所有对象⼀样,都具有系统提供的
继承结构。exception 对象⼏乎定义了所有异常情况。在Java程序中,可以使⽤try/catch关键字来处理异
常情况; 如果在JSP⻚⾯中出现没有捕获到的异常,就会⽣成 exception 对象,并把 exception 对象传送
到在page指令中设定的错误⻚⾯中,然后在错误⻚⾯中处理相应的 exception 对象。
-
out 对象⽤于在Web浏览器内输出信息,并且管理应⽤服务器上的输出缓冲区。JSP中的out对象是
JspWriter类型。
-
pageContext 对象的作⽤是取得任何范围的参数,通过它可以获取 JSP⻚⾯的out、request、reponse、session、application 等对象。pageContext对象的创建和初始化都是由容器来完成的,可以获取项⽬的根⽬录,还可通过getXXX()获取其他内置对象
// 最小的域对象 相当于局部变量
pageContext.setAttribute("pc", "最小域对象中的数据");
// 操作其他内置对象
pageContext.setAttribute("sc1", "app中数据", PageContext.APPLICATION_SCOPE);
pageContext.setAttribute("se1", "session中数据", PageContext.SESSION_SCOPE);
pageContext.setAttribute("req1", "request中数据", PageContext.REQUEST_SCOPE);
request.getRequestDispatcher("03-get.jsp").forward(request, response);
3.3.2、作用域
1、作用
为了在⻚⾯、请求、和⽤户之间传递和共享数据,JSP提供了四个不同的作⽤域:pageContext(⻚⾯作⽤
域)、request(请求作⽤域)、session(会话作⽤域)、application(应⽤程序作⽤域),这些作⽤域
就规定了数据可以传递和共享的范围以及数据的存活时间。
2、详解
1、application 作⽤域
如果把变量放到application⾥,就说明它的作⽤域是application,它的有效范围是整个应⽤。 整个应
⽤是指从应⽤启动,到应⽤结束。我们没有说“从服务器启动,到服务器关闭”,是因为⼀个服务器可能部署多个
应⽤,当然你关闭了服务器,就会把上⾯所有的应⽤都关闭了。 application作⽤域⾥的变量,它们的存活时
间是最⻓的,如果不进⾏⼿⼯删除,它们就⼀直可以使⽤。
application作⽤域上的信息传递是通过ServletContext实现的,它提供的主要⽅法如下所示:
Object getAttribute(String name) //从application中获取信息;
void setAttribute(String name, Object value) //向application作⽤域中设置信息。
2、session作⽤域
session作⽤域⽐较容易理解,同⼀浏览器对服务器进⾏多次访问,在这多次访问之间传递信息,就session作⽤域的体现。如果把变量放到session⾥,就说明它的作⽤域是session,它的有效范围是当前会话。所谓当前会话,就是指从⽤户打开浏览器开始,到⽤户关闭浏览器这中间的过程。这个过程可能包含多个请求响应。也就是说,只要⽤户不关浏览器,服务器就有办法知道这些请求是⼀个⼈发起的,整个过程被称为⼀个会话(session),⽽放到会话中的变量,就可以在当前会话的所有请求⾥使⽤。
session是通过HttpSession接⼝实现的,它提供的主要⽅法如下所示:
Object HttpSession.getAttribute(String name) //从session中获取信息。
void HttpSession.setAttribute(String name, Object value)//向session中保存信息。
HttpSession HttpServletRequest.getSessio() //获取当前请求所在的session的对象。
session的开始时刻⽐较容易判断,它从浏览器发出第⼀个HTTP请求即可认为会话开始。但结束时刻就不好判断了,因为浏览器关闭时并不会通知服务器,所以只能通过如下这种⽅法判断:如果⼀定的时间内客户端没有反应,则认为会话结束。Tomcat的默认值为30分钟,但这个值也可以通过HttpSession的
setMaxInactiveInterval()⽅法来设置:
void setMaxInactiveInterval(int interval)
如果想主动让会话结束,例如⽤户单击“注销”按钮的时候,可以使⽤ HttpSession 的 invalidate()⽅
法,⽤于强制结束当前session:void invalidate()
3、request作⽤域
⼀个HTTP请求的处理可能需要多个Servlet合作,⽽这⼏个Servlet之间可以通过某种⽅式传递信息,但这个信息在请求结束后就⽆效了。request⾥的变量可以跨越forward前后的两⻚。但是只要刷新⻚⾯,它们就重新计算了。如果把变量放到request⾥,就说明它的作⽤域是request,它的有效范围是当前请求周期。 所谓请求周期,就是指从http请求发起,到服务器处理结束,返回响应的整个过程。在这个过程中可能使forward的⽅式跳转了多个jsp⻚⾯,在这些⻚⾯⾥你都可以使⽤这个变量。Servlet之间的信息共享是通过HttpServletRequest接⼝的两个⽅法来实现的:void setAttribute(String name, Object value)//将对象value以name为名称保存到request作⽤域中。
Object getAttribute(String name) //从request作⽤域中取得指定名字的信息。
JSP中的doGet()、doPost()⽅法的第⼀个参数就是HttpServletRequest对象,使⽤这个对象的
setAttribute()⽅法即可传递信息。那么在设置好信息之后,要通过何种⽅式将信息传给其他的Servlet呢?
这就要⽤到RequestDispatcher接⼝的forward()⽅法,通过它将请求转发给其他Servlet。
RequestDispatcher ServletContext.getRequestDispatcher(String path) //取得Dispatcher以便转发,path为转发的⽬的Servlet。
void RequestDispatcher.forward(ServletRequest request, ServletResponse response)//
将request和response转发
因此,只需要在当前Servlet中先通过setAttribute()⽅法设置相应的属性,然后使⽤forward()⽅法进
⾏跳转,最后在跳转到的Servlet中通过使⽤getAttribute()⽅法即可实现信息传递。
4、pageContext作⽤域
page对象的作⽤范围仅限于⽤户请求的当前⻚⾯,对于page对象的引⽤将在响应返回给客户端之后被释放,
或者在请求被转发到其他地⽅后被释放。page⾥的变量只要⻚⾯跳转了,它们就不⻅了。如果把变量放到
pageContext⾥,就说明它的作⽤域是page,它的有效范围只在当前jsp⻚⾯⾥。从把变量放到pageContext
开始,到jsp⻚⾯结束,你都可以使⽤这个变量。
两个⻚⾯03-四⼤作⽤域.jsp ,04-四⼤作⽤域02.jsp
03-四⼤作⽤域.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title>
</head> <body> <%
pageContext.setAttribute("name","张三");
request.setAttribute("password","123456");
session.setAttribute("sex","男");
application.setAttribute("hobby","旅游,学习");
//转发
request.getRequestDispatcher("04-四⼤作⽤域02.jsp").forward(request,response);
%>
<!--获取数据并输出-->
<%
Object name = pageContext.getAttribute("name");
Object password = pageContext.getAttribute("password");
Object sex = pageContext.getAttribute("sex");
Object hobby = pageContext.getAttribute("hobby");
%>
当前⻚的pageContext中name值:<%=name%> <br>
当前⻚request中password的值:<%=password%> <br>
当前⻚session中sex的值:<%=sex%> <br>
当前⻚application中hobby的值:<%=hobby%>
</body>
</html>
04-四⼤作⽤域02.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title>
</head> <body>
<!--获取保存在作⽤域对象中的数据-->
<%
Object name = pageContext.getAttribute("name");
Object password = request.getAttribute("password");
Object sex = session.getAttribute("sex");
Object hobby = application.getAttribute("hobby");
%>
当前⻚的pageContext中name值:<%=name%> <br>
当前⻚request中password的值:<%=password%> <br>
当前⻚session中sex的值:<%=sex%> <br>
当前⻚application中hobby的值:<%=hobby%>
</body>
</html>
作⽤域⼤⼩排序:
从⼩到⼤: pageContext < request < session < application
3.4、EL表达式
3.4.1、简介
EL(Expression Language) 是为了使JSP写起来更加简单。表达式语⾔的灵感来⾃于 ECMAScript 和XPath 表达式语⾔,它提供了在 JSP 中简化表达式的⽅法,让Jsp的代码更加简化。
3.4.2、作用
是⼀种在JSP⻚⾯获取数据的简单⽅式(只能获取数据,不能设置数据)通过以下⽅式:
在JSP⻚⾯的任何静态部分均可通过:${expression}来获取到指定表达式的值
包含以下⼏种⽅式:
${绑定名} 获取javaBean对象或者其他类型数据
${绑定名.属性名} 获取javaBean中对应的属性名
${绑定名[索引值]} 获取集合或者数组中对应的值
${绑定名[“key”]} 通过key的值获取在Map中对应的value值
同样也可以在el表达式内部做⼀些简单的运算:
Map<String, Map<String, Map<String, Person>>> map = new HashMap<>();
Person person = new Person(1001, "小明明", new XiFu(001, "翠花"));
Map<String, Person> map1 = new HashMap<>();
map1.put("p", person);
Map<String, Map<String, Person>> map2 = new HashMap<>();
map2.put("map1", map1);
map.put("map2", map2);
request.setAttribute("map", map);
// 获取小明明媳妇名字
/**
* 原理:
* map.get("map2") -----> map.map2
* map2.get("map1") -----> map2.map1
* map1.get("p") -----> map1.p
* p.getXiFu() -----> p.xiFu
* xiFu.getName() -----> xiFu.name
**/
3.4.4、原理
依次从四⼤作⽤域对象检索对应的绑定名,如果在某⼀个对象中获取到了,则不再去其他对象检索,否则继续检索,如果都没有查找到则返回的是⼀个空字符串,⽽不是null如果如下操作时:以表达式${user.name}为例EL表达式会根据name去User类⾥寻找这个name的get⽅法,此时会⾃动把name⾸字⺟⼤写并加上get前缀,⼀旦找到与之匹配的⽅法,El表达式就会认为这就是要访问的属性,并返回属性的值。所以,想要通过EL表达式获取对象属性的值,那么这个属性就必须有与之对应的get⽅法。
可以通过指定检索四⼤作⽤域对象来提升检索速度,如下:
application–>applicationScope
session–>sessionScope
request–>requestScope
pageContext–>pageScope
⽐如:
${requestScope.user} 表示直接去request对象中获取user绑定名对应的值
【案例】
ElDemoServlet
package com.ujiuye.servlet;
import com.ujiuye.bean.User;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@WebServlet("/elDemo")
public class ElDemoServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, IOException {
//解决乱码问题的两⾏代码
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//开始绑定数据
//1.绑定⼀个字符串数据
req.setAttribute("uname","邓紫棋");
//2.绑定⼀个Map对象数据
Map<String,String> map = new HashMap<>();
map.put("name","张飒");
req.setAttribute("map",map);
//3.绑定⼀个List集合数据
List<String> list = new ArrayList<>();
list.add("三国演义");
list.add("红楼梦");
req.setAttribute("list",list);
//4.绑定⼀个数组对象
int[] arr ={12,89,10};
req.setAttribute("arr",arr);
//5.绑定⼀个javaBean对象
User u = new User("李思思","666666");
req.setAttribute("user",u);
//转发
req.getRequestDispatcher("06-el表达式常⽤⽅式.jsp").forward(req,resp);
}
}
⻚⾯06-el表达式常⽤⽅式.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>el表达式常⽤⽅式</title>
</head> <body>
el获取字符串数据:${uname} <br>
el获取Map对象中name对应的value值:${map["name"]} <br>
el获取List集合中第⼆个数组:${list[1]} <br>
el获取数组的第⼀个数据:${arr[0]} <br>
el获取javaBeand的username属性值:${user.username}
</body>
</html>
3.5、JSTL 标签库
3.5.1、简介
JSTL(JavaServer Pages Standard Tag Library,JSP标准标签库)是⼀个不断完善的开放源代码的JSP标签库。它主要提供给JavaWeb开发⼈员⼀个标准通⽤的标签,开发⼈员可以利⽤这些标签取代JSP⻚⾯上的Java代码,从⽽提⾼程序的可读性,降低程序的维护难度。需要注意的是:jstl中需要获取值的地⽅⼀般都要配合EL表达式去使⽤
3.5.2、使用
1、 下载导包:jstl.jar standard.jar 两个包
2、将标签库引⼊ ⻚⾯中
<%-- 引⼊标签库 --%>
<%@taglib uri=“http://java.sun/jsp/jstl/core” prefix=“c” %>
3、使⽤
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun/jsp/jstl/core" %>
<html>
<head>
<title>jstl的使用</title>
</head>
<body>
<%
User user = new User(1001, "小翠");
session.setAttribute("user", user);
%>
<%-- 1. 判读标签--%>
<c:if test="${empty user}">
<h2>您好,请登录!</h2>
</c:if>
<c:if test="${!empty user}">
<h2>欢迎您:${user.username }</h2>
</c:if>
<%-- 2. 定义变量--%>
<c:set var="num" value="180"></c:set>
<%-- 3. 变量输出--%>
<c:out value="${num }" default="没有该变量"></c:out>
<%-- 4. 删除变量--%>
<c:remove var="num"></c:remove>
<c:out value="${num }" default="没有该变量"></c:out>
<%-- 5. choose多分⽀标签--%>
<c:choose>
<c:when test="${num>100 }">
VIP老白菜
</c:when>
<c:when test="${num>80 }">
VIP大白菜
</c:when>
<c:when test="${num>50 }">
VIP小白菜
</c:when>
<c:otherwise>
VIP没白菜
</c:otherwise>
</c:choose>
<hr>
<%-- 6. 循环标签--%>
<c:forEach begin="1" end="100" step="1" var="i">
${i }
</c:forEach>
<%
List<Person> list = new ArrayList<>();
list.add(new Person(101, "小江江", new XiFu(001, "翠花")));
list.add(new Person(102, "小军军", new XiFu(002, "小翠")));
list.add(new Person(103, "小伟伟", new XiFu(003, "小美丽")));
list.add(new Person(104, "小亮亮", new XiFu(004, "小栾栾")));
list.add(new Person(105, "小康康", new XiFu(005, "小鑫鑫")));
request.setAttribute("list", list);
%>
<table border="1" cellspacing="0" width="400" align="center">
<tr>
<th>用户编号</th>
<th>用户姓名</th>
<th>媳妇编号</th>
<th>媳妇名字</th>
</tr>
<c:forEach items="${list }" var="p">
<tr>
<td>${p.id }</td>
<td>${p.pname }</td>
<td>${p.xiFu.id }</td>
<td>${p.xiFu.name1 }</td>
</tr>
</c:forEach>
</table>
</body>
</html>
更多推荐
JSP 新手入门理解教程(附带案例)
发布评论