1:为什么会有JSP
jsp全名(java server pages)中文叫做java服务器页面。在Servlet那一篇我们发现用Servlet可以生成动态页面,但是我们却在Servlet中却写了大量的html标签,此外在Servlet中我们不得不将大量静态显示内容和动态生产内容混合在一起,使得我们网页编辑人员和程序员无法一起进行研发,这样会大大增加开发的效率,有人会说为什么不用ajax,因为在那个时候并没有ajax。所以为了克服这些问题,SUN公司就推出了JSP。
2:JSP的运行机制
我们先来写一个非常简单的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>jsp</title> </head> <body> <% out.print("Hello Jsp"); %> </body> </html>
这是一个非常普通的jsp如果我们打开tomcat服务器然后在服务器输入http://localhost:8080/jsp-test/index.jsp它就会显示Hello Jsp
当然这不是我说的重点,然后我们打开jsp编译后的文件(位置在.metadata.pluginsorg.eclipse.wst.server.core mp0workCatalinalocalhostjsp-testorgapachejsp)里面有2个文件一个是index_jsp.java另一个是index_jsp.class。这2个文件就是当我们访问jsp的时候由jsp(web)容器产生。现在我们看下index_jsp.java的内容
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 { 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 javax.el.ExpressionFactory _el_expressionfactory; private org.apache.tomcat.InstanceManager _jsp_instancemanager; public java.util.Map<java.lang.String,java.lang.Long> getDependants() { return _jspx_dependants; } public void _jspInit() { _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory(); _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig()); } 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 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(" "); out.write("<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> "); out.write("<html> "); out.write("<head> "); out.write("<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> "); out.write("<title>jsp</title> "); out.write("</head> "); out.write("<body> "); out.print("Hello Jsp"); out.write(" "); out.write("</body> "); out.write("</html>"); } catch (java.lang.Throwable t) { if (!(t instanceof javax.servlet.jsp.SkipPageException)){ out = _jspx_out; if (out != null && out.getBufferSize() != 0) try { 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); } } }
看到这个页面我相信大家很熟悉,可能会说这不是Servlet吗?我们可以理解成动态的Servlet,其中_jspInit、_jspService、_jspDestroy分别对应的是Servlet中的init、service、destroy,他们具有相同的功能,他的优点显而易见的,就不需要我们在Servlet中去写上面我用黑体加重的代码。这样一来就加快了我们开发的效率。这样一来我们就很容易理解jsp生成的过程。如下图
然后我们在来分析一下Servlet和Jsp的区别
1:Jsp第一次需要编译成Servlet(只编译一次)
2:Jsp是Java和HTML可以组合成一个扩展名为.jsp的文件而Servlet直接从Html分离出来
3:侧重点不同,SP侧重于视图,Servlet主要用于控制逻辑。
3:JSP语法
3.1:指令元素
指令元素:主要用于为转换阶段提供整jsp页面的相关信息,指令元素不会产生任何的输出到当前的输出流中(说白了就是定义一些关于JSP相关的信息)
3.1.1:page指令
page指令作用于整个jsp页面,定义了许多和页面相关的属性,那么我们来看看这些属性
在我们生成的jsp页面常常会有这条代码<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
这上面几个属性就是指令元素 language表示开发的语言,contentType表示文本类型,charset和pageEncoding都表示编码的格式
在将jsp转成Servlet以后我们可以在_jspService的方法中可以发现response.setContentType("text/html; charset=UTF-8");那么我们在来看其他的指令元素
<%@ page import="" %>这是是导入java的类和我们在开发中引用类的作用是一样的,加入这个指令元素以后生成的Servlet就导入这个类。
<%@ page isELIgnored="true" %>用的比较多,表示是否启动EL表达式 如果是Servlet2.3以前的版本默认是true,2.4以后的版本默认是false
<%@ page session="true" %>是否启动Session 如果是false那么Session在这个jsp就是无效的 默认是true
<%@ page errorPage="" %> 出现错误以后的指向的错误页,此时web.xml配置的对这个就无效了
<%@ page isErrorPage="false" %> 指定这个JSP是否是别的页面的错误页 默认是false
<%@ page buffer="8kb" %> 指定out对象使用缓冲区的大小 默认值为8kb,none就是不设置缓冲区。
当然还有一些指令元素就不一一说了可以自己查阅一下,大家记住这些指令元素的范围只能是当前页面。
3.1.2:include指令
从字面意思我们知道include就是包含的意思,那么这个指令元素到底干嘛的呢,它主要用于JSP页面中静态包括一个文件,这个文件可以是一个html,一个jsp页面,一个文本文件,一段java代码,我们来看看运行结果
先写一个简单的jsp页面
1 <html> 2 <head> 3 <title>我是一个jsp静态文件</title> 4 </head> 5 <body>i am myinclede.jsp 6 </body> 7 </html>
然后我们在index.jsp中引用
1 <%@ include file="myinclude.jsp" %>
运行结果如下
如果要是一段代码呢然后我们把myinclede.jsp修改成如下
1 <%@ page import="java.util.*" %> 2 <html> 3 <head> 4 <title>我是一个jsp静态文件</title> 5 </head> 6 <body> 7 <% 8 out.print(new Date().toLocaleString()); 9 %> 10 </body> 11 </html>
我们在此运行结果如下
3.1.3:taglib指令
这个指令用户自定义标签
tablib有三个属性分别是uri、tagdir、prefi,这个在以后的自定义标签中详细讲解(暂时简单介绍)
3.2:脚本元素
脚本元素包括三个部分分别为声明、脚本段、表达式
3.2.1:声明
这个和在java代码中声明一个变量或方法一样,我们来看下它的写法
<%! int i=1; %>
<% out.print(i); %>
声明以后我们就可以直接使用这个变量了,记住声明要在%后面要加上!
当然你也可以声明一个方法如下
<%! public String getUserName(){ return "zhangsan"; } %> <% out.print(getUserName());%>
注意:使用<%! %>声明的变量在jsp容器转换成Servlet类是将该类的实例变量或者类变量(声明时会加上static关键字)所以要注意线程安全问题
3.2.2:脚本段
脚本段是在请求处理期间要执行的java代码<% %>里面的代码,这个就不多说了<% out.print(getUserName());%>就算。
3.2.3:表达式
表达式脚本元素是java语言完成的表达式,在请求计算这些完整表达式时会把结果转成字符串,插入当前的输入流中,表达式以<%=开始 %>结束
比喻姓名:<%= "张三"%>这个就是一个表达式(这个后面不需要添加如何符号)
3.3:动作元素
与 JSP指令元素不同的是,JSP动作元素在请求处理阶段起作用。JSP动作元素是用XML语法写成的。标准的jsp动作元素主要有20种,下面我主要拿常用的说一下
1:<jsp:useBean>、<jsp:setProperty>、<jsp:getProperty>
<jsp:useBean>动作用来加载一个将在JSP页面中使用的JavaBean,它的属性有id为对象对一个名,class指定Bean的完整包名,scope表示这个对象的范围
<jsp:setProperty>主要来设置对象值,其中name就是bean对象名,
<jsp:getProperty>主要来获取对象的,我们来看下例子
public class UserBean { private String userName; private String realName; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getRealName() { return realName; } public void setRealName(String realName) { this.realName = realName; }
<body> <jsp:useBean id="user" class="com.lp.beans.UserBean" scope="session"></jsp:useBean> <jsp:setProperty property="userName" name="user" value="zhangsan" /> <jsp:setProperty property="realName" name="user" value="张三"/> 用户名:<jsp:getProperty property="userName" name="user" /> 真实姓名:<jsp:getProperty property="realName" name="user" /> </body>
运行结果:
2:<jsp:forward page=""></jsp:forward>这个和上面那个forward作用相同,跳转地址的。
3:<jsp:include page=""></jsp:include>包含页面,作用上面也有提及
其他的我这里不做提及,现在开发用这个估计是不多了,想了解的可以自己看看
4:jsp九大内置对象
在Servlet中我们看到有许多对象比喻Request,response等那么Jsp中有吗,我们说过Jsp是动态的Servlet当然会有这些,我们来看看Jsp的9中内置对象
4.1:request
4.2:response
4.3:out,out的对象是JspWriter
4.4:page是jsp转换成Servlet以后的实例object page=this;
4.5:pageContext来获取当前页面所有的属性
4.6:application是javax.servlet.ServletContext的实例。
4.7:config是javax.servlet.ServletConfig实例
4.8:session
4.9:exception这个表示异常处理
这个我们一看应该都会明白
5:对象和范围
jsp4种范围
5.1:request:只在请求一次service有效
5.2:page只在当前页有效,跳出此页就无效
5.3:Session在整个会话期间有效
5.4:application在整个应用程序中有效,知道服务器关闭