JSP的引入
Servlet的作用: 用java语言开发动态资源的技术!!! Jsp的作用:用java语言(+html语言)开发动态资源的技术!!! Jsp就是servlet!!! |
JSP的特点:
1)jsp的运行必须交给tomcat服务器!!!! tomcat的work目录: tomcat服务器存放jsp运行时的临时文件 2)jsp页面既可以写html代码,也可以写java代码。 (html页面不能写java代码 。而jsp页面可以写java代码) |
JSP初体验
需求:显示当前时间到浏览器上 可以把jsp页面当做html页面在tomcat中访问!!! |
01.hello.jsp 代码:
<%@ page language="java" import="java.util.*,java.text.*,java.io.*" pageEncoding="utf-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>第一个jsp页面</title> </head> <body> <% //写java代码 //获取当前时间 SimpleDateFormat sdf = new SimpleDateFormat(); String curDate = sdf.format(new Date()); //输出内容到浏览器 //response.getWriter().write(""); out.write("当前时间为:"+curDate); %> </body> </html> |
当前时间为:17-9-25 下午12:23 |
JSP的执行流程:
问题: 访问http://localhost:8080/day12/01.hello.jsp 如何显示效果? 1)访问到01.hello.jsp页面,tomcat扫描到jsp文件,在%tomcat%/work把jsp文件翻译成java源文件 (01.hello.jsp -> _01_hello_jsp.java) (翻译) 2)tomcat服务器把java源文件编译成class字节码文件 (编译) (_01_hello_jsp.java -> _01_hello_jsp.class) 3)tomcat服务器构造_01_hello_jsp类对象 4)tomcat服务器调用_01_hello_jsp类里面方法,返回内容显示到浏览器。 第一次访问jsp: 走(1)(2)(3)(4) 第n次访问jsp: 走(4) 注意:1)jsp文件修改了或jsp的临时文件被删除了,要重新走翻译(1)和编译(2)的过程 |
JSP和Servlet的关系:
jsp翻译的java文件: public final class _01_hello_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent { HttpJspBase类: public abstract class org.apache.jasper.runtime.HttpJspBase extends javax.servlet.http.HttpServlet implements javax.servlet.jsp.HttpJspPage { |
可以看到,继承了HTTPServlet类
结论: Jsp就是一个servlet程序!!! servlet的技术可以用在jsp程序中 jsp的技术并不是全部适用于servlet程序! |
JSP和Servlet的生命周期对比:
Servlet的生命周期: 1)构造方法(第1次访问) 2)init方法(第1次访问) 3)service方法 4)destroy方法 Jsp的生命周期 1)翻译: jsp->java文件 2)编译: java文件->class文件(servlet程序) 3)构造方法(第1次访问) 4)init方法(第1次访问):_jspInit() 5)service方法:_jspService() 6)destroy方法:_jspDestroy() |
JSP表达式
语法:<%=变量或表达式%> 作用: 向浏览器输出变量的值或表达式计算的结果 注意: 1)表达式的原理就是翻译成out.print(“变量” );通过该方法向浏览器写出内容 2)表达式后面不需要带分号结束。 |
JSP脚本
语法:<%java代码 %> 作用: 执行java代码 (定义的变量是局部的变量) 注意: 1)原理把脚本中java代码原封不动拷贝到_jspService方法中执行。 2)脚本中是不可以定义方法的,原因是脚本的代码会被拷贝带_jspService 方法中,方法中 是不能在定义方法 |
JSP生命
语法:<%! 变量或方法 %> 作用: 声明jsp的变量或方法(定义的变量是全局的变量和方法) 注意: 1)变量翻译成成员变量,方法翻译成成员方法。 |
例子:
<!-- jsp脚本 --> <% //变量 String name = "eric"; int a = 10; int b =20; %> <!-- JSP声明 --> <%! String name = "jarry"; %> <%--JSP表达式: 同名时,局部变量会覆盖全局变量,打印的是局部变量--%> <%=name %> |
打印输出:eric |
JSP注释
<!-- html注释 --> <%-- jsp注释 --%> |
html的注释会被翻译和执行。而jsp的注释不能被翻译和执行 |
JSP的三大指令
include指令
作用: 在当前页面用于包含其他页面 语法: <%@include file="common/header.jsp"%> 注意: 1)原理是把被包含的页面(header.jsp)的内容翻译到包含页面(index.jsp)中,合并成翻译成一个java源文件,再编译运行!!,这种包含叫静态包含(源码包含) 2)如果使用静态包含,被包含页面中不需要出现全局的html标签了!!!(如html、head、body) |
|
Head.jsp文件代码:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> 头部页面的内容wwwwwww <br/> |
Index.jsp文件代码:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>网站首页</title> </head> <body> <%@include file="common/header.jsp"%> 首页的内容xxxxxxx </body> </html> |
Page指令:
作用: 告诉tomcat服务器如何翻译jsp文件 <%@ page language="java" --告诉服务器使用什么动态语言来翻译jsp文件 import="java.util.*" --告诉服务器java文件使用什么包导入包,多个包之间用逗号分割 pageEncoding="utf-8" --告诉服务器使用什么编码翻译jsp文件(成java文件) contentType="text/html; charset=utf-8" 服务器发送浏览器的数据类型和内容编码 注意:在开发工具中,以后只需要设置pageEncoding即可解决中文乱码问题 buffer="8kb" session="true" isELIgnored="false" |
异常错误相关的: errorPage: 指定当前jsp页面的错误处理页面。 isErorrPage: 指定当前页面是否为错误处理页面。false,不是错误处理页面, 则 不能使用exception内置对象;true,是错误处理页面,可以使用exception内置对象。 配置全局的错误处理页面: |
<!-- 全局错误处理页面配置 --> <error-page> <error-code>500</error-code> <location>/common/500.jsp</location> </error-page> <error-page> <error-code>404</error-code> <location>/common/404.html</location> </error-page> |
session: 是否开启session功能。 false,不能用session内置对象; true,可以使用session内置对象。 buffer: jsp页面的缓存区大小。 isELIgnore: 是否忽略EL表达式。 |
JSP的内置对象:
内置对象的概念:
在jsp开发中,会频繁使用到一些对象 。例如HttpSession,ServletContext,,HttpServletRequet。如果我们每次要使用这些对象都去创建这些对象就显示非常麻烦。所以Sun公司设计Jsp时,在jsp页面加载完毕之后就会自动帮开发者创建好这些对象,而开发者只需要直接使用这些对象调用方法即可!,这些创建好的对象就叫内置对象! |
举例: servlet: HttpSession session = request.getSession(true); (需要开发者做) jsp: tomcat服务器: HttpSession session = request.getSession(true);(不需要开发者做) 开发者做的: session.getId(); |
九大内置对象:
内置对象名 对应的类 request HttpServletRequest response HttpServletResponse config ServletConfig application ServletContext session HttpSession exception Throwable out JspWriter page Object(this) pageContext PageContext |
Out对象:
out对象类型,JspWriter类,相当于带缓存的PrintWriter PrintWriter: wrier(内容): 直接向浏览器写出内容。 JspWriter writer(内容): 向jsp缓冲区写出内容 当满足以下条件之一,缓冲区内容写出: 1)缓冲区满了 2)刷新缓存区 3)关闭缓存区 4)执行完毕jsp页面 |
PageContext对象:
pageContext对象的类型是PageContext,叫jsp的上下文对象
可以获取其它八个内置对象
ServletRequest request2 = pageContext.getRequest(); ServletResponse response2 = pageContext.getResponse(); pageContext.getServletConfig(); pageContext.getServletContext(); pageContext.getSession(); pageContext.getException(); pageContext.getOut(); pageContext.getPage(); |
在自定义标签的时候,PageContext对象频繁使用到!!! |
四大域对象:
类 域范围 ServletContext context域 HttpServletRequet request域 HttpSession session域 --Servlet学习的 PageContext page域 --jsp学习的 |
作用: 保存数据和获取数据,用于共享数据 |
四个域对象: Jsp内置对象 域范围 pageContext page域 request request域 session session域 application context域 |
#保存数据 1)默认情况下,保存到page域 pageContext.setAttribute("name"); 2)可以向四个域对象保存数据 pageContext.setAttribute("name",域范围常量 #获取数据 1)默认情况下,从page域获取 pageContext.getAttribute("name") 2)可以从四个域中获取数据 pageContext.getAttribute("name",域范围常量) 域范围常量: PageContext.PAGE_SCOPE PageContext.REQUEST_SCOPE PageContext..SESSION_SCOPE PageContext.APPLICATION_SCOPE 3)自动在四个域中搜索数据 pageContext.findAttribute("name"); 顺序: page域 -> request域 -> session域- > context域(application域) |
3)域对象作用范围: page域: 只能在当前jsp页面中使用(当前页面) request域: 只能在同一个请求中使用(转发) session域: 只能在同一个会话(session对象)中使用(私有的) context域: 只能在同一个web应用中使用。(全局的) |
例子: |
<% pageContext.setAttribute("message","page‘s message"); pageContext.setAttribute("message","request‘s messsage",PageContext.REQUEST_SCOPE);//保存到request域中 pageContext.setAttribute("message","session‘s messsage",PageContext.SESSION_SCOPE);//保存到sessio域中 pageContext.setAttribute("message","application‘s messsage",PageContext.APPLICATION_SCOPE);//保到context域中 %> |
page域:<%=pageContext.getAttribute("message",PageContext.PAGE_SCOPE) %><br/> request域: <%=pageContext.getAttribute("message",PageContext.REQUEST_SCOPE) %><br/> session域: <%=pageContext.getAttribute("message",PageContext.SESSION_SCOPE) %><br/> context域:<%=pageContext.getAttribute("message",PageContext.APPLICATION_SCOPE) %><br/> |
打印的结果: |
page域:null request域: null session域: session‘s messsage context域:application‘s messsage |
findAttribute(): 在四个域自动搜索数据 顺序: page域 -> request域 -> session域 -> context域 <%=pageContext.findAttribute("message") %> |
JSP+Servlet的模式
Servlet技术: 开发动态资源。是一个java类,最擅长写java代码 jsp技术: 开发动态资源。通过java代码,最擅长输出html代码。 |
servlet+jsp模式 servlet: 优点 1)接收参数 2)处理业务逻辑 3)把结果保存到域对象中 4)跳转到jsp页面 Jsp:优点 1)从域对象取出数据 2)把数据显示到浏览器 servlet的数据 -> jsp页面 List<Contact> 使用域对象 共享数据 |
EL表达式
开发jsp的原则: 尽量在jsp页面中少写甚至不写java代码。 使用EL表达式替换掉jsp表达式
EL表达式作用: 向浏览器输出域对象中的变量值或表达式计算的结果!!!
语法: ${变量或表达式} |
输出基本类型的变量
1.1 从四个域获取 ${name} 1.2 指定域获取 ${pageScope.name} 域范围: pageScoep / requestScope / sessionScope / applicationScope |
例子: |
<body> <% String name = "rose"; //放入域中 pageContext.setAttribute("name",name); pageContext.setAttribute("name",name,PageContext.REQUEST_SCOPE); %> 1)从四个域自动搜索 : <br/> EL表达式: ${name } <br/> 等价于 <%=pageContext.findAttribute("name")%> <br/> 2)从指定的域中获取数据 <br/> EL表达式: ${pageScope.name }; <br/> EL表达式: ${requestScope.name }; </body> |
打印结果: 1)从四个域自动搜索 : EL表达式: rose 等价于 rose 2)从指定的域中获取数据 EL表达式: rose; EL表达式: rose; |
输出对象的属性值和输出集合对象
Student类,有name和age属性,这二个属性的get方法和set方法,
JSP文件 代码
<body> <%-- 1)EL输出对象的属性 --%> <% //保存数据 Student student = new Student("eric",20); //放入域中 pageContext.setAttribute("student",student); //List List<Student> list = new ArrayList<Student>(); list.add(new Student("rose",18)); list.add(new Student("jack",28)); list.add(new Student("lucy",38)); //放入域中 pageContext.setAttribute("list",list); //Map Map<String,Student> map = new HashMap<String,Student>(); map.put("100",new Student("mark",20)); map.put("101",new Student("maxwell",30)); map.put("102",new Student("narci",40)); //放入域中 pageContext.setAttribute("map",map); %> <%--使用EL获取对象 --%> ${student.name} - ${student.age } <%-- ${student.name} 等价于 (点相对于调用getXX()方法) <%=((Student)pageContext.findAttribute("student")).getName()%> --%> <hr/> <%--使用EL获取List对象 --%> ${list[0].name } - ${list[0].age }<br/> ${list[1].name } - ${list[1].age }<br/> ${list[2].name } - ${list[2].age } <%-- list[0]等价于 (中括号相对于调用get(参数)方法) ((List)pageContext.findAttribute("list")).get(0) --%> <hr/> <%--使用EL获取Map对象 --%> ${map[‘100‘].name } - ${map[‘100‘].age }<br/> ${map[‘101‘].name } - ${map[‘101‘].age }<br/> ${map[‘102‘].name } - ${map[‘102‘].age }<br/> </body> |
打印结果 eric - 20 |
rose - 18 jack - 28 lucy - 38 |
mark - 20 maxwell - 30 narci - 40 |
EL表达式判断对象非空
<body> <%-- 4)判空 null 或 空字符串: empty --%> <% Student student = null; String name = ""; pageContext.setAttribute("name",name); %> 判断null: ${name==null }<br/> 判断空字符: ${name=="" }<br/> 判空: ${name==null || name=="" } <br/> 另一种判空写法: ${empty student } <br/> ${empty name } </body> |
判断null: false 判断空字符: true 判空: true 另一种判空写法: true true |
JSP标签
jsp标签作用:替换jsp脚本。
JSP标签的分类:
1)内置标签(动作标签): 不需要在jsp页面导入标签 2)jstl标签: 需要在jsp页面中导入标签 3)自定义标签 : 开发者自行定义,需要在jsp页面导入标签 |
JSP动作标签
转发标签: <jsp:forward /> 参数标签: <jsp:pararm/> 包含标签: <jsp:include/>(动作标签) |
动作标签的特点和静态包含的对比:
原理: 包含与被包含的页面先各自翻译成java源文件,然后再运行时合并在一起。 (先翻译再合并),动态包含 |
|
静态包含 vs 动态包含的区别? |
|
1) 语法不同 静态包含语法: <%@inclue file="被包含的页面"%> 动态包含语法: <jsp:include page="被包含的页面"> 2)参数传递不同 静态包含不能向被包含页面传递参数 动态包含可以向被包含页面传递参数 3)原理不同 静态包含: 先合并再翻译 动态包含: 先翻译再合并 |
|
例子: |
|
<jsp:include page="/common/header.jsp"> <jsp:param value="lucy" name="name"/> //动态包含 </jsp:include> <%@include file="common/header.jsp" %> <br/> //静态包含 主页的内容 |
|
结果: 通用的头部页面的内容 参数: lucy 通用的头部页面的内容 参数: null 主页的内容 |
|
JSP:forword标签:Servlet转发的另一种写法 |
|
<body> <% request.setAttribute("AA", "aa"); %> <jsp:forward page="/09.action2.jsp"> <jsp:param value="jacky" name="name"/> //可以带参数过去 <jsp:param value="123456" name="password"/> </jsp:forward> </body> |
|
09.action。Jsp代码: <body> <%=request.getParameter("name")%><br/> <%=request.getParameter("password")%> <br/> ${requestScope.AA } </body> |
Jacky 打印结果: 123456 aa |
JSTL标签
JSTL (全名:java standard tag libarary - java标准标签库 ) |
分类
核心标签库 (c标签库) 天天用 国际化标签(fmt标签库) EL函数库(fn函数库) xml标签库(x标签库) sql标签库(sql标签库)(几乎不用) |
使用JSTL标签的步骤
1) 导入jstl支持的jar包(标签背后隐藏的java代码) 注意:使用javaee5.0的项目自动导入jstl支持jar包 2)使用taglib指令导入标签库 <%@taglib uri="tld文件的uri名称" prefix="简写" %> <%--导入标签库 --%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 3)在jsp中使用标签 |
核心标签库的重点标签: 保存数据: <c:set></c:set> 获取数据: <c:out value=""></c:out> 单条件判断 <c:if test=""></c:if> 多条件判断 <c:choose></c:choose> <c:when test=""></c:when> <c:otherwise></c:otherwise> 循环数据 <c:forEach></c:forEach> <c:forTokens items="" delims=""></c:forTokens> 重定向 <c:redirect></c:redirect> |
例子:
<%--使用标签 --%> <%--set标签 :保存数据(保存到域中)默认保存到page域 --%> <c:set var="name" value="rose" scope="request"></c:set> <% String msg = null; pageContext.setAttribute("msg",msg); %> ${msg } <br/> ${name } <br/> <%--out标签: 获取数据(从域中) default: 当value值为null时,使用默认值 escapeXml: 是否对value值进行转义,false,不转义,true,转义(默认) --%> <c:out value="${msg}" default="<h3>标题3</h3>" escapeXml="true"></c:out> |
打印的数据 rose <h3>标题3</h3> |
单条件判断
|
<%--set标签 :保存数据(保存到域中)默认保存到page域 --%> <c:set var="name" value="rose" scope="request"></c:set> <% String msg = null; pageContext.setAttribute("msg",msg); %> <%--if标签 :单条件判断--%> <c:if test="${empty msg}"> 条件成立 </c:if> 打印:条件成立 |
多重条件判断 |
<%--choose标签+when标签+otherwirse标签: 多条件判断 --%> <c:set var="score" value="80"></c:set> <c:choose> <c:when test="${score>=90 && score<=100}"> 优秀 </c:when> <c:when test="${score>=80 && score<90}"> 良好 </c:when> <c:when test="${score>=70 && score<80}"> 一般 </c:when> <c:when test="${score>=60 && score<70}"> 及格 </c:when> <c:otherwise> 不及格 </c:otherwise> </c:choose> |
<%-- forEach标签:循环 --%> <% //List List<Student> list = new ArrayList<Student>(); list.add(new Student("rose",18)); list.add(new Student("jack",28)); list.add(new Student("lucy",38)); //放入域中 pageContext.setAttribute("list",list); //Map Map<String,Student> map = new HashMap<String,Student>(); map.put("100",new Student("mark",20)); map.put("101",new Student("maxwell",30)); map.put("102",new Student("narci",40)); //放入域中 pageContext.setAttribute("map",map); %> <hr/> <%-- begin="" : 从哪个元素开始遍历,从0开始.默认从0开始 end="": 到哪个元素结束。默认到最后一个元素 step="" : 步长 (每次加几) ,默认1 items="": 需要遍历的数据(集合) var="": 每个元素的名称 varStatus="": 当前正在遍历元素的状态对象。(count属性:当前位置,从1开始) --%> <c:forEach items="${list}" var="student" varStatus="varSta"> 序号:${varSta.count} - 姓名:${student.name } - 年龄:${student.age}<br/> </c:forEach> <hr/> <c:forEach items="${map}" var="entry"> ${entry.key } - 姓名: ${entry.value.name } - 年龄:${entry.value.age }<br/> </c:forEach> <hr/> <%-- forToken标签: 循环特殊字符串 --%> <% String str = "java-php-net-平面"; pageContext.setAttribute("str",str); %> <c:forTokens items="${str}" delims="-" var="s"> ${s }<br/> </c:forTokens> |
序号:1 - 姓名:rose - 年龄:18 序号:2 - 姓名:jack - 年龄:28 序号:3 - 姓名:lucy - 年龄:38 --------------------------- 100 - 姓名: mark - 年龄:20 101 - 姓名: maxwell - 年龄:30 102 - 姓名: narci - 年龄:40 --------------------------- java php net 平面 |
<%--redrict:重定向 --%> |
<c:redirect url="http://www.baidu.com"></c:redirect> |