一.基本原理
JSP的本质是Servlet,经过tomcat编译后就是变成Servlet,Servlet利用输出流动态生成HTML页面。而因为Servlet生成页面的代码晦涩难懂,所以JSP技术出来了。
正常部分的页面内容同HTML页面相同,只有动态部分受java控制的则由java程序来生成
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>My JSP 'index.jsp' starting page</title> </head> <body> 欢迎学习JSP现在的时间是: <%out.println(new java.util.Date()); %> </body> </html>
JSP注释:<%--注释内容—%> JSP注释页面源代码无法找到
HTML注释:<!--注释内容—>
JSP声明:<%!声明内容%>
<%! int num; String name; String address; %> <%! public String info(){ return "我是声明"; } %>
相当于java里的
public final class test2_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent { int count; public String info(){ return "我是声明"; }
注意:JSP声明语法定义的变量对应于java中,比如修饰符private public,但不能使用 abstract修饰声明部分,因为抽象方法将导致JSP编译成Servlet时变成抽象类而无法实例化。还有每个servlet在容器中只有一个实例,也就是单例。
JSP表达式:<%=表达式内容%> 注意:后面不能有分号
<%! int count; public String info(){ return "我是声明"; } %> </head> <body> <%= count++ %> <br/> <%=info() %>
JSP脚本:<%java代码%>
-----------------------------------------------------
JSP三个编译指令:page(针对当前页面),include(指定包含另一页面),taglib(用于定义和访问自定义标签)
格式为:<%@ 指令名 属性名=”属性值”… %>
例<%@page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
JSP的7个动作指令:
jsp:forward:执行转发,讲请求转发到下一个页面(发生转发时,请求转发到的目标资源会首先清空响应缓存区!)
jsp:param:传递参数,与其他支持参数的标签一起用
jsp:include:动态引入一个JSP页面
jsp: plugin:下载javaBean
jsp: userBean:创建javabean实例
jsp: setProperty 设置javabean的实例属性
jsp: setProperty 输出javabean实例的属性
-----------------------------------------------------------------
如果只有type没有class,在<jsp:userBean>标记中的体是没有意义的!只有创建新bean时才会执行标记体!如果标记里只有type,没有class,则根本不可能创建bean的新实例
<!-- person是抽象类只有一个name,employee继承person,只有一个userID --> <jsp:useBean id="person" type=cn.itcast.domin.employee> <jsp:setProperty name="person" property="name" value="张三"/> </jsp:useBean> 名字是:<jsp:getProperty property="name" name="person"/>
foo.Person p = new foo.Employee();
p.setName(“李四”);
request.setAttribute(“person”,p);请求时会失败!因为”person”属性存储在requestScope作用域中,而且只指定了type,<jsp:Bean>标记不会工作
-----------------------------------------------
foo.Person p = new foo.Person();
p.setName(“李四”);
request.setAttribute(“person”,p);这个servlet无法编译!因为person无法实例化,它是抽象
--------------------------------------------------
foo.Employeep = new foo.Employee();
p.setName(“李四”);
request.setAttribute(“person”,p);请求时会失败!因为”person”属性存储在requestScope作用域中,而且只指定了type,<jsp:Bean>标记不会工作
关于静态包含( <%@ include file=”page.jsp%> )和动态包含( <jsp:include page=”page.jsp></jsp:include>),他们的区别是:静态包含在转换时插入源代码,而动态包含在运行时插入被包含文件的响应。<jsp:include>标准动作会带来额外的性能开销,但指令不同,影响只出现一次。在JSP规范中,指令包含只会编译一次,但是现在的新容器也会自动检查被包含文件的变化!
静态包含:是将被包含的JSP与自身整合到一起,再编译成servlet响应用户。静态包含一般用于不经常变动的文件,注意被包含文件头去掉(通用的head.jsp left.jsp right.jsp)
out.write("\r\n"); out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n"); out.write("<html>\r\n"); out.write("<head>\r\n"); out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\r\n"); out.write("<title>Insert title here</title>\r\n"); out.write("</head>\r\n"); out.write("<body>\r\n"); out.write("\r\n"); out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n"); out.write("<html>\r\n"); out.write(" <head> \r\n"); out.write(" <title>My JSP 'index.jsp' starting page</title>\r\n"); out.write(" </head> \r\n"); out.write(" <body>\r\n"); out.write(" 欢迎学习JSP现在的时间是:11\r\n"); out.write(" "); out.print(request.getAttribute("name") ); out.write("\r\n"); out.write(" "); out.print(request.getParameter("name") ); out.write("\r\n"); out.write(" </body>\r\n"); out.write("</html>\r\n"); out.write('\r'); out.write('\n');
动态包含:是先编译成servlet再用include方法来引入被导入的页面内容(生成两个Servlet),并且引入的文件是servlet响应后生成的静态JSP/html网页。
out.write("<body>\r\n"); org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "index.jsp", out, false); out.write("\r\n");
<jsp:forward page="index.jsp"></jsp:forward> <jsp:include page="index.jsp" flush="false"> <jsp:param value="lisi1" name="name"/> </jsp:include> <jsp:useBean id="p1" class="cn.xxx.Domin.Person" scope="page"> <jsp:setProperty name="p1" property="name" value="张三"/> <jsp:setProperty name="p1" property="age" value="29"/> <jsp:setProperty name="p1" property="gender" value="公"/> </jsp:useBean> <jsp:getProperty property="name" name="p1"/>
总结:无论是静态包含还是动态包含,呈现给客户端的页面都是由所有页面共同组成的jsp/html页面,从源代码可以看到,只是一个是整合编译成一个servlet,一个是先编译自己,再编译被包含的。而且无论是哪种包含,tomcat都会检查被包含页面的变化,会依据时间来决定是否生成新的Servlet
<!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> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>My JSP 'index.jsp' starting page</title> </head> <body> 欢迎学习JSP现在的时间是: Sun Jul 07 15:57:57 CST 2013 </body> </html> </body> </html>
还有<jsp:include page=”page.jsp” fulsh=”true> 默认是flase,该属性用于输出缓存部分给客户端,比如缓存积累到了一定数据时,服务器先提供一部分数据给浏览器并等待后续内容,一般在简单页面中,该属性不写即可,如果页面包含大量数据时,则可设置为true,先将一部分内容输出
JSP 9大内置对象
application: 代表当前的Web应用,javax.servlet.ServletContext的实例
application详解:servlet中没有application对象,但可以获取 ServletContext,通过它来获取属性值。主要作用可以让多个JSP、servlet之间共享数据。
<%@ 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> <%application.setAttribute("name", "张三");%> application的值是:<%=application.getAttribute("name") %> </body> </html>
注意:因为application代表的是整个应用,所以放置数据的时候需要谨慎,同常application的重要作用是用来获取配置参数(context-param是上下文pageContext初始化的参数)
<context-param> <param-name>driver</param-name> <param-value>com.mysql.jdbc.Driver</param-value> </context-param> <context-param> <param-name>url</param-name> <param-value>jdbc:mysql://localhost:3306/mysql</param-value> </context-param> <context-param> <param-name>user</param-name> <param-value>root</param-value> </context-param> <context-param> <param-name>password</param-name> <param-value>root</param-value> </context-param>
<%@ 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> <% String driver = application.getInitParameter("driver"); String url = application.getInitParameter("url"); String user = application.getInitParameter("user"); String password = application.getInitParameter("password"); %> 数据库驱动:<%=driver %><br/> 数据库地址:<%=url %><br/> 用户名:<%=user %><br/> 密码:<%=password %> </body> </html>
PageContext: 代表JSP页面上下文,javax.servlet.jsp.PageContext的实例使用方法则是可以访问页面中共享的数据,也就是JSP 4个作用域(page,request,session,application)的设置或者获取
pageContext.setAttribute("page", a1,pageContext.PAGE_SCOPE); pageContext.setAttribute("request", a2,pageContext.REQUEST_SCOPE); pageContext.setAttribute("session", a3,pageContext.SESSION_SCOPE); pageContext.setAttribute("application", a4,pageContext.APPLICATION_SCOPE); String b1 = (String)pageContext.getAttribute("page", pageContext.PAGE_SCOPE); String b2 = (String)pageContext.getAttribute("request",pageContext.REQUEST_SCOPE); String b3 = (String)pageContext.getAttribute("session",pageContext.SESSION_SCOPE); String b4 = (String)pageContext.getAttribute("application",pageContext.APPLICATION_SCOPE);
还可以用来获取其他内置对象:
<% pageContext.getRequest();//request对象 pageContext.getSession();//session对象 pageContext.getResponse();//Response对象 pageContext.getServletConfig();//config对象 pageContext.getServletContext();//application对象 %>
config:代表当前JSP的配置信息,javax.servlet.ServletConfig的实例,JSP一般都不用配置,很少使用。如果硬要配置,可以把它当做普通的servlet来配置。切记:访问的时候,只能通过映射地址访问才能获取配置参数。
<servlet> <servlet-name>config</servlet-name> <jsp-file>/config.jsp</jsp-file> <init-param> <param-name>name</param-name> <param-value>张三</param-value> </init-param> <init-param> <param-name>age</param-name> <param-value>33</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>config</servlet-name> <url-pattern>/config</url-pattern> </servlet-mapping>
<%@ 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> <%=config.getServletName()%> <%=config.getInitParameter("name") %> <%=config.getInitParameter("age") %> </body> </html>
session:代表一次回话,javax.servlet.http:HttpSession的实例。
out:代表JSP页面的输出流,用于输出内容(输出HTML页面).javax.servlet.jsp.JspWriter的实例
request:代表封装了一次请求,javax.servlet.http.HttpServletRequest的实例,客户端的请求参数都被封装在该对象
response:代表服务器响应客户端。
exception:代表异常和错误,java.lang.Throwable的实例,注意:当前JSP页面的编译指令 page的 isErrorPage=true时,才能使用
page:代表当前页面本身,相当于Servlet中的this。
public void _jspService(HttpServletRequest request, HttpServletResponse response) throws java.io.IOException, ServletException { PageContext pageContext = null; HttpSession session = null; ServletContext application = null; ServletConfig config = null; JspWriter out = null; Object page = this; JspWriter _jspx_out = null; PageContext _jspx_page_context = null;
-------------------------------------------------------------------------------------------------