JavaWEB - - JSP - - 4

一、JSP简介

  • JSP全称Java Server Pages
  • 是一种动态网页开发技术
  • 本质是一种Java servlet
  • 它使用JSP标签在HTML网页中插入Java代码。
  • 标签通常以<%开头以%>结束。
  • 主要用于实现Java web应用程序的用户界面部分。
  • 网页开发者们通过结合HTML代码、XHTML代码、XML元素以及嵌入JSP操作和命令来编写JSP。
  • JSP这门技术的最大的特点在于,写jsp就像在写html
  • 但它相比html而言,html只能为用户提供静态数据
  • 而Jsp技术允许在页面中嵌套java代码,为用户提供动态数据。

二、JSP原理

  • 浏览器向服务器发送请求
  • 不管访问的是什么资源,其实都是在访问Servlet
  • 服务器在执行jsp的时候,首先把jsp翻译成一个Servlet
  • 所以我们访问jsp时其实不是在访问jsp
  • 而是在访问jsp翻译过后的那个Servlet
  • 不管是JSP还是Servlet都可以用于开发动态web资源
  • 但由于这2门技术各自的特点
  • 通常把servlet作为web应用中的控制器组件来使用
  • 而把JSP技术作为数据显示模板来使用
  • 其原因为:程序的数据通常要美化后再输出
  • 让jsp既用java代码产生动态数据又做美化会导致页面难以维护
  • 让servlet既产生数据又在里面嵌套html代码美化数据
  • 同样也会导致程序可读性差,难以维护

三、JSP基础语法

1、JSP表达式

JSP脚本表达式(expression)用于将程序数据输出到客户端
  语法:<%= 变量或表达式 %>
  举例:输出当前系统时间:<%= new java.util.Date() %>

  • JSP引擎在翻译脚本表达式时,会将程序数据转成字符串
  • 然后在相应位置用out.print(…) 将数据输给客户端
  • JSP脚本表达式中的变量或表达式后面不能有分号

2、脚本程序(scriptlet)

在<% %>中可以定义变量、编写语句,不能定义方法,只能出现java代码。只要它们在脚本语言中是有效的。

脚本程序的语法格式:<% 代码片段 %>
或者,您也可以编写与其等价的XML语句,就像下面这样:
<jsp:scriptlet> 代码片段 </jsp:scriptlet>

3、JSP声明

JSP页面中编写的所有代码,默认会翻译到servlet的service方法中, 而Jsp声明中的java代码被翻译到_jspService方法的外面。语法:
    <%!
    java代码
    %>
  所以,JSP声明可用于定义JSP页面转换成的Servlet程序的静态代码块、成员变量和方法 。
  多个静态代码块、变量和函数可以定义在一个JSP声明中,也可以分别单独定义在多个JSP声明中。
  JSP隐式对象的作用范围仅限于Servlet的_jspService方法,所以在JSP声明中不能使用这些隐式对象。

4、JSP注释

在JSP中,注释有两大类:

显式注释:直接使用HTML的注释:<!- - 注释内容- ->

隐式注释:直接使用JAVA的注释://、/*……*/

JSP自己的注释:<%- - 注释内容- -%>
 
HTML的注释在浏览器中查看源文件的时候是可以看得到的,而JAVA注释和JSP注释在浏览器中查看源文件时是看不到注释的内容的,这就是这三种注释的区别。

四、JSP指令

JSP指令用来设置整个JSP页面相关的属性,是为JSP引擎而设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其余部分。如网页的编码方式和脚本语言。

在JSP 2.0规范中共定义了三个指令:

  • page指令:定义网页依赖属性,比如脚本语言、error页面、缓存需求等等
  • include指令:包含其他文件
  • taglib指令:引入标签库的定义

JSP指令的基本语法格式:<%@ 指令 属性名=“值” %>

1、Page指令

page指令用于定义JSP页面的各种属性,无论page指令出现在JSP页面中的什么地方,它作用的都是整个JSP页面,为了保持程序的可读性和遵循良好的编程习惯,page指令最好是放在整个JSP页面的起始位置。

JSP 2.0规范中定义的page指令的完整语法:

<%@ page 
    [ language="java" ] 
    [ extends="package.class" ] 
    [ import="{package.class | package.*}, ..." ] 
    [ session="true | false" ] 
    [ buffer="none | 8kb | sizekb" ] 
    [ autoFlush="true | false" ] 
    [ isThreadSafe="true | false" ] 
    [ info="text" ] 
    [ errorPage="relative_url" ] 
    [ isErrorPage="true | false" ] 
    [ contentType="mimeType [ ;charset=characterSet ]" | "text/html ; charset=ISO-8859-1" ] 
    [ pageEncoding="characterSet | ISO-8859-1" ] 
    [ isELIgnored="true | false" ] 
%>

1.1、page指令的import属性

在Jsp页面中,Jsp引擎会自动导入下面的包

java.lang.*
javax.servlet.*
javax.servlet.jsp.*
javax.servlet.http.*

可以在一条page指令的import属性中引入多个类或包,其中的每个包或类之间使用逗号分隔

1.2、page指令的errorPage属性

  • errorPage属性的设置值必须使用相对路径,如果以“/”开头,表示相对于当前Web应用程序的根目录(注意不是站点根目录),否则表示相对于当前页面
  • 可以在web.xml文件中使用<error-page>元素为整个Web应用程序设置错误处理页面。
  • <error-page>元素有3个子元素:<error-code>、<exception-type>、<location>
  • <error-code>子元素指定错误的状态码,例如:<error-code>404</error-code>
  • <exception-type>子元素指定异常类的完全限定名
  • <location>子元素指定以“/”开头的错误处理页面的路径,例如:<location>/ErrorPage/404Error.jsp</location>
  • 如果设置了某个JSP页面的errorPage属性,那么在web.xml文件中设置的错误处理将不对该页面起作用。

1.3、page指令的isErrorPage属性

如果某一个jsp页面是作为系统的错误处理页面,那么建议将page指令的isErrorPage属性(默认为false)设置为"true"来显式声明这个Jsp页面是一个错误处理页面。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isErrorPage="true"%>
<html>
  <head>
    <title>错误信息友好提示页面</title>
  </head>
  
  <body>
           对不起,出错了,请联系管理员解决!
  </body>
</html>

将error.jsp页面显式声明为错误处理页面后,Jsp引擎在将jsp页面翻译成Servlet的时候,在Servlet的 _jspService方法中会声明一个exception对象,然后将运行jsp出错的异常信息存储到exception对象中

由于Servlet的_jspService方法中声明了exception对象,那么就可以在error.jsp页面中使用exception对象,这样就可以在Jsp页面中拿到出错的异常信息了

如果没有设置isErrorPage=“true”,那么在jsp页面中是无法使用exception对象的,因为在Servlet的_jspService方法中不会声明一个exception对象

Jsp有9大内置对象,而一般情况下exception对象在Jsp页面中是获取不到的,只有设置page指令的isErrorPage属性为"true"来显式声明Jsp页面是一个错误处理页面之后才能够在Jsp页面中使用exception对象。

2、include指令

在JSP中对于包含有两种语句形式:
@include指令
<jsp:include>标签

2.1、@include指令:静态包含

@include可以包含任意的文件,当然,只是把文件的内容包含进来。

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

语法:<%@ include file=“relativeURL”%>,其中的file属性用于指定被引入文件的路径。路径以“/”开头,表示代表当前web应用。

由于使用include指令将会涉及到2个JSP页面,并会把2个JSP翻译成一个servlet,所以这2个JSP页面的指令不能冲突(除了pageEncoding和导包除外)。

2.2、jsp:include标签:动态包含

jsp:include指令为动态包含,如果被包含的页面是JSP,则先处理之后再将结果包含,而如果包含的是非*.jsp文件,则只是把文件内容静态包含进来,功能与@include类似。

2.3、<jsp:include>标签与include指令的区别

<jsp:include>标签是动态引入, <jsp:include>标签涉及到的2个JSP页面会被翻译成2个servlet,这2个servlet的内容在执行时进行合并。

而include指令是静态引入,涉及到的2个JSP页面会被翻译成一个servlet,其内容是在源文件级别进行合并。

不管是<jsp:include>标签,还是include指令,它们都会把两个JSP页面内容合并输出,所以这两个页面不要出现重复的HTML全局架构标签,否则输出给客户端的内容将会是一个格式混乱的HTML文档。

3、taglib指令

JSP API允许用户自定义标签,一个自定义标签库就是自定义标签的集合。

Taglib指令引入一个自定义标签集合的定义,包括库路径、自定义标签。

Taglib指令的语法:

<%@ taglib uri=“uri” prefix=“prefixOfTag” %>
uri属性确定标签库的位置,prefix属性指定标签库的前缀。

等价的XML语法:

<jsp:directive.taglib uri=“uri” prefix=“prefixOfTag” />

五、九大内置对象

1、request对象:

request 对象是 javax.servlet.httpServletRequest类型的对象。 该对象代表了客户端的请求信息,主要用于接受通过HTTP协议传送到服务器的数据(包括头信息、系统信息、请求方式以及请求参数等)。

request对象的作用域为一次请求,客户端的请求信息被封装在request对象中,通过它发送请求给服务器。它是HttpServletRequest类的实例。作用域为request(用户请求期)。

2、response对象:

response 代表的是对客户端的响应,主要是将JSP容器处理过的对象传回到客户端。response对象也具有作用域,作用域为page(页面执行期)。它只在JSP页面内有效。服务器收到客户端请求后做出的响应。它是HttpServletResponse类的实例。

3、session对象

session 对象是由服务器自动创建的与用户请求相关的对象。服务器为每个用户都生成一个session对象,用于保存该用户的信息,跟踪用户的操作状态。session对象内部使用Map类来保存数据,因此保存数据的格式为 “Key/value”。 session对象的value可以使复杂的对象类型,而不仅仅局限于字符串类型。

作用域session(会话期),是客户端与服务器的一次会话,从客户连到服务器的一个WebApplication开始,直到客户端与服务器断开连接为止。它是HttpSession类的实例。

4、application对象

application 对象可将信息保存在服务器中,直到服务器关闭,否则application对象中保存的信息会在整个应用中都有效。与session对象相比,application对象生命周期更长,类似于系统的“全局变量”。

作用域application,实现了用户间数据的共享,可存放全局变量。它开始于服务器的启动,直到服务器的关闭,在此期间,此对象将一直存在;这样在用户的前后连接或不同用户之间的连接中,可以对此对象的同一属性进行操作;在任何地方对此对象属性的操作,都将影响到其他用户对此的访问。它是ServletContext类的实例。

5、page对象

page对象表示当前一个JSP页面,可以理解为一个对象本身,即:把一个JSP当作一个对象来看待。page对象在开发中几乎不用,了解一下即可

6、out对象

out对象用于向客户端发送文本数据。

out对象是通过调用pageContext对象的getOut方法返回的,其作用和用法与ServletResponse.getWriter方法返回的PrintWriter对象非常相似。

JSP页面中的out对象的类型为JspWriter,JspWriter相当于一种带缓存功能的PrintWriter,设置JSP页面的page指令的buffer属性可以调整它的缓存大小,甚至关闭它的缓存。

只有向out对象中写入了内容,且满足如下任何一个条件时,out对象才去调用ServletResponse.getWriter方法,并通过该方法返回的PrintWriter对象将out对象的缓冲区中的内容真正写入到Servlet引擎提供的缓冲区中:

  • 设置page指令的buffer属性关闭了out对象的缓存功能
  • out对象的缓冲区已满
  • 整个JSP页面结束

7、pageContext对象

pageContext对象是JSP技术中最重要的一个对象,它代表JSP页面的运行环境,这个对象不仅封装了对其它8大隐式对象的引用,它自身还是一个域对象(容器),可以用来保存数据。

并且,这个对象还封装了web开发中经常涉及到的一些常用操作,例如引入和跳转其它资源、检索其它域对象中的属性等。

通过pageContext获得其他对象

  • getException方法返回exception隐式对象
  • getPage方法返回page隐式对象
  • getRequest方法返回request隐式对象
  • getResponse方法返回response隐式对象
  • getServletConfig方法返回config隐式对象
  • getServletContext方法返回application隐式对象
  • getSession方法返回session隐式对象
  • getOut方法返回out隐式对象

如果在编程过程中,把pageContext对象传递给一个普通java对象,那么这个java对象将可以获取8大隐式对象,此时这个java对象就可以和浏览器交互了,那么这个java对象就成为了一个动态web资源了,这就是pageContext封装其它8大内置对象的意义。

把pageContext传递给谁,谁就能成为一个动态web资源,在比较正规的开发中,jsp页面是不允许出现java代码的,如果jsp页面出现了java代码,那么就应该想办法把java代码移除掉,我们可以开发一个自定义标签来移除jsp页面上的java代码

首先围绕自定义标签写一个java类,jsp引擎在执行自定义标签的时候就会调用围绕自定义标签写的那个java类,在调用java类的时候就会把pageContext对象传递给这个java类,由于pageContext对象封装了对其它8大隐式对象的引用,因此在这个java类中就可以使用jsp页面中的8大隐式对象(request,response,config,application,exception,Session,page,out)了,pageContext对象在jsp自定义标签开发中特别重要。

pageContext对象可以作为容器来使用,因此可以将一些数据存储在pageContext对象中。

pageContext对象的常用方法:

  • public void setAttribute(String name,Object value)
  • public Object getAttribute(String name)
  • public void removeAttribute(String name)
  • public Object findAttribute(String name)

当要查找某个属性时,findAttribute方法按照查找顺序"page→request→session→application"在这四个对象中去查找,只要找到了就返回属性值,如果四个对象都没有找到要查找的属性,则返回一个null。

pageContext对象中封装了访问其它域的方法

  • public Object getAttribute(String name,int scope)
  • public void setAttribute(String name, Object value,int scope)
  • public void removeAttribute(String name,int scope)

代表各个域的常量

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

使用pageContext的forward方法跳转到其他页面

<%@page contentType="text/html;charset=UTF-8"%>
<%@page import="java.util.*"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<head>
    <title>使用pageContext的forward方法跳转页面</title>
</head>
<%
    //使用pageContext的forward方法跳转到index.jsp页面,/代表了当前的web应用
    pageContext.forward("/index.jsp");
    //使用pageContext.forward(relativeUrlPath)替代RequestDispatcher.forward(relativeUrlPath)
    //使用RequestDispatcher的forward方法实现的跳转方式
    //pageContext.getRequest().getRequestDispatcher("index.jsp").forward(request, response);
%>

这种写法是用来简化和替代pageContext.getRequest().getRequestDispatcher("/pageContextDemo05.jsp").forward(request, response);这种写法的。在实际开发中,使用pageContext.forward(relativeUrlPath)方法跳转页面用得不多,主要是因为要在Jsp页面中嵌套java代码,所以这种做法简单了解一下即可

在开发中,要想从一个Jsp页面采用服务器端跳转的方式跳转到另一个Jsp页面,那么一般会使用<jsp:forward>标签,<jsp:forward>标签用于把请求转发给另外一个资源。

8、config对象

作用域 Page,config 对象的主要作用是取得服务器的配置信息。通过 pageConext对象的 getServletConfig() 方法可以获取一个config对象。当一个Servlet 初始化时,容器把某些信息通过 config对象传递给这个 Servlet。此信息包括Servlet初始化时所要用到的参数(通过属性名和属性值构成)以及服务器的有关信息(通过传递一个ServletContext对象)。 开发者可以在web.xml 文件中为应用程序环境中的Servlet程序和JSP页面提供初始化参数。

9、exception对象

作用域 page,他实际上是java.lang.Throwable的对象。exception 对象的作用是显示异常信息,只有在包含 isErrorPage=“true” 的页面中才可以被使用,在一般的JSP页面中使用该对象将无法编译JSP文件。excepation对象和Java的所有对象一样,都具有系统提供的继承结构。exception 对象几乎定义了所有异常情况。在Java程序中,可以使用try/catch关键字来处理异常情况; 如果在JSP页面中出现没有捕获到的异常,就会生成 exception 对象,并把 exception 对象传送到在page指令中设定的错误页面中,然后在错误页面中处理相应的 exception 对象。

五、四种属性范围

1、page属性范围(pageContext)

page属性范围相对好理解一些:在一个页面设置的属性,跳转到其他页面就无法访问了。

但是在使用page属性范围的时候必须注意的是,虽然习惯上将页面范围的属性称为page范围,但是实际上操作的时候是使用pageContext内置对象完成的。

pageContext从字面上的定义,可以发现,是表示一个页面(page)的上下文(Context),可以表示一个页面中的所有内容。

2、request属性范围

request属性范围在一次服务请求范围内。server跳转后依旧有效,只要是服务器端跳转,则设置的request属性可以一直传递下去。
  
使用客户端跳转传递的话,则属性是无法向下继续传递的。

Java中服务器端跳转:

  1. request.getRequestDispatcher(“success.jsp”).forward(request,response),只要执行到此语句之后立刻进行跳转,可以传递request属性;
  2. <jsp:forward>标签,这种跳转属于无条件跳转,它只能在站内跳转,而sendREdirect中则可以任意转,甚至可以输入baidu;注意:无条件跳转后,此跳转语句后边的代码都不会被执行(比如关闭数据库一类的)

客户端跳转:

  1. response.sendRedirect(“index.jsp”),所有页面执行完之后再进行跳转,不能传递request范围的属性,但是可以通过地址重写的方式向跳转页传递参数,因为该方法执行完之后就相当于一次http request的结束,这时服务器会向客户端发送302状态码和新的url,告诉客户端重新发送request请求到新的url,然后客户端照此执行,执行即新的请求响应流程开始,服务器再重新创建HttpServletRequest对象和HttpServletResponse对象,此时两个请求已经不在一个线程了
  2. response.setHeader(“refresh”,“3;URL=index.jsp”),3秒后跳转到其他页面;
  3. 超链接:<a href="http://www.baidu.com">百度</a>
  4. 表单提交:如果现在一个页面中使用了JDBC,则应该在forward跳转之前关闭数据库链接,而使用respose则可以在任意的位置处关闭

注意:

  1. 客户端跳转“/”代表服务器路径webapps,即服务器根路径;服务器端跳转“/”代表站点根路径,即应用程序根路径;
  2. 尽量使用response.sendRedirect(“index.jsp”)而不去使用forward,因为当服务器崩溃了,那么sendRedirect则就会起很大的好处了。

3、session属性范围

session设置的属性在一次会话范围内,不管何种跳转都能够使用,可是新开浏览器无法使用。当然,session只针对一个用户

4、application属性范围

因为application属性范围是在服务器上设置的一个属性,所以一旦设置之后任何用户都可以浏览到此属性

注意:如果在服务器上设置了过多的application属性,则会影响到服务器的性能。

5、使用场合

  1. request:如果客户向服务器发请求,产生的数据,用户看完就没用了,像这样的数据就存在request域,像新闻数据,属于用户看完就没用的。
  2. session:如果客户向服务器发请求,产生的数据,用户用完了等一会儿还有用,像这样的数据就存在session域中,像购物数据,用户需要看到自己购物信息,并且等一会儿,还要用这个购物数据结帐。
  3. application(servletContext):如果客户向服务器发请求,产生的数据,用户用完了,还要给其它用户用,像这样的数据就存在application(servletContext)域中,像聊天数据。

六、JSP标签

JSP标签也称之为Jsp Action(JSP动作)元素,它用于在Jsp页面中提供业务逻辑功能,避免在JSP页面中直接编写java代码,造成jsp页面难以维护。

jsp的常用标签有以下三个

  • <jsp:include>标签
  • <jsp:forward>标签
  • <jsp:param>标签

1、<jsp:include>标签

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

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

page属性用于指定被引入资源的相对路径,它也可以通过执行一个表达式来获得。

flush属性指定在插入其他资源的输出内容时,是否先将当前JSP页面的已输出的内容刷新到客户端。

2、<jsp:forward>标签

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

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

page属性用于指定请求转发到的资源的相对路径,它也可以通过执行一个表达式来获得。

3、<jsp:param>标签

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

<jsp:include page="relativeURL | <%=expression%>">
    <jsp:param name="parameterName" value="parameterValue|<%= expression %>" />
</jsp:include>
<jsp:forward page="relativeURL | <%=expression%>">
    <jsp:param name="parameterName" value="parameterValue|<%= expression %>" />
</jsp:include>

<jsp:param>标签的name属性用于指定参数名,value属性用于指定参数值。在<jsp:include>和<jsp:forward>标签中可以使用多个<jsp:param>标签来传递多个参数。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值