-
概述
Jsp技术:Java Server Page, 服务器端的页面技术。
JSP全称是Java Server Page,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术,Jsp就是Servlet。
-
快速使用
<body>
<% for (int i=0;i<3;i++){ %>
<h3>hellomiemie</h3>
<%} %>
<%
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
String now = sdf.format(new Date());
// 输出到浏览器
out.write(now);
%>
</body>
-
特点
1.Jsp中可以写html代码, 我们像开发html一样开发jsp技术。
2.Jsp与html不同的是, jsp中可以写java代码。
3.Jsp = html + java 代码 (理解)。
4.out 对象可以直接使用。
5. jsp中所有的html内容, 都是通过out.write(); 写到浏览器。
6. jsp中java代码,直接拷贝到翻译后的*.java 文件中。
7. 因为在service方法中,Html 所有内容都被会在service方法中通过out.write()写到浏览器,在service方法的第一行已经定义了out对象,所以在方法后面都可以用out对象。
-
原理
jsp执行原理:
# tomcat/work 这个是jsp的工作目录。
# 第一次访问jsp的时候,先把访问的jsp翻译成.java文件, 再对.java文件进行编译.class文件, 最后再运行.class文件。
# 再次访问,直接运行*.class文件。(jsp在第一次运行访问时候会稍慢)
翻译、编译,都是由tomcat服务器完成的,tomcat服务器中“jsp引擎”专门处理jsp,即翻译、编译。
-
应用场景
Servlet 是开发动态网站技术,Jsp就是servlet。
在开发中:
Servlet
在servlet中,我们一般只处理业务逻辑,不负责显示数据(处理业务逻辑: 登陆、注册、查询列表、修改),因为在servlet中显示数据太麻烦。
JSP
在jsp中,一般只负责显示数据,不涉及任何业务逻辑。
业务逻辑处理(servlet(业务逻辑实现)与显示数据(jsp(数据展示))要分离。
-
JSP语法_Jsp脚本代码
语法:
<% %>
1. 里面可以写多行java代码,要完全符合java代码格式;如每一行结束要用分号。
2. 脚本代码内容,会直接拷贝到返回后的java文件中。
-
JSP语法_Jsp表达式
语法:
<%= %>
1. 输出已经定义的变量的值。
2. 相当于out.write(…);。
3. 注意不要用分号结束。
<font color="red"><%=request.getAttribute("name") %></font>
-
JSP语法_Jsp声明
语法:
<%! %>
<body>
<%!
// 这里是jsp声明,这里的内容会拷贝到翻译后的java文件中service()方法外、类内部
private String str= "jack";
// 返回当前用户
public String getName(){
return str;
}
// 面试题:在jsp声明中 里面定义如下方法, 是否可以?
// public void _jspInit() {} 不可以这样,翻译后的方法已经有这个名称了。
%>
<font color="red"><%=getName() %></font>
</body>
-
JSP语法_Jsp注释
<body>
<!-- 客户端注释,浏览器源码可以看到。 -->
<%-- jsp注释,浏览器源码不可以看到。 --%>
</body>
-
Jsp指令
概述
指令,不产生任何可见输入, 只会告诉当前解析器如何解析、执行、显示当前文件。
三种指令:
pge 指令, jsp页面都要有page指令。
include指定,静态包含(包含其他页面)。
tglib指令, 引入标签库文件(jstl标签库、自定义标签)。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@include file="" %>
<%@taglib prefix="" uri="" %>
-
Jsp指令_include包含指令
include指令,引入其他页面,也叫做静态进入。
<!-- include指令,引入头部页面 -->
<%@include file="/public/head.jsp" %>
会去当前项目下public目录查找head.jsp,即WebRoot/public/head.jsp 会被引入。
注意:
1. include引入,也叫静态引入。
先包含被引入的页面,再一起翻译。对于引入的页面,会把其内容拷贝到当前页面,再一起翻译、编译。
2. 对于静态引入,被引入的页面,最好不要有html这些重复的内容。
-
Jsp指令_ pge指令
-
page指令,jsp页面默认要有page指令。 page指令属性
<%@ page
language="java" 当前页面语言环境,默认java
import="java.util.*" 默认导入的包
pageEncoding="UTF-8" 指定编码
contentType="text/html; charset=ISO-8859-1" 编码设置
autoFlush="true"
buffer="8kb" 页面缓存大小
errorPage="" 错误页面
extends="" 当前页面翻译后的类继承哪个类
jsp默认继承org.apache.jasper.runtime.HttpJspBase
isELIgnored="false" 是否忽略el表达式; 默认不忽略!
isErrorPage="false" 是否是错误页面,如果设置为true, 页面可以使用exception页面
isThreadSafe="true" 一旦设置为false,会实现SingleThreadModel接口;
%>
导包(import=“java.util.*”):
- 默认导入的包,可以查看java翻译后的源码:
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.util.*;
- 自己导入包
<%@ page language="java" import="java.util.*,cn.itcast.entity.*" pageEncoding="UTF-8" %>
或者,
<%@page import="cn.itcast.entity.Person"%>
-
编码设置
pageEncoding=“GBK”, 会设置响应数据的编码
即:response.setContentType("text/html; charset=GBK ");
或者:
contentType=“text/html; charset=UTF-8”
也会生成,response.setContentType("text/html;charset=UTF-8 "); -
错误页面
errorPage=""
一旦当前页面出现错误,会跳转到这里配置的页面。
优先级高于全局的声明式异常配置。
声明式异常配置:
对项目所有位置都有效,配置到web.xml。
<%@ page language="java" errorPage="/error/error.jsp" import="java.util.*" pageEncoding="UTF-8"%>
全局配置:
<!-- 配置全局声明式异常处理 -->
<!-- 根据错误状态码配置其对应的错误页面 -->
<error-page>
<error-code>404</error-code>
<location>/error/404.jsp</location>
</error-page>
<!-- 根据错误类型配置其对应的错误页面 -->
<error-page>
<exception-type>java.lang.NullPointerException</exception-type>
<location>/error/500.jsp</location>
</error-page>
-
Jsp动作
Jsp标签,也叫做jsp动作。
举例:
<jsp:forward page=""></jsp:forward> 转发
<jsp:param value="" name=""/> 转发/包含时带的参数 (不能单独使用)
<jsp:include page=""></jsp:include> 包含, 动态包含
静态/动态包含的区别:
静态包含:是通过jsp的指令实现
特点: 先合并,再编译。
(包含页面与被包含页面,在翻译的时候会合并再一起,再编译。)
动态包含: 通过jsp动作(标签)实现
特点, 先编译,再合并。
(包含页面与被包含页面,分别翻译、编译,运行时期再合并在一起显示。)
- <jsp:forward page=""></jsp:forward> 转发标签
<body>
<%--
// 通过java代码转发!
request.getRequestDispatcher("/index.jsp?userName=Jack").forward(request,response);
--%>
<%-- 通过jsp动作实现转发,以及转发带参数 --%>
<jsp:forward page="/index.jsp">
<jsp:param name="userName" value="Rose"/>
<jsp:param name="pwd" value="888"/>
</jsp:forward>
</body>
- <jsp:include page=""></jsp:include>
<body>
<!-- 引入页面的头部 -->
<jsp:include page="/public/head.jsp"></jsp:include>
index 首页 <br/>
</body>
-
Jsp映射
<!-- jsp映射 -->
<servlet>
<servlet-name>test</servlet-name>
<jsp-file>/index.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>test</servlet-name>
<url-pattern>/test1.jsp</url-pattern>
<url-pattern>/test2.html</url-pattern>
<url-pattern>/test3.htm</url-pattern>
</servlet-mapping>
访问:
http://localhost:8080/day11/test1.jsp
http://localhost:8080/day11/test2.html
http://localhost:8080/day11/test3.htm
都会指向上面配置的index.jsp
当项目发布后,不想让用户知道访问的资源,可以模糊处理 (提升安全性)。
-
九大内置对象
-
内置对象:已经有的对象,是别人创建的,我们可以直接使用(tomcat服务器创建的对象)。 Jsp九大内置对象:
对象名称 类型 描述
request HttpServletRequest 封装请求信息
response HttpServletResponse 封装设置的响应信息
session HttpSession 会话对象(访问jsp默认开启会话)
application ServletContext 代表整个应用
config SevletConfig 可以获取servlet在web.xml中配置
out JspWriter 带缓冲功能的PrintWriter
pageContext PageContext 域对象,范围最小
page this (当前servlet/页面) 当前servlet(this)
exception Throwable 异常对象
-
九大内置对象_Out对象
带缓冲功能的PrintWriter对象。
- out隐式对象用于向客户端发送文本数据。
- out对象是通过调用pageContext对象的getOut方法返回的,其作用和用法与ServletResponse.getWriter方法返回的PrintWriter对象非常相似。
- JSP页面中的out隐式对象的类型为JspWriter,JspWriter相当于一种带缓存功能的PrintWriter,设置JSP页面的page指令的buffer属性可以调整它的缓存大小,甚至关闭它的缓存。
- 只有向out对象中写入了内容,且满足如下任何一个条件时,out对象才去调用ServletResponse.getWriter方法,并通过该方法返回的PrintWriter对象将out对象的缓冲区中的内容真正写入到Servlet引擎提供的缓冲区中:
(1)设置page指令的buffer属性关闭了out对象的缓存功能
(2)out对象的缓冲区已满
(3)整个JSP页面结束
out(JspWriter) -> 写入缓冲区 ->PrinterWriter对象 ->输出到浏览器
<body>
<%
// 通过带缓冲功能的out对象,往浏览器写数据!
out.write("1. JspWriter<br>");
// 通过response对象获取PrintWriter,再向浏览器写数据
PrintWriter writer = response.getWriter();
writer.write("2.PrintWriter<br>"); // [默认会先输出]
%>
</body>
如果想让上面的代码按照顺序输入,需要关闭页面缓存大小,设置为0即可
<%@ page language=“java” buffer=“0kb” session=“true” import=“java.util.*” pageEncoding=“UTF-8”%>
-
九大内置对象_PageContext对象
pageContext对象是JSP技术中最重要的一个对象,它代表JSP页面的运行环境,这个对象不仅封装了对其它8大隐式对象的引用,它自身还是一个域对象,可以用来保存数据。并且,这个对象还封装了web开发中经常涉及到的一些常用操作,例如引入和跳转其它资源、检索其它域对象中的属性等。
获取其他隐式对象
通过jsp的内置对象pageContext,可以获取其他八大隐式对象的引用。
<body>
<%
// 一、通过pageContext对象,获取其他隐式对象
out.println(request == pageContext.getRequest());
out.println(session == pageContext.getSession());
out.println(application == pageContext.getServletContext());
out.println(config == pageContext.getServletConfig());
%>
</body>
域对象
pageContext是一个域对象,可以存储数据,数据在当前page内有效。
数据操作:
pageContext.setAttribute(…);
pageContext.getAttribute(…);
pageContext.removeAttribute(…);
范围:只在当前页面有效,转发后不能获取pageContext中数据。
常用方法
pageContext.forward(“hello.jsp”); 转发
pageContext.include(); 包含
pageContext.findAttribute(); 从各个域中查找搜索值,找到后立刻返回。按照域的范围从小到大搜索,找到后立刻返回:
Page域 < request 域 < session域 < application域
<body>
<%
// 1. 转发 [转发四中方式总结: request对象/servletContext/jsp动作/pageContext]
pageContext.forward("/index.jsp");
// 2. 包含(动态)
pageContext.include("/public/head.jsp");
/* 获取各个域中值
String request_data = (String)request.getAttribute("my_data");
String session_data = (String)session.getAttribute("my_data");
String application_data = (String)application.getAttribute("my_data");
*/
// 3. 自动检索各个域中值
pageContext.getAttribute("my_data");// 获取page域中数据
/* 3.1 通过pageContext指定从哪个域中获取数据
String request_data = (String)pageContext.getAttribute("my_data",PageContext.REQUEST_SCOPE);
String session_data = (String)pageContext.getAttribute("my_data",PageContext.SESSION_SCOPE);
String application_data = (String)pageContext.getAttribute("my_data",PageContext.APPLICATION_SCOPE);
*/
// 3.2 自动搜索各个域
String value = (String)pageContext.findAttribute("my_data");
%>
<!-- 显示值 -->
<%=value %>
</body>
-
四大对象总结
pageContext,request,seesion,servletContect。
域对象的生命周期
域对象的范围由域对象的生命周期决定。
pageContext
每次访问jsp页面创建,访问jsp结束,对象就失效。
request
每次访问服务器创建, 访问结束对象失效。
转发后用的是同一个request。
Session
第一次执行request.getSession()对象创建, 访问jsp默认创建。
当浏览器关闭,session就不能用。
当session达到最大活跃时间,服务器端销毁session。
或者调用销毁方法。
servletContext
服务器启动创建,服务器停止销毁。
对象的范围,就决定了对象中存储数据的访问。
存储数据范围由大到小顺序:
Application > session > request > pageContext
servlet处理业务,得到结果:例如查询结果、登陆是否成功结果; 结果保存到域中;
再在jsp中,从域中取出数据。
-
EL表达式语言
Jsp2.0规范:Jsp中不能出现任何java代码。
EL 全名为Expression Language。EL主要作用:
1.获取域中的数据。
2.运算。
EL 是jsp页面取值标准(可以直接使用)。
EL 的出现主要是取代jsp中的java代码。
运算
<!-- 1. el表达式语言,会计算表达式的值 -->
${1+1 }
${1+1 == 3}
${user == null }
域对象取值
1.自动搜索各个域
2.指定域取值
El中的内置对象:
pageScope 指定从page域中取值
requestScope 指定从request域中取值
sessionScope 指定从session域中取值
appliactionScope 指定从application域中取值
<%
// 模拟servlet中保存数据
pageContext.setAttribute("name1","Jack1");
request.setAttribute("name","Jack2");
session.setAttribute("name","Jack3");
application.setAttribute("name","Jack4");
%>
<body>
<!-- 1. el表达式语言,会计算表达式的值 -->
${1+1 }
${1+1 == 3}
${user == null }
<!-- 2. 从域中取值 -->
<!-- 等同于pageContext.findAttribute('')方法 -->
<!-- 自动搜索各个域中值,按照域的范围从小到大搜索,找到后就立刻返回! -->
${name } <hr/>
<!-- 指定域取值 -->
${pageScope.name1 }
${requestScope.name }
${sessionScope.name }
${applicationScope.name }
</body>
El从域对象,对象属性中取值
Person
package cn.itcast.entity;
public class Person {
private int id;
private String name;
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
}
servlet
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 数据在这里保存
Person p = new Person();
p.setId(1000);
p.setName("Jack");
// 保存到request域
request.setAttribute("person1", p);
// 转发
request.getRequestDispatcher("/11_el.jsp").forward(request, response);
}
Jsp
<body>
<br/>1. 获取request域中数据, 是一个对象<br/>
${requestScope.person1 }
<br/>2. 获取对象”属性“<br/>
${requestScope.person1.id }
${requestScope.person1.name }
</body>
JSTL标签库
El 用于取代jsp中的java代码,El不能完全做到,例如,集合,需要遍历,核心标签库,里面定义遍历集合的标签。
<body>
<br/>1. 获取request域中数据, 是一个对象<br/>
${requestScope.person1 }
<br/>2. 获取对象”属性“<br/>
${requestScope.person1.id }
${requestScope.person1.name }
<br/>3. 获取list集合<br/>
${list } <!-- 整个list集合对象 -->
${list[0].id }
${list[0].name }
<br/>4.获取map<br/>
${map } <br/> <!-- 整个map集合对象 -->
<hr/>
<!-- 一、遍历list集合 -->
<!-- 引入jstl核心标签库 -->
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!-- 迭代 var 保存的是当前迭代的临时变量; items表示的是迭代的集合(从域中获取的) -->
<c:forEach var="p" items="${list}">
${p.id } , ${p.name } <br/>
</c:forEach>
<hr/>
<!-- 遍历map集合 -->
<c:forEach var="en" items="${map}">
${en.key } , ${en.value.name } <br/>
</c:forEach>
</body>