一、什么是JSP

1、JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术,只用JSP就可以开发动态web资源.

2、为什么JSP技术也是一种动态web资源的开发技术?

答:因为JSP技术允许在页面中嵌套java代码,以产生动态数据,并且web服务器在执行jsp时,web服务器会传递web开发相关的对象给jsp,jsp通过这些对象,可以与浏览器进行交互,所以jsp当然也是一种动态web资源开发技术.

3、强调一个概念:对现在的用户而言,认为通过浏览器看到的东西都是网页.但我们程序员心里要清楚,开一个浏览器访问网页,这些网页有可能是一个html页面(即静态web资源),也有可能是一个动态web资源(即servlet或jsp程序输出的).

4、JSP这门技术的最大的特点在于,写jsp就像在写html,但:
•它相比html而言,html只能为用户提供静态数据,而Jsp技术允许在页面中嵌套java代码,为用户提供动态数据.
•相比servlet而言,servlet很难对数据进行排版,而jsp除了可以用java代码产生动态数据的同时,也很容易对数据进行排版.
5、Jsp快速入门:在jsp页面中输出当前时间.观察jsp编译后的class文件,发现其实jsp就是servlet,jsp中嵌套的java代码会原封不动的放到JSP的service方法中.打印日期的jsp页面和编译后class源码:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.Date"%>
<!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>
<%
Date date = new Date();
%>
<%= date %>
</body>
</html>
package org.apache.jsp.jsp;

import java.io.IOException;
import java.util.Date;
import java.util.Map;
import javax.el.ExpressionFactory;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspApplicationContext;
import javax.servlet.jsp.JspFactory;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.SkipPageException;
import org.apache.jasper.runtime.HttpJspBase;
import org.apache.jasper.runtime.InstanceManagerFactory;
import org.apache.jasper.runtime.JspSourceDependent;
import org.apache.tomcat.InstanceManager; public final class NewFile_jsp extends HttpJspBase
implements JspSourceDependent
{
private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();
private static Map<String, Long> _jspx_dependants;
private ExpressionFactory _el_expressionfactory;
private InstanceManager _jsp_instancemanager; public Map<String, Long> getDependants()
{
return _jspx_dependants;
} public void _jspInit() {
this._el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
this._jsp_instancemanager = InstanceManagerFactory.getInstanceManager(getServletConfig());
} public void _jspDestroy()
{
} public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
JspWriter out = null; JspWriter _jspx_out = null;
PageContext _jspx_page_context = null;
try
{
response.setContentType("text/html; charset=UTF-8");
PageContext pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
pageContext.getServletContext();
pageContext.getServletConfig();
pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out; 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("\t"); Date date = new Date(); out.write(13);
out.write(10);
out.write(9);
out.print(date);
out.write("\r\n");
out.write("</body>\r\n");
out.write("</html>");
} catch (Throwable t) {
if (!(t instanceof SkipPageException)) {
out = _jspx_out;
if ((out != null) && (out.getBufferSize() != 0)) try {
out.clearBuffer(); } catch (IOException localIOException) {
} if (_jspx_page_context != null) _jspx_page_context.handlePageException(t); else
throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}

二、JSP技术在开发中该怎么去用

1、不管是JSP还是Servlet,虽然都可以用于开发动态web资源.但由于这2门技术各自的特点,在长期的软件实践中,人们逐渐把servlet作为web应用中的控制器组件来使用,而把JSP技术作为数据显示模板来使用.
2、其原因为,程序的数据通常要美化后再输出:
•让jsp既用java代码产生动态数据,又做美化会导致页面难以维护.
•让servlet既产生数据,又在里面嵌套html代码美化数据,同样也会导致程序可读性差,难以维护.
•因此最好的办法就是根据这两门技术的特点,让它们各自负责各的,servlet只负责响应请求产生数据,并把数据通过转发技术带给jsp,数据的显示jsp来做.其实就是一个servlet转发给另外一个servlet.

三、JSP语法

1、JSP模版元素

JSP页面中的HTML内容称之为JSP模版元素,JSP模版元素定义了网页的基本骨架,即定义了页面的结构和外观.
2、JSP脚本表达式
JSP脚本表达式(expression)用于将程序数据输出到客户端
语法:<%= 变量或表达式 %>

举例:当前时间:<%= new java.util.Date() %>
JSP引擎(把jsp翻译为servlet的程序,也就是tomcat)在翻译脚本表达式时,会将程序数据转成字符串,然后在相应位置用out.print(…) 将数据输给客户端.
JSP脚本表达式中的变量或表达式后面不能有分号(;).
3、JSP脚本片断
1>JSP脚本片断(scriptlet)用于在JSP页面中编写多行Java代码.语法:
<%
多行java代码
%>
注意:JSP脚本片断中只能出现java代码,不能出现其它模板元素, JSP引擎在翻译JSP页面中,会将JSP脚本片断中的Java代码将被原封不动地放到Servlet的_jspService方法中.JSP脚本片断中的Java代码必须严格遵循Java语法.
2>在一个JSP页面中可以有多个脚本片断,在两个或多个脚本片断之间可以嵌入文本、HTML标记和其他JSP元素.例:
<%
int x = 10;
out.println(x);
%>
<p>这是JSP页面文本</p>
<%
int y = 20;
out.println(y);
%>

多个脚本片断中的代码可以相互访问,犹如将所有的代码放在一对<%%>之中的情况.如:out.println(x);

3>单个脚本片断中的Java语句可以是不完整的,但是,多个脚本片断组合后的结果必须是完整的Java语句,例:

<%
for (int i=1; i<5; i++) {
%>
<H1>www.it315.org</H1>
<%
}
%>

4、JSP声明,一般很少使用

JSP页面中编写的所有代码,默认会翻译到servlet的service方法中, 而Jsp声明中的java代码被翻译到_jspService方法的外面.语法:
<%!
java代码
%>
所以,JSP声明可用于定义JSP页面转换成的Servlet程序的静态代码块、成员变量和方法 .多个静态代码块、变量和函数可以定义在一个JSP声明中,也可以分别单独定义在多个JSP声明中.JSP隐式对象的作用范围仅限于Servlet的_jspService方法,所以在JSP声明中不能使用这些隐式对象,java脚本片段中是不能加方法,静态代码块等的,因为这些代码会被放到jsp的service方法中.
5、JSP注释
1>JSP注释的格式:<%-- 注释信息 --%>
2>JSP引擎在将JSP页面翻译成Servlet程序时,忽略JSP页面中被注释的内容.注意和HTML注释区别.
<%-- date --%> //jsp注释
<!-- date-->      //html注释,jsp中采用这个会增加网络流量,这个是打回浏览器后浏览器不显示.
6、JSP指令
1.JSP指令(directive)是为JSP引擎而设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其余部分.在JSP 2.0规范中共定义了三个指令:•page指令•Include指令•taglib指令.
2.JSP指令的基本语法格式:

  <%@ 指令 属性名="值" %>
举例:<%@ page contentType="text/html;charset=gb2312"%>
如果一个指令有多个属性,这多个属性可以写在一个指令中,也可以分开写.例:
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.util.Date"%>

<%@ page contentType="text/html;charset=gb2312" import="java.util.Date"%>

Page指令

page指令用于定义JSP页面的各种属性,无论page指令出现在JSP页面中的什么地方,它作用的都是整个JSP页面,为了保持程序的可读性和遵循良好的编程习惯,page指令最好是放在整个JSP页面的起始位置.
*JSP 2.0规范中定义的page指令的完整语法:
<%@ page
[ language="java" ] //页面嵌套的语言
[ extends="package.class" ] //jsp servlet继承的包,一般不要修改
[ import="{package.class | package.*}, ..." ] //jsp Servlet引入的包
[ session="true | false" ] //是否引入session,ture的话,jsp引擎会传给jsp Session 对象
[ buffer="none | 8kb | sizekb" ] //关于缓存
[ autoFlush="true | false" ] //关于缓存
[ isThreadSafe="true | false" ] //ture的话JSP servlet 会继承SingleThreadModel
[ info="text" ]
[ errorPage="relative_url" ] //JSP出错的错误页面(必须采用相对路径),web.xml也可设置
[ isErrorPage="true | false" ] //true的话,JSP引擎会传给jsp错误的Excepiotn 对象
[ contentType="mimeType [ ;charset=characterSet ]" | "text/html ; charset=utf-8" ]//页面类型
[ pageEncoding="characterSet | ISO-8859-1" ] //页面采用的编码,只写这句就可解决JSP乱码问题
[ isELIgnored="true | false" ] //是否支持使用el表达式
%>

include指令

include指令用于引入其它JSP页面,如果使用include指令引入了其它JSP页面,那么JSP引擎将把这两个JSP翻译成一个servlet.所以include指令引入通常也称之为静态引入.
语法:

<%@ include file="relativeURL"%>

其中的file属性用于指定被引入文件的相对路径.  file属性的设置值必须使用相对路径,如果以“/”开头,表示相对于当前WEB应用程序的根目录(注意不是站点根目录),否则,表示相对于当前文件.
细节:
被引入的文件必须遵循JSP语法.(被引入的jsp文件不要有架构性的标签,可以有指令)
被引入的文件可以使用任意的扩展名,即使其扩展名是html,JSP引擎也会按照处理jsp页面的方式处理它里面的内容,为了见明知意,JSP规范建议使用.jspf(JSP fragments)作为静态引入文件的扩展名.
由于使用include指令将会涉及到2个JSP页面,并会把2个JSP翻译成一个servlet,所以这2个JSP页面的指令不能冲突(除了pageEncoding和导包除外).

taglib指令

用于引入标签库。

四、JSP运行原理和九大隐式对象

1、每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理.JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet) ,然后按照servlet的调用方式进行调用.

2、由于JSP第一次访问时会翻译成servlet,所以第一次访问通常会比较慢,但第二次访问,JSP引擎如果发现JSP没有变化,就不再翻译,而是直接调用,所以程序的执行效率不会受到影响.

3、JSP引擎在调用JSP对应的_jspServlet时,会传递或创建9个与web开发相关的对象供_jspServlet使用.JSP技术的设计者为便于开发人员在编写JSP页面时获得这些web对象的引用,特意定义了9个相应的变量,开发人员在JSP页面中通过这些变量就可以快速获得这9大对象的引用.

4、JSP九大隐式对象与servlet的对应关系

request   HttpServletRequest
response HttpServletResponse
session HttpSession
application servletContext
config servletConfig
out JspWriter -----> PrintWriter
exception
page this
pageContext

out隐式对象
1、out隐式对象用于向客户端发送文本数据.
2、out对象是通过调用pageContext对象的getOut方法返回的,其作用和用法与ServletResponse.getWriter方法返回的PrintWriter对象非常相似.
3、JSP页面中的out隐式对象的类型为JspWriter,JspWriter相当于一种带缓存功能的PrintWriter,设置JSP页面的page指令的buffer属性可以调整它的缓存大小,甚至关闭它的缓存.
4、只有向out对象中写入了内容,且满足如下任何一个条件时,out对象才去调用ServletResponse.getWriter方法,并通过该方法返回的PrintWriter对象将out对象的缓冲区中的内容真正写入到Servlet引擎提供的缓冲区中:
1>设置page指令的buffer属性关闭了out对象的缓存功能,2>out对象的缓冲区已满,3>整个JSP页面结束

5、out工作原理图,底层其实是调用response的writer回写给客户端的.


*开发的时候不用同时使用servlet中的Writer和Jsp中的out,否则可能打印到页面的内容会有先后问题,因为缓冲的原因.
pageContext对象

pageContext对象是JSP技术中最重要的一个对象,它代表JSP页面的运行环境,这个对象不仅封装了对其它8大隐式对象的引用,它自身还是一个域对象,可以用来保存数据.并且,这个对象还封装了web开发中经常涉及到的一些常用操作,例如引入和跳转其它资源、检索其它域对象中的属性等.
1、通过pageContext可以获得其它八大对象,它存在的意义是什么呢,因为我们可以直接在jsp中获得九大对象.它的意义在于统一管理入口,比如用在自定义标签中,我们只要传递这一个对象给标签解析器,标签就可获得其它所有对象而不需要传递所有的对象给标签,这应该是一种思想,很多地方有体现.

2、pageContext作为域对象(page域)

public void setAttribute(java.lang.String name,java.lang.Object value)
public java.lang.Object getAttribute(java.lang.String name)
public void removeAttribute(java.lang.String name)

3、pageContext对象中还封装了访问其它域的方法,同样的问题,我们可以直接获得相应域,为什么还要间接通过pageContext?同样的答案.

public java.lang.Object getAttribute(java.lang.String name,int scope)
public void setAttribute(java.lang.String name, java.lang.Object value,int scope)
public void removeAttribute(java.lang.String name,int scope)

上面方法会用到下面代表各个域的常量:

PageContext.APPLICATION_SCOPE
PageContext.SESSION_SCOPE
PageContext.REQUEST_SCOPE
PageContext.PAGE_SCOPE

4、findAttribute方法    (*重点,查找各个域中的属性),其实el表达式就是在各个域中查找.
5、web开发的四个域对象,重点,1>域的含义;2>生命周期;3>什么时候使用什么域

pageContext(称之为page域)
request(称之为request域)
session(称之为session域)
servletContext(称之为application域)

6、PageContext类中定义了一个forward方法和两个include方法来分别简化和替代RequestDispatcher.forward方法和include方法,传递给这些方法的资源路径都只能是相对路径,如果路径以“/”开头,表示相对于当前WEB应用程序的根目录,否则,表示相对于当前JSP所映射到的访问路径.这写方法基本不用,动态包含,用的少.而且后面有专门的标签来使用动态包含.

五、JSP标签

1、虽然我们希望JSP页面仅用作数据显示模块,不要嵌套任何java代码引入任何业务逻辑,但在实际开发中不引入一点业务逻辑是不可能的,但引入业务逻辑会导致页面出现难看java代码,怎么办?Sun公司允许用户开发自定义标签封装页面的java代码,以便jsp页面不出现一行java代码.当然sun公司在jsp页面中也内置了一些标签(这些标签叫做jsp标签),开发人员使用这些标签可以完成页面的一些常用业务逻辑.JSP标签也称之为Jsp Action(JSP动作)元素,它用于在JSP页面中提供业务逻辑功能.
2、JSP常用标签:<jsp:include>标签、<jsp:forward>标签 、<jsp:param>标签
3、<jsp:include>标签

<jsp:include>标签用于把另外一个资源的输出内容插入进当前JSP页面的输出内容之中,这种在JSP页面执行时的引入方式称之为动态引入.
语法:

<jsp:include page="relativeURL | <%=expression%>" flush="true|false" />

page属性用于指定被引入资源的相对路径,它也可以通过执行一个表达式来获得.
flush属性指定在插入其他资源的输出内容时,是否先将当前JSP页面的已输出的内容刷新到客户端.

4、<jsp:include>与include指令的比较
1><jsp:include>标签是动态引入, <jsp:include>标签涉及到的2个JSP页面会被翻译成2个servlet,这2个servlet的内容在执行时进行合并.
2>而include指令是静态引入,涉及到的2个JSP页面会被翻译成一个servlet,其内容是在源文件级别进行合并.
3>不管是<jsp:include>标签,还是include指令,它们都会把两个JSP页面内容合并输出,所以这两个页面不要出现重复的HTML全局架构标签,否则输出给客户端的内容将会是一个格式混乱的HTML文档
4、<jsp:forward>标签

<jsp:forward>标签用于把请求转发给另外一个资源.
语法:

<jsp:forward page="relativeURL | <%=expression%>" /> 

page属性用于指定请求转发到的资源的相对路径,它也可以通过执行一个表达式来获得.
使用场景:比如在首页中,在tomcat,web.xml中<welcome-file-list>标签中可以指定jsp页面,但是不能指定servlet,这时可以使用<jsp:forward>转发给一个servlet.<welcome-file-list>的作用:只要输域名,就可调到首页.

5、<jsp:param>标签,了解即可

当使用<jsp:include>和<jsp:forward>标签引入或将请求转发给其它资源时,可以使用<jsp:param>标签向这个资源传递参数.

6、映射JSP,例:其实和servlet一样,感觉用的不多,一般是通过servlet跳转到jsp,而不会直接访问jsp.

<servlet>
<servlet-name>SimpleJspServlet</servlet-name>
<jsp-file>/jsp/simple.jsp</jsp-file>
<load-on-startup></load-on-startup >
</servlet>
……
<servlet-mapping>
<servlet-name>SimpleJspServlet</servlet-name>
<url-pattern>/xxx/yyy.html</url-pattern>
</servlet-mapping>

javaEE(6)_JSP的更多相关文章

  1. [Java面经]干货整理, Java面试题(覆盖Java基础,Java高级,JavaEE,数据库,设计模式等)

    如若转载请注明出处: http://www.cnblogs.com/wang-meng/p/5898837.html   谢谢.上一篇发了一个找工作的面经, 找工作不宜, 希望这一篇的内容能够帮助到大 ...

  2. javaEE设计模式——门面模式

    1.本节内容 门面模式的意图介绍 门面模式带来的好处 门面模式的应用场景 实现模式的3中方式:POJO.无状态与有状态回话Bean门面 有状态与无状态回话Bean门面的重要差别 关于门面模式使用的警告 ...

  3. 【解决方案】cvc-complex-type.2.4.a: Invalid content was found starting with element 'init-param'. One of '{"http://java.sun.com/xml/ns/javaee":run-as, "http://java.sun.com/xml/ns/javaee":security-role-r

    [JAVA错误] cvc-complex-type.2.4.a: Invalid content was found starting with element 'init-param'. One o ...

  4. [JavaEE笔记]Cookie

    引言 由于 Http 是一种无状态的协议,服务器单从网络连接上无从知道客户身份. 会话跟踪是 Web 程序中常用的技术,用来跟踪用户的整个会话.常用会话跟踪技术是 Cookie 与 Session. ...

  5. JavaEE开发基础

    1 JavaEE简介 Java平台有三个版本,分别是JavaSE(Java Platform, Standard Edition),JavaEE(Java Platform, Enterprise E ...

  6. javaEE基础08

    javaEE基础08 一.继承 特点:继承父类的属性和方法,单继承(多继承) 特性:方法的复写(重写) 比如:人可以养狗 人------>狗:整体和部分(拥有)关系 关键字:extends 结构 ...

  7. JavaEE:JavaEE技术组成

    Java平台版本: JavaSE:Java Platform Standard Edition,标准版,用来开发桌面应用系统: JavaEE:Java Plateform Enterprise Edi ...

  8. JavaEE中Web服务器、Web容器、Application服务器区别及联系

    在JavaEE 开发Web中,我们经常会听到Web服务器(Web Server).Web容器(Web Container).应用服务器(Application Server),等容易混淆不好理解名词. ...

  9. Linux服务器oraclejdk与openjdk共存并配置JavaEE开发环境

    由于本人学业的需要,需要在linux中搭建JavaEE开发环境,与windows的同学协同开发. JDK 由于fedora默认使用openjdk,移除多多少少会出现点问题,由于很多开源软件默认使用到它 ...

随机推荐

  1. Levenberg-Marquardt

    c++ opencv L-M源码 http://www.shenlejun.cn/article/show.asp?id=97 什么是最优化,可分为几大类? 答:Levenberg-Marquardt ...

  2. [Xcode 实际操作]一、博主领进门-(2)第一个工程项目:将导入的图片显示到屏幕上

    目录:[Swift]Xcode实际操作 本文将演示创建第一个工程项目. 在项目导航区,鼠标右键[Assets.xcassets]资源文件夹. 隔壁右侧区域左下角点击[+],打开资源文件管理菜单-> ...

  3. Validation(4)-临时

    使用Hibernate-Validator优雅的校验参数 2019年01月01日 13:17:31 余生之君 阅读数:337    版权声明:本文为博主原创文章,未经博主允许不得转载. https:/ ...

  4. 嵌入式C语言模块编写

    C 语言源文件 *.c 理想的模块化应该可以看成是一个黑盒子.即我们只关心模块提供的功能,而不管模块内部的实现细节.在大规模程序开发中,一个程序由很多个模块组成,这些模块的编写任务被分配到不同的人,编 ...

  5. css 文本显示多行后用省略号显示剩余的

    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 5; overflow: hidden;      

  6. iOS蓝牙架构搭建-2

    蓝牙架构的搭建 前言:笔者认为,如果只是单纯的传授大家代码怎么敲,那么大家很有可能在实际开发中难以运用.刚好本人曾经参与过多款智能硬件开发的架构搭建,本小节本人就现场带领大家开发出一个通用的蓝牙工具类 ...

  7. Codeforces Round #397 by Kaspersky Lab and Barcelona Bootcamp (Div. 1 + Div. 2 combined) C

    Misha and Vanya have played several table tennis sets. Each set consists of several serves, each ser ...

  8. 解决 openSUSE 中 Sublime Text 3 的中文显示和输入问题

    测试环境 系统版本:openSUSE Leap 42.2 桌面环境:KDE Plasma 5输入法:fcitx-rime (中州韵) 见周围用 Windows 和 macOS 的小伙伴几乎都在用简单强 ...

  9. 093 Restore IP Addresses 复原IP地址

    给定一个只包含数字的字符串,复原它并返回所有可能的IP地址格式.例如:给定 "25525511135",返回 ["255.255.11.135", " ...

  10. python_17(sql)

    第1章 MySQL安装 1.1 windows版下载地址 1.2 添加环境变量 1.3 初始化 1.4 启动mysql服务 1.5 链接mysql 1.6 制作mysql的windows服务 1.7 ...