• jsp机制基础


    JSP

     

    Servlet技术一样,JSP也是SUN公司定义的一种开发动态web资源的技术,属于JavaEE技术之一。JSP实际上就是Servlet,它们在一起又称JSP/Servlet规范。

    Servlet:写Java代码。在做HTML页面的输出时不方便(开发效率很低)

    JSP:HTML+Java

    1JSP的原理及生命周期

    当某个jsp页面第一次被请求时,会被Tomcat服务器的JSP引擎部分翻译成一个Servlet (☆),然后按照servlet的调用方式进行调用,过程如下:

     

    当一个jsp页面被翻译成Servlet后,后面的过程,包括生命周期都和Servlet是类似的。所以说JSP就是Servlet,理解了JSP页面中的各个组成部分是如何被翻译成Servlet的,就掌握了JSP。学习JSP的过程中,应时常翻阅JSP对应的Servlet源码。

    2demo1_jsp.java

    上一小节中的demo1.jsp在访问时会被翻译成demo1_jsp.java,该类称为jsp的实现类(关于Tomcat中该类怎么命名不多说)。

    demo1_jsp类继承自org.apache.jasper.runtime.HttpJspBase抽象类,该类除了继承HttpServlet类外,还实现了javax.servlet.jsp.HttpJspPage接口,在HttpJspPage接口中声明了一个_jspService()方法,它对应着jsp页面,绕晕了的看下图所示:

     

    demo1.jsp中的几乎各种组成部分都能在demo1_jsp.java_jspService()方法中找到(☆)。

    3JSP页面的组成部分

    一个JSP页面可能会包含如下几个部分:JSP模板元素、Java脚本、JSP指令、JSP标签等等,这些部分都会被翻译到生成的Servlet中。

    JSP模板元素即JSP页面中的HTML内容,翻译时直接放在out.write()方法中输出。

    4JSP中的JAVA脚本

    1JSP脚本片断:<% Java代码 %>

    ① JSP脚本片断中只能出现java代码,不能出现其它模板元素。JSP引擎在翻译JSP页面时,会将JSP脚本片断中的Java代码将被原封不动地放到Servlet_jspService()方法中。

    ② 在一个JSP页面中可以有多个脚本片断,在两个或多个脚本片断之间可以嵌入文本、HTML标记和其他JSP元素。

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

    <ul>

    <%

    for(int i = 0;i < 5; i ++){

    %>

    <li>第<%=i %></li>

    <%

    }

    %>

    </ul>

    2JSP脚本表达式:<%=Java变量或表达式 %>

    JSP脚本表达式用于将程序数据输出到客户端。JSP引擎在翻译脚本表达式时,会在相应位置用out.print(将表达式的值输给客户端(变量或表达式后面不能有分号!)。

    3JSP声明:<%! Java代码 %>

    ① JSP页面中编写的所有代码,默认会翻译到servlet_jspService() 方法中,JSP声明中的Java代码被翻译到_jspService方法的外面,所以JSP声明可用于定义JSP页面转换成的Servlet程序的成员变量和方法、静态代码块

    ② JSP中九大隐式对象的作用范围仅限于_jspService()方法中,所以JSP声明中不能使用这些隐式对象

    4JSP注释:<%-- 注释信息 --%>

    JSP引擎在将JSP页面翻译成Servlet程序时,忽略JSP页面中被注释的内容。

    正规开发的JSP中应尽量避免出现Java脚本(可用标签封装)。

    5JSP指令

    JSP指令是为JSP引擎而设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其余部分。在JSP 2.0规范中共定义了三大指令(pageincludetaglib)。

    基本语法格式:<%@ 指令 属性=”值” …… %>,如果一个指令有多个属性,这多个属性可以写在一个指令中,也可以分开写。

    1page指令:<%@ page …… %>,有以下常用属性:

    ① import告知JSP引擎,导入哪些包。JSP引擎会在生成的Servlet中默认导入javax.servlet.*javax.servlet.http.*javax.servlet.jsp.*。如:

    <%@ page import="java.util.*,java.sql.*" %> 等价于:

    <%@ page import="java.sql.*" %>   <%@ page import="java.util.*" %>

    ② session告知引擎是否在_jspService()代码中产生session对象,默认值true

    ③ errorPage告知引擎,如果当前页面出现了异常,应该转发到哪个页面上(“/”代表当前应用)。开发中一般会直接在web.xml中配置全局错误页面(两种写法):

    <error-page>

    <exception-type>java.lang.Exception</exception-type>

    <location>/common/error.jsp</location>

    </error-page>

    <error-page>

    <error-code>404</error-code>

    <location>/common/404.jsp</location>

    </error-page>

    ④ isErrorPage告知引擎是否在_jspService()代码中产生exception对象,默认为false。利用该对象可以捕获页面中的异常,打印异常的详细信息。

    ⑤ contentType:☆ 告知引擎响应正文的MIME类型,在Servlet中被翻译成response.setContentType(xxx)

    ⑥ pageEncoding:☆ 告知引擎,翻译JSP时(从磁盘上读JSP文件)所用的码表,同时还会设置响应正文的MIME类型。pageEncoding的默认值为“ISO-8859-1”。

    如:pageEncoding=”UTF-8”相当于告知了引擎用UTF-8jsp,并在servletresponse.setContentType(“text/html;charset=UTF-8”)

    ⑦ isELIgnored:告知引擎,是否忽略EL表达式。默认值是false,不忽略。

    2include指令:<%@ include file=”/demo2.jsp” %>file属性以“/”开头代表当前应用。

    3taglib<%@ taglib uri=”” prefix=”” %>导入外部标签库,uri表示外部标签库的uri地址,好比名称空间,prefix相当于一个别名。

    6JSP标签

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

    1)转发:

    <jsp:forward page=”/demo2.jsp”> 

    <jsp:param name=”from” value=”demo1” />

    </jsp:forward>

    2)包含:

    <jsp:include page=”/demo2.jsp” >

    <jsp:param name=”from” value=”demo1” />

    </jsp:include>

    注意:

    ① JSP转发和包含标签实际上是对RequestDispatcher的两个方法(forwardinclude)的改写,且都可以包含<jsp:param>子标签,<jsp:param>中的name-value会以参数的形式加在page后。

    ② 动态包含和静态包含:除了include指令为静态包含,其余的全是动态包含,它们的区别如下图:

     

    了解了上图后,对静态包含和动态包含的各种区别就很容易理解了,实际开发中,能用静态包含就不用动态包含!

    3JavaBean相关

    JSP中提供了三个关于JavaBean组件的内置标签,分别为:

    ① <jsp:useBean>标签

    语法:<jsp:useBean id="beanName" class="package.class" scope="xxx"/>

    属性:id属性用于指定JavaBean实例对象的引用名称和其存储在域范围中的名称,class属性用于指定JavaBean的完整类名,scope的取值为pagerequestsessionapplication四个中的一个,默认值为page属性。

    作用:在指定的域范围内查找指定的JavaBean对象:

    A. 如果存在则直接返回该JavaBean对象的引用。

    B. 如果不存在则实例化一个新的JavaBean对象并将它以指定的名称存储到指定的域范围中。

    ② <jsp:setProperty>标签:

    语法1<jsp:setProperty name="beanName" property=”propertyName” value=”xxx” />

    语法2<jsp:setProperty name=”beanName” property=”propertyName | *” param=”xxx” />

    属性:name指定JavaBean实例对象的引用名称,对应id属性;property 指定JavaBean的属性名,指定param用请求参数设置JavaBean的属性

    ③ <jsp:getProperty>标签:

    语法:<jsp:getProperty name="beanName" property="propertyName" />

    使用案例,注意事项都写在注释中了,直接看即可:

    <jsp:useBean id="p" class="org.flyne.domain.Person" scope="page" />

    <!-- 一定要注意value的写法:基本类型和字符串类型直接写,其他类型用表达式 -->

    <jsp:setProperty name="p" property="name" value="Flyne" />

    <jsp:setProperty name="p" property="age" value="24" />

    <jsp:setProperty name="p" property="regTime" value="<%=new Date() %>" />

    name: <jsp:getProperty name="p" property="name"/><br />

    age: <jsp:getProperty name="p" property="age"/><br />

    regTime: <jsp:getProperty name="p" property="regTime"/><br />

    另外还可以使用请求参数设置JavaBean的属性:

    <jsp:setProperty name="p" property="name" param="name"/>

    <!-- 当JavaBean的属性名同请求参数名一致时还可以使用通配符 -->

    <jsp:setProperty name="p" property="*" />

    7、九大隐含对象和四大域对象(☆)

    在_jspService方法的开始部分定义了9大对象(exception对象需自行开启,通过isErrorPage指定),在JSP页面中可以直接使用这9大对象。

    隐含对象名称

    类型

    备注

    request

    javax.servlet.http.HttpServletRequest

    response

    javax.servlet.http.HttpResponse

    session

    javax.servlet.http.HttpSession

    page指令有开关:session

    application

    javax.servlet.ServletContext

    config

    javax.servlet.ServletConfig

    page

    javax.servlet.http.HttpServlet

    当前jsp对应Servlet的实例引用

    exception

    java.lang.Throwable

    page指令有开关:isErrorPage

    out

    javax.servlet.jsp.JspWriter

    相当于带缓存功能的PrintWriter

    pageContext

    javax.servlet.jsp.PageContext

    很重要(☆)

    其中pageContextrequestsessionapplication被称为四大域对象,又称属性范围,在实际开发中被用于存放数据(核心是把握其生命周期):

    pageContext

    页面范围:存储的数据仅本页有效,开发中不用它来存储数据

    request

    请求范围:一次请求范围内均有效,经常用

    session

    会话范围:多次请求可共享数据,但不同的客户端不能共享,经常用

    application

    应用范围:开发中尽量少用,用时要做同步处理

    8PageContext抽象类

    1)利用PageContext可以获取其他8JSP隐含对象

    使用场景:试想有这样一个函数,需要同时用到上述9个隐含对象(有点极端),设置9个参数?错,只需传入pageContext对象,再利用pageContext对象的getRequest()getResponse()getSession()getServletContext()等方法获取其余8个对象。(自定义标签时会用到)

    2操作其他3个域对象中的属性:

    ① void setAttribute(String name, Object value, int scope)

       Object getAttribute(String name, int scope)

       void removeAttribute(String name, int scope)

    scope参数可取如下常量值:PAGE_SCOPE(页面范围)、REQUEST_SCOPE(请求范围)、SESSION_SCOPE(会话范围)、APPLICATION_SCOPE(应用范围)。

    ② Object findAttribute(String name) 依次在四个范围中查找指定名称的属性:pageContext --> request --> session --> application

    3提供转发和包含的简易方法(forwardinclude

    9、其他问题

    1JSP中的异常处理技巧

    ① 运行时异常:如1 / 0的运算,此时需查看JSP文件对应的的Servlet的源码

    ② 出现语法错误时,一般IDE会报错,在浏览器中也可以看到错误的详细信息,此时直接定位到JSP文件中查看就行。

    2)使用page指令解决JSP中文乱码(☆)

    出现中文乱码问题主要还是因为读和写所用的码表不一致造成的:

    JSP开发人员可以采用各种字符集编码来编写JSP源文件(如UTF-8GBK),JSP引擎将JSP源文件翻译成的Servlet源文件默认采用ISO8859-1编码,因此,JSP引擎将JSP源文件翻译成Servlet源文件时,需要进行字符编码转换,通过pageEncoding属性指定,两者需要保持一致。

    3JSP最佳实践

    由于ServletJSP各自的特点,在长期的软件实践中,人们逐渐把servlet作为web应用中的控制器组件来使用,而把JSP技术作为数据显示模板来使用。

    本文来源于:http://www.flyne.org/article/502

  • 相关阅读:
    CUDA 纹理内存
    CUDA三维数组
    cutil.h问题
    GPU和CPU耗时统计方法
    NVIDIA CUDA Library Documentation
    device not ready cuda
    送给女朋友的礼物
    手机屏幕录制软件分享
    统计函数运行时间-CPU端
    二十四孝,图文并茂,古今必读!
  • 原文地址:https://www.cnblogs.com/w-wfy/p/5294850.html
Copyright © 2020-2023  润新知