JSP简介:
JSP是简化Servlet编写的一种技术,
它将Java代码和HTML语句混合在一个文件中编写, 只对网页中药动态产生的内容采用Java代码来编写, 而对固定不变的静态内容采用普通的静态HTML页面的方式编写
案例: Hello JSp
新建动态web工程 helloJSp
WebContent下新建hello.jsp
会发现有一行为
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>这是编码格式, 但是我们大多都是用的utf-8编码, 避免每次都写
window->Preferences->查找jsp 选择JSP Files
选择utf-8
->Apply->OK
新建 hello.jsp
1 <%@page import="java.util.Date"%> 2 <%@ page language="java" contentType="text/html; charset=UTF-8" 3 pageEncoding="UTF-8"%> 4 5 6 7 8Insert title here 9 10 11 <%12 Date date = new Date();13 System.out.println(date);14 %>15 16
右键用tomcat来运行一下, 会在控制台输出
这就说明jsp页面执行成功了
为了知道jsp页面到底是什么 我们在项目中查找hello.jsp
在工作目录下
.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\helloJSP\org\apache\jsp\hello_jsp.java
1 /* 2 * Generated by the Jasper component of Apache Tomcat 3 * Version: Apache Tomcat/7.0.67 4 * Generated at: 2016-08-09 16:59:45 UTC 5 * Note: The last modified time of this file was set to 6 * the last modified time of the source file after 7 * generation to assist with modification tracking. 8 */ 9 package org.apache.jsp; 10 11 import javax.servlet.*; 12 import javax.servlet.http.*; 13 import javax.servlet.jsp.*; 14 import java.util.Date; 15 16 public final class hello_jsp extends org.apache.jasper.runtime.HttpJspBase 17 implements org.apache.jasper.runtime.JspSourceDependent { 18 19 private static final javax.servlet.jsp.JspFactory _jspxFactory = 20 javax.servlet.jsp.JspFactory.getDefaultFactory(); 21 22 private static java.util.Map_jspx_dependants; 23 24 private volatile javax.el.ExpressionFactory _el_expressionfactory; 25 private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager; 26 27 public java.util.Map getDependants() { 28 return _jspx_dependants; 29 } 30 31 public javax.el.ExpressionFactory _jsp_getExpressionFactory() { 32 if (_el_expressionfactory == null) { 33 synchronized (this) { 34 if (_el_expressionfactory == null) { 35 _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory(); 36 } 37 } 38 } 39 return _el_expressionfactory; 40 } 41 42 public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() { 43 if (_jsp_instancemanager == null) { 44 synchronized (this) { 45 if (_jsp_instancemanager == null) { 46 _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig()); 47 } 48 } 49 } 50 return _jsp_instancemanager; 51 } 52 53 public void _jspInit() { 54 } 55 56 public void _jspDestroy() { 57 } 58 59 public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response) 60 throws java.io.IOException, javax.servlet.ServletException { 61 62 final javax.servlet.jsp.PageContext pageContext; 63 javax.servlet.http.HttpSession session = null; 64 final javax.servlet.ServletContext application; 65 final javax.servlet.ServletConfig config; 66 javax.servlet.jsp.JspWriter out = null; 67 final java.lang.Object page = this; 68 javax.servlet.jsp.JspWriter _jspx_out = null; 69 javax.servlet.jsp.PageContext _jspx_page_context = null; 70 71 72 try { 73 response.setContentType("text/html; charset=UTF-8"); 74 pageContext = _jspxFactory.getPageContext(this, request, response, 75 null, true, 8192, true); 76 _jspx_page_context = pageContext; 77 application = pageContext.getServletContext(); 78 config = pageContext.getServletConfig(); 79 session = pageContext.getSession(); 80 out = pageContext.getOut(); 81 _jspx_out = out; 82 83 out.write("\r\n"); 84 out.write("\r\n"); 85 out.write("\r\n"); 86 out.write("\r\n"); 87 out.write("\r\n"); 88 out.write(" \r\n"); 89 out.write(" Insert title here \r\n"); 90 out.write("\r\n"); 91 out.write("\r\n"); 92 93 Date date = new Date(); 94 System.out.println(date); 95 96 out.write("\r\n"); 97 out.write("\r\n"); 98 out.write(""); 99 } catch (java.lang.Throwable t) {100 if (!(t instanceof javax.servlet.jsp.SkipPageException)){101 out = _jspx_out;102 if (out != null && out.getBufferSize() != 0)103 try {104 if (response.isCommitted()) {105 out.flush();106 } else {107 out.clearBuffer();108 }109 } catch (java.io.IOException e) {}110 if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);111 else throw new ServletException(t);112 }113 } finally {114 _jspxFactory.releasePageContext(_jspx_page_context);115 }116 }117 }
JavaWEB_JSP 页面的 9 个隐含对象
这部分的案例是抄袭 的, 他的总结写的非常全面了, 并且从目前的角度来说非常有深度, 有兴趣的朋友可以直接看他的博客来学习javaweb
在此对致敬, 并且无意侵犯您的版权, 如果您觉得侵犯了您的版权, 可以随时联系我
从上面的serlvet中可以得到这么几个对象
1 PageContext pageContext;2 HttpSession session;3 ServletContext application;4 ServletConfig config;5 JspWriter out;6 Object page = this;7 HttpServletRequest request, 8 HttpServletResponse response 这8个对象在jsp页面中是可以直接使用的
1 <% 2 session.setAttribute("name", "session对象");//使用session对象,设置session对象的属性 3 out.print(session.getAttribute("name")+"");//获取session对象的属性 4 pageContext.setAttribute("name", "pageContext对象");//使用pageContext对象,设置pageContext对象的属性 5 out.print(pageContext.getAttribute("name")+"");//获取pageContext对象的属性 6 application.setAttribute("name", "application对象");//使用application对象,设置application对象的属性 7 out.print(application.getAttribute("name")+"");//获取application对象的属性 8 out.print("Hello Jsp"+"");//使用out对象 9 out.print("服务器调用index.jsp页面时翻译成的类的名字是:"+page.getClass()+"");//使用page对象10 out.print("处理请求的Servlet的名字是:"+config.getServletName()+"");//使用config对象11 out.print(response.getContentType()+"");//使用response对象12 out.print(request.getContextPath()+"");//使用request对象13 %>
运行当前jsp页面会有如下显示信息
1 session对象2 pageContext对象3 application对象4 Hello Jsp5 服务器调用index.jsp页面时翻译成的类的名字是:class org.apache.jsp.hello_jsp6 处理请求的Servlet的名字是:testJSP7 text/html;charset=UTF-88 /helloJSP
剩下一个是叫作 java.lang.Throwable exception 的一个异常类型的对象, 在普通的页面中是无法使用的, 只有在特定的错误页面中才能使用,
下面的关于jsp的语法中会提到一个错误的页面的定义方法会用到这个类型的对象
JavaWEB_JSP 语法
这里就直接摘抄了, 他写的太好了
一、JSP模版元素
JSP页面中的HTML内容称之为JSP模版元素。
JSP模版元素定义了网页的基本骨架,即定义了页面的结构和外观。二、JSP表达式
JSP脚本表达式(expression)用于将程序数据输出到客户端
语法:<%= 变量或表达式 %> 举例:输出当前系统时间:1 <%= new java.util.Date() %>
JSP引擎在翻译脚本表达式时,会将程序数据转成字符串,然后在相应位置用out.print(…) 将数据输给客户端。
JSP脚本表达式中的变量或表达式后面不能有分号(;)。三、JSP脚本片断
JSP脚本片断(scriptlet)用于在JSP页面中编写多行Java代码。语法:
<% 多行java代码 %>在<% %>中可以定义变量、编写语句,不能定义方法。
范例:在Scriptlet中定义变量、编写语句
1 <%2 int sum=0;//声明变量3 4 /*编写语句*/5 for (int i=1;i<=100;i++){6 sum+=i;7 }8 out.println("Sum="+sum+"
");9 %>
注意事项:
- JSP脚本片断中只能出现java代码,不能出现其它模板元素, JSP引擎在翻译JSP页面中,会将JSP脚本片断中的Java代码将被原封不动地放到Servlet的_jspService方法中。
- JSP脚本片断中的Java代码必须严格遵循Java语法,例如,每执行语句后面必须用分号(;)结束。
- 在一个JSP页面中可以有多个脚本片断,在两个或多个脚本片断之间可以嵌入文本、HTML标记和其他JSP元素。
举例:
1 <%2 int x = 10;3 out.println(x);4 %>5这是JSP页面文本
6 <%7 int y = 20;8 out.println(y);9 %>
多个脚本片断中的代码可以相互访问,犹如将所有的代码放在一对<%%>之中的情况。如:out.println(x);
单个脚本片断中的Java语句可以是不完整的,但是,多个脚本片断组合后的结果必须是完整的Java语句,例如:1 <%2 for (int i=1; i<5; i++) 3 {4 %>5http://localhost:8080/JavaWeb_Jsp_Study_20140603/
6 <%7 }8 %>
四、JSP声明
JSP页面中编写的所有代码,默认会翻译到servlet的service方法中, 而Jsp声明中的java代码被翻译到_jspService方法的外面。语法:
<%! java代码 %> 所以,JSP声明可用于定义JSP页面转换成的Servlet程序的静态代码块、成员变量和方法 。 多个静态代码块、变量和函数可以定义在一个JSP声明中,也可以分别单独定义在多个JSP声明中。 JSP隐式对象的作用范围仅限于Servlet的_jspService方法,所以在JSP声明中不能使用这些隐式对象。JSP声明案例:
1 <%! 2 static { 3 System.out.println("loading Servlet!"); 4 } 5 6 private int globalVar = 0; 7 8 public void jspInit(){ 9 System.out.println("initializing jsp!");10 }11 %>12 13 <%!14 public void jspDestroy(){15 System.out.println("destroying jsp!");16 }17 %>
五、JSP注释
在JSP中,注释有两大类:
显式注释:直接使用HTML风格的注释:<!- - 注释内容- ->
隐式注释:直接使用JAVA的注释://、/*……*/
JSP自己的注释:<%- - 注释内容- -%>
这三种注释的区别
1 2 3 <% 4 //JAVA中的单行注释 5 6 /* 7 JAVA中的多行注释 8 */ 9 %>10 11 <%--JSP自己的注释--%>
HTML的注释在浏览器中查看源文件的时候是可以看得到的,而JAVA注释和JSP注释在浏览器中查看源文件时是看不到注释的内容的,这就是这三种注释的区别。
JSP指令
- page指令
- Include指令
- taglib指令
JSP指令的基本语法格式:<%@ 指令 属性名="值" %>
例如:
1 <%@ page contentType="text/html;charset=gb2312"%>
如果一个指令有多个属性,这多个属性可以写在一个指令中,也可以分开写。
例如:1 <%@ page contentType="text/html;charset=gb2312"%>2 <%@ page import="java.util.Date"%>
也可以写作:
1 <%@ page contentType="text/html;charset=gb2312" import="java.util.Date"%>
JSP 2.0规范中定义的page指令的完整语法:
1 <%@ page 2 [ language="java" ] 3 [ extends="package.class" ] 4 [ import="{package.class | package.*}, ..." ] 5 [ session="true | false" ] 6 [ buffer="none | 8kb | sizekb" ] 7 [ autoFlush="true | false" ] 8 [ isThreadSafe="true | false" ] 9 [ info="text" ] 10 [ errorPage="relative_url" ] 11 [ isErrorPage="true | false" ] 12 [ contentType="mimeType [ ;charset=characterSet ]" | "text/html ; charset=ISO-8859-1" ] 13 [ pageEncoding="characterSet | ISO-8859-1" ] 14 [ isELIgnored="true | false" ] 15 %>
可以在一条page指令的import属性中引入多个类或包,其中的每个包或类之间使用逗号(,)分隔
例如:
1 <%@ page import="java.util.*,java.io.*,java.sql.*"%>
上面的语句也可以改写为使用多条page指令的import属性来分别引入各个包或类
例如:
1 <%@ page import="java.util.Date"%>2 <%@ page import="java.io.*" %>3 <%@ page import="java.sql.*" %>
page指令的errorPage在最后说
include指令
在JSP中对于包含有两种语句形式:
- @include指令
- <jsp:include>指令
3.1、@include指令
@include可以包含任意的文件,当然,只是把文件的内容包含进来。
include指令用于引入其它JSP页面,如果使用include指令引入了其它JSP页面,那么JSP引擎将把这两个JSP翻译成一个servlet。所以include指令引入通常也称之为静态引入。
语法:<%@ include file="relativeURL"%>,其中的file属性用于指定被引入文件的路径。路径以“/”开头,表示代表当前web应用。
include指令细节注意问题:
- 被引入的文件必须遵循JSP语法。
- 被引入的文件可以使用任意的扩展名,即使其扩展名是html,JSP引擎也会按照处理jsp页面的方式处理它里面的内容,为了见明知意,JSP规范建议使用.jspf(JSP fragments(片段))作为静态引入文件的扩展名。
- 由于使用include指令将会涉及到2个JSP页面,并会把2个JSP翻译成一个servlet,所以这2个JSP页面的指令不能冲突(除了pageEncoding和导包除外)。
include指令使用范例:
新建head.jspf页面和foot.jspf页面,分别作为jsp页面的头部和尾部,存放于WebRoot下的jspfragments文件夹中,代码如下:
head.jspf代码:
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>2网页头部
foot.jspf代码:
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>2网页尾部
在WebRoot文件夹下创建一个IncludeTagTest.jsp页面,在IncludeTagTest.jsp页面中使用@include指令引入head.jspf页面和foot.jspf页面,代码如下:
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 3 4 5jsp的Include指令测试 6 7 8 9 <%--使用include标签引入引入其它JSP页面--%>10 <%@include file="/jspfragments/head.jspf" %>11网页主体内容
12 <%@include file="/jspfragments/foot.jspf" %>13 14
运行结果如下:
我们查看一下jsp引擎将IncludeTagTest.jsp翻译成IncludeTagTest_jsp类之后的源代码,找到Tomcat服务器的work\Catalina\localhost\JavaWeb_Jsp_Study_20140603\org\apache\jsp目录下找到IncludeTagTest_jsp.java,如下图所示:
打开IncludeTagTest_jsp.java,里面的代码如下所示:
1 package org.apache.jsp; 2 3 import javax.servlet.*; 4 import javax.servlet.http.*; 5 import javax.servlet.jsp.*; 6 import java.util.*; 7 import java.util.*; 8 import java.util.*; 9 10 public final class IncludeTagTest_jsp extends org.apache.jasper.runtime.HttpJspBase11 implements org.apache.jasper.runtime.JspSourceDependent {12 13 private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();14 15 private static java.util.List _jspx_dependants;16 17 static {18 _jspx_dependants = new java.util.ArrayList(2);19 _jspx_dependants.add("/jspfragments/head.jspf");20 _jspx_dependants.add("/jspfragments/foot.jspf");21 }22 23 private javax.el.ExpressionFactory _el_expressionfactory;24 private org.apache.AnnotationProcessor _jsp_annotationprocessor;25 26 public Object getDependants() {27 return _jspx_dependants;28 }29 30 public void _jspInit() {31 _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();32 _jsp_annotationprocessor = (org.apache.AnnotationProcessor) getServletConfig().getServletContext().getAttribute(org.apache.AnnotationProcessor.class.getName());33 }34 35 public void _jspDestroy() {36 }37 38 public void _jspService(HttpServletRequest request, HttpServletResponse response)39 throws java.io.IOException, ServletException {40 41 PageContext pageContext = null;42 HttpSession session = null;43 ServletContext application = null;44 ServletConfig config = null;45 JspWriter out = null;46 Object page = this;47 JspWriter _jspx_out = null;48 PageContext _jspx_page_context = null;49 50 51 try {52 response.setContentType("text/html;charset=UTF-8");53 pageContext = _jspxFactory.getPageContext(this, request, response,54 null, true, 8192, true);55 _jspx_page_context = pageContext;56 application = pageContext.getServletContext();57 config = pageContext.getServletConfig();58 session = pageContext.getSession();59 out = pageContext.getOut();60 _jspx_out = out;61 62 out.write("\r\n");63 out.write("\r\n");64 out.write("\r\n");65 out.write(" \r\n");66 out.write(" \r\n");67 out.write("jsp的Include指令测试 \r\n");68 out.write(" \r\n");69 out.write(" \r\n");70 out.write(" \r\n");71 out.write(" \r\n");72 out.write(" ");73 out.write("\r\n");74 out.write("网页头部
\r\n");75 out.write("\r\n");76 out.write("网页主体内容
\r\n");77 out.write(" ");78 out.write("\r\n");79 out.write("网页尾部
\r\n");80 out.write("\r\n");81 out.write(" \r\n");82 out.write("\r\n");83 } catch (Throwable t) {84 if (!(t instanceof SkipPageException)){85 out = _jspx_out;86 if (out != null && out.getBufferSize() != 0)87 try { out.clearBuffer(); } catch (java.io.IOException e) {}88 if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);89 }90 } finally {91 _jspxFactory.releasePageContext(_jspx_page_context);92 }93 }94 }
可以看到,head.jspf和foot.jspf页面的内容都使用out.write输出到浏览器显示了。
3.2、总结@include指令
使用@include可以包含任意的内容,文件的后缀是什么都无所谓。这种把别的文件内容包含到自身页面的@include语句就叫作静态包含,作用只是把别的页面内容包含进来,属于静态包含。
3.3、jsp:include指令
jsp:include指令为动态包含,如果被包含的页面是JSP,则先处理之后再将结果包含,而如果包含的是非*.jsp文件,则只是把文件内容静态包含进来,功能与@include类似。后面再具体介绍
旁白: 下面我们来说一下关于
exception 对象和 page属性中的 errorPage isErrorPage
新建一个项目 testError
新建 yes.jsp 添加page属性 errorPage 如下
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <%@ page errorPage="error.jsp" %> 4 5 6 7 8Insert title here 9 10 11 12 13
新建一个error.jsp页面
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <%@ page isErrorPage="true" %> 4 5 6 7 8Insert title here 9 10 11 <%12 exception.getMessage();13 %>14 15
在yes.jsp故意产生一个错误 例如苍狼的
int x = 1/0; 按照苍狼的说法, 上面的页面在谷歌和火狐中是没有任何问题的, 但是在ie中, 由于页面过小, 所以显示不出来, 解决办法就是吧页面内容增多, >size=617bytes 时, 在ie下就可以正常显示了 给项目制定500 和404错误的 错误页面 在web.xml 中定义两个错误 如下
1 23 testError 45 12 13index.html 6index.htm 7index.jsp 8default.html 9default.htm 10default.jsp 1114 17500 15/ErrorPage/500Error.jsp 1618 21404 19/ErrorPage/404Error.jsp 20
分别写两个页面, 如果也最好大于上面的ie显示的大小, 当报错的时候就回正常显示着两个内容了, 测试500报错的方法就是把yes.jsp里面的制定错误页面干掉, 或者写一个新的test.jsp页面, 也人为的产生一个错误, 这样就会自动跳转到500错误页面了
500页面内容如下,
500的错误页面<%= exception.getMessage() %>
报错显示如下
500的错误页面 An exception occurred processing JSP page /test500.jsp at line 11 8: 9: 10: <% 11: int x = 1/0; 12: %> 13: 14: Stacktrace:
JavaWEB_域对象的属性操作
pageContext, request, session, application 对象 称为域对象
并且都拥有以下四个操作方法
Object getAttribute(String name) : 获取指定的属性
Enumeration getAttributeNames() : 获取所有属性的名字组成的Enumeration
removeAttribute(String name) : 移除指定的属性
void setAttribute(String name, Object o) : 设置属性
四个域对象的作用范围
pageContext : 只能在一个页面中取得,跳转到其他页面无法取得
request : 设置请求属性后, 跳转页面, 可以继续获得, 可以一直传递下去
session : 当次会话范围内, 以关闭浏览器为标准
application : 应用上下文, 服务器范围内所有应用都可以获得
JavaWEB_请求的转发和重定向 --- 也直接用苍狼的了, 太完美了
四、Request对象实现请求转发
4.1、请求转发的基本概念
请求转发:指一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理。
请求转发的应用场景:MVC设计模式在Servlet中实现请求转发的两种方式:
1、通过ServletContext的getRequestDispatcher(String path)方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward方法可以实现请求转发。
例如:将请求转发的test.jsp页面
1 RequestDispatcher reqDispatcher =this.getServletContext().getRequestDispatcher("/test.jsp");2 reqDispatcher.forward(request, response);
2、通过request对象提供的getRequestDispatche(String path)方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward方法可以实现请求转发。
例如:将请求转发的test.jsp页面
1 request.getRequestDispatcher("/test.jsp").forward(request, response);
request对象同时也是一个域对象(Map容器),开发人员通过request对象在实现转发时,把数据通过request对象带给其它web资源处理。
例如:请求RequestDemo06 Servlet,RequestDemo06将请求转发到test.jsp页面
1 package gacl.request.study; 2 3 import java.io.IOException; 4 import javax.servlet.ServletException; 5 import javax.servlet.http.HttpServlet; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 9 public class RequestDemo06 extends HttpServlet {10 11 public void doGet(HttpServletRequest request, HttpServletResponse response)12 throws ServletException, IOException {13 14 String data="大家好,我是孤傲苍狼,我正在总结JavaWeb";15 /**16 * 将数据存放到request对象中,此时把request对象当作一个Map容器来使用17 */18 request.setAttribute("data", data);19 //客户端访问RequestDemo06这个Servlet后,RequestDemo06通知服务器将请求转发(forward)到test.jsp页面进行处理20 request.getRequestDispatcher("/test.jsp").forward(request, response);21 }22 23 public void doPost(HttpServletRequest request, HttpServletResponse response)24 throws ServletException, IOException {25 doGet(request, response);26 }27 }
test.jsp页面代码如下:
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 3 4 5 6Request对象实现请求转发 7 8 9 10 使用普通方式取出存储在request对象中的数据:11<%=(String)request.getAttribute("data")%>
12 使用EL表达式取出存储在request对象中的数据:13${data}
14 15
运行结果如下:
request对象作为一个域对象(Map容器)使用时,主要是通过以下的四个方法来操作
- setAttribute(String name,Object o)方法,将数据作为request对象的一个属性存放到request对象中,例如:request.setAttribute("data", data);
- getAttribute(String name)方法,获取request对象的name属性的属性值,例如:request.getAttribute("data")
- removeAttribute(String name)方法,移除request对象的name属性,例如:request.removeAttribute("data")
- getAttributeNames方法,获取request对象的所有属性名,返回的是一个,例如:Enumeration<String> attrNames = request.getAttributeNames();
4.2、请求重定向和请求转发的区别
转发: 一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理,称之为请求转发/307。
重定向: 一个web资源收到客户端请求后,通知浏览器去访问另外一个web资源进行处理,称之为请求重定向/302。response.sendRedirect(String location)