1、为什么要学习jsp技术
1.1、什么是jsp?
JSP(全称Java Server Pages)是由Sun 公司专门为了解决动态生成HTML文档的技术。
1.2、Servlet程序输出html页面。
在学习jsp技术之前,如果我们要往客户端输出一个页面。我们可以使用Servlet程序来实现。具体的代码如下:
1)Servlet输入html页面的程序代码:
package com.atguigu.servlet;
import java.io.IOException;
import java.io.Writer;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HtmlServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// 设置返回的数据内容的数据类型和编码
response.setContentType("text/html; charset=utf-8");
// 获取字符输出流
Writer writer = response.getWriter();
//输出页面内容!
writer.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">");
writer.write("<html>");
writer.write("<head>");
writer.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");
writer.write("<title>Insert title here</title>");
writer.write("</head>");
writer.write("<body>");
writer.write("这是由Servlet程序输出的html页面内容!");
writer.write("</body></html>");
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
}
}
2)在浏览器中输入访问Servlet的程序地址得到以下结果:
上面的代码我们不难发现。通过Servlet输出简单的html页面信息都非常不方便。
那我们要输出一个复杂页面的时候,就更加的困难,而且不利于页面的维护和调试。
所以sun公司推出一种叫做jsp的动态页面技术帮助我们实现对页面的输出繁锁工作。
jsp页面的访问千万不能像HTML页面一样。托到浏览器中。只能通过浏览器访问Tomcat服务器再访问jsp页面。
1.3、如何创建一个jsp动态页面程序
1)选中WebContent目录,右键创建一个jsp文件
2) 修改jsp页面的文件名
3)选择生成jsp文件的模板,我们选择默认的New JSP File(html)
4) 在body标签中添加你想要显示的文本内容
5) 然后在浏览器中输入jsp页面的访问地址。
jsp页面的访问地址和html页面的访问路径一样http://ip:端口号/工程名/文件名
也就是http://127.0.0.1:8080/day08/index.jsp
1.4、如何修改jsp文件的默认编码。
注意事项:
1、jsp页面是一个类似于html的一个页面。 jsp直接存放到WebContent目录下,和html一样
访问jsp的时候,也和访问html一样
2、jsp的默认编码集是iso-8859-1修改jsp的默认编码为UTF-8
2、 jsp的运行原理(要求知道)
jsp的本质 ,其实是一个Servlet程序。
首先我们去找到我们Tomcat的目录下的work\Catalina\localhost目录。当我们发布day09工程。并启动Tomcat服务器后。我们发现
在work\Catalina\localhost目录下多出来一个day09目录。
一开始day09目录还是空目录。
然后,我们在浏览器输入一个jsp文件的访问路径访问。
比如http://127.0.0.1:8080/day09/index.jsp访问index.jsp文件
day09目录马上会生成org\apache\jsp目录。
并且在会中有两个文件。
index_jsp.class文件很明显是index_jsp.java源文件编译后的字节码文件。
那么 index_jsp.java是个什么内容呢?
生成的java文件名,是以原来的文件名加上_jsp得到。 xxxx_jsp.java文件的名字
我们打开index_jsp.java文件查看里面的内容:
发现,生成的类继承于HttpJspBase类。这是一个jsp文件生成Servlet程序要继承的基类!!!
于是,我们关联源代码。去查看一下HttpJspBase类的内容。从源码的类注释说明中,我们发现。HttpJspBase这个类就是所有jsp文件生成Servlet程序
需要去继承的基类。并且这个HttpJspBase类继承于HttpServlet类。所以jsp也是一个Servlet小程序。
我们分别在工程的WebContent目录下创建多个jsp文件。然后依次访问。它们都被翻译为.java文件并编译成为.class字节码文件
我们打开index_jsp.java文件查看里面的内容不难发现。jsp中的html页面内容都被翻译到Servlet中的service方法中直接输出。
小结:
从生成的文件我们不难发现一个规则。
- jsp 翻译成 java文件后的全名是 a_jsp.java文件
- jsp 翻译成 java文件后的全名是 b_jsp.java文件
那么 当我们访问 一个xxx.jsp 文件后 翻译成java文件的全名是 xxx_jsp.java文件
xxx_jsp.java文件是一个Servlet程序。原来jsp中的html内容都被翻译到Servlet类的service方法中原样输出。
3、jsp的语法(重点掌握)
3.1、jsp文件头部声明介绍(page指令介绍)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
这是jsp文件的头声明。表示这是jsp页面。
language属性 值只能是java。 表示翻译的得到的是java语言的
contentType属性 设置响应头contentType的内容
pageEncoding属性 设置当前jsp页面的编码
import属性 给当前jsp页面导入需要使用的类包
autoFlush属性 设置是否自动刷新out的缓冲区,默认为true
buffer属性 设置out的缓冲区大小。默认为8KB
errorPage属性 设置当前jsp发生错误后,需要跳转到哪个页面去显示错误信息
isErrorPage属性 设置当前jsp页面是否是错误页面。是的话,就可以使用exception异常对象
session 属性 设置当前jsp页面是否获取session对象,默认为true
extends 属性 给服务器厂商预留的jsp默认翻译的servlet继承于什么类
3.2、jsp中的三种脚本介绍
1)第一种,声明脚本:
声明脚本格式如下:
<%!
java 代码
%>
在声明脚本块中,我们可以干4件事情
- 我们可以定义全局变量。
- 定义static静态代码块
- 定义方法
- 定义内部类
几乎可以写在类的内部写的代码,都可以通过声明脚本来实现
2)第二种,表达式脚本(***重点,使用很多):
表达式脚本格式如下:
<%=表达式 %>
表达式脚本 用于向页面输出内容。
表达式脚本 翻译到Servlet程序的service方法中 以 out.print() 打印输出
out 是jsp的一个内置对象,用于生成html的源代码
注意:表达式不要以分号结尾,否则会报错
表达式脚本可以输出任意类型。
比如:
- 输出整型
- 输出浮点型
- 输出字符串
- 输出对象
3)第三种,代码脚本(*****重点,使用最多):
代码脚本如下:
<% java代码 %>
代码脚本里可以书写任意的java语句。
代码脚本的内容都会被翻译到service方法中。
所以service方法中可以写的java代码,都可以书写到代码脚本中
3.3、jsp中的注释:
// 单行java注释
/*
多行java代码注释
*/
单行注释和多行注释能在翻译后的java源代码中看见。
<%-- jsp注释 --%>
jsp注释在翻译的时候会直接被忽略掉
<!-- html注释 -->
html的注释会被翻译到java代码中输出到html页面中查看
4、jsp九大内置对象
我们打开翻译后的java文件。查看_jspService方法。
那么 jsp 中九大内置对象分别是:
request 对象 请求对象,可以获取请求信息
response 对象 响应对象。可以设置响应信息
pageContext 对象 当前页面上下文对象。可以在当前上下文保存属性信息
session 对象 会话对象。可以获取会话信息。
exception 对象 异常对象只有在jsp页面的page 指令中设置 isErrorPage="true" 的时候才会存在
application 对象 ServletContext对象实例,可以获取整个工程的一些信息。
config 对象 ServletConfig对象实例,可以获取Servlet的配置信息
out 对象 输出流。
page 对象 表示当前Servlet对象实例(无用,用它不如使用this对象)。
九大内置对象,都是我们可以在【代码脚本】中或【表达式脚本】中直接使用的对象。
5、jsp四大域对象
四大域对象经常用来保存数据信息。
pageContext 可以保存数据在同一个jsp页面中使用
request 可以保存数据在同一个request对象中使用。经常用于在转发的时候传递数据
session 可以保存在一个会话中使用
application(ServletContext) 就是ServletContext对象
四个作用域的测试代码:
新建两个jsp页面。分别取名叫:context1.jsp,context2.jsp
① context1.jsp的页面代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
这是context1页面<br/>
<%
//设置page域的数据
pageContext.setAttribute("key", "pageContext-value");
//设置request域的数据
request.setAttribute("key", "request-value");
//设置session域的数据
session.setAttribute("key", "session-value");
//设置application域的数据
application.setAttribute("key", "application-value");
%>
<%-- 测试当前页面作用域 --%>
<%=pageContext.getAttribute("key") %><br/>
<%=request.getAttribute("key") %><br/>
<%=session.getAttribute("key") %><br/>
<%=application.getAttribute("key") %><br/>
<%
// 测试request作用域
// request.getRequestDispatcher("/context2.jsp").forward(request, response);
%>
</body>
</html>
② context2.jsp的页面代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
这是context2页面 <br/>
<%=pageContext.getAttribute("key") %><br/>
<%=request.getAttribute("key") %><br/>
<%=session.getAttribute("key") %><br/>
<%=application.getAttribute("key") %><br/>
</body>
</html>
测试pageContext作用域步骤:
直接访问context1.jsp文件
测试request作用域步骤:
1.在context1.jsp文件中添加转发到context2.jsp(有数据)
2.直接访问context2.jsp文件 (没有数据)
测试session作用域步骤:
- 访问完contextjsp文件
- 关闭浏览器。但是要保持服务器一直开着
- 打开浏览器,直接访问context2.jsp文件
测试application作用域步骤:
- 访问完contextjsp文件,然后关闭浏览器
- 停止服务器。再启动服务器。
- 打开浏览器访问context2.jsp文件
6、jsp中out输出流 和 response.getwriter()输出流
1) jsp中out和response的writer的区别演示
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
// out输出
out.write("这是out的第一次输出<br/>");
// out flush之后。会把输出的内容写入writer的缓冲区中
out.flush();
// 最后一次的输出,由于没有手动flush,会在整个页面输出到客户端的时候,自动写入到writer缓冲区
out.write("这是out的第二次输出<br/>");
// writer的输出
response.getWriter().write("这是writer的第一次输出<br/>");
response.getWriter().write("这是writer的第二次输出<br/>");
%>
</body>
</html>
在浏览器里输入 http://127.0.0.1:8080/day09/output.jsp 运行查看的结果:
2) 图解out流和writer流的两个缓冲区如何工作
7、jsp的常用标签(重点****)
<%-- 静态包含 --%>
<%-- 动态包含 --%>
<%-- 转发 --%>
1)静态包含--很常用
<%@ include file="" %>
静态包含是把包含的页面内容原封装不动的输出到包含的位置。
2)动态包含--少用
<jsp:include page=""></jsp:include>
动态包含会把包含的jsp页面单独翻译成servlet文件,然后在执行到时候再调用翻译的servlet程序。并把计算的结果返回。
动态包含是在执行的时候,才会加载。所以叫动态包含。
传参数:
<jsp:include page="/index2.jsp" >
<jsp:param value="abcValue" name="abc"/>
</jsp:include>
接收时:
<%= request.getParameter("abc")%>
3)页面转发--常用
<jsp:forward page=""></jsp:forward>
<jsp:forward 转发功能相当于
request.getRequestDispatcher("/xxxx.jsp").forward(request, response); 的功能。
静态包含和动态包含的区别:
| 静态包含 | 动态包含 |
是否生成java文件 | 不生成 | 生成 |
service方法中的区别 | 把包含的内容原封拷贝到service中 | JspRuntimeLibrary.include方法 |
是否可以传递参数 | 不能 | 可以 (<jsp:param value="abcValue" name="abc"/>) |
编译次数 | 1 | 包含的文件 + 1 |
适用范围 | 适用包含纯静态内容(CSS,HTML,JS),或没有非常耗时操作。或大量java代码的jsp | 包含需要传递参数。含有大量java代码,运算,耗时很长的操作。 |
在这里需要补充说明一点:我们在工作中,几乎都是使用静态包含。理由很简单。因为jsp页面虽然可以写java代码,做其他的功能操作。但是由于jsp在开发过程中被定位为专门用来展示页面的技术。也就是说。jsp页面中,基本上只有html,css,js。还有一些简单的EL,表达式脚本等输出语句。所以我们都使用静态包含。