疏影横斜

疏影横斜

有趣有盼,无灾无难.
github
telegram
misskey

JSP 基础

JSP 简介#

JSP (Java Server Pages), 其根本是一个简化的 Servlet 设计,它实现了在 Java 中使用 HTML 标签。JSP 是 一种动态网页技术标准,也是 JavaEE 的标准。JSP 和 Servlet 一样,是在服务器端执行的。JSP 是在 Servlet 技术发展之后为了让开发者写 html 标签更方便而发展起来的技术,JSP 实际上就是 Servlet。

但是,人们通常把 Servlet 作为 Web 应用中的控制组件来使用,只负责响应请求产生数据,并把数据通 过转发技术带给 JSP,而把 JSP 技术作为数据显示模板来使用。这样使程序结构更清晰,可读性和可维护性更高。

常用动态网站开发技术#

JSP:Java 平台,安全性高,适合开发大型的,企业级的,分布式的 Web 应用程序。如 Hadoop,电子银行,12306 等

ASP.NET:.Net 平台,简单易学。但是安全性以及跨平台型差。

PHP:简单,高效,成本低开发周期端,特别适合中小型企业的 Web 应用开发。(LAMP: Linux+Apache+MySQL+PHP)

JSP 页面元素构成#

JSP 指令#

JSP 指令 (directive) 是为 JSP 引擎二设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理 JSP 页面中的其余部分。在 JSP2.0 规范中共定义了三个指令,基本语法格式为,<%@ 指令 属性名 ="值" %>,如果一个指令有多个属性,这多个属性可以写在一个指令中,也可以分开写。

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

    <%@ page language="java" contentType="text/html,ISO-8859-1" 
    import="java.util.*,java.sql.*,java.io.*" session="true|flase" 
    buffer="none|8kb|sizekb" autoFlush="true|false" info="一段字符串内容" 
    errorPage="relative_url" isErrorpage="true|false"%>
    
  • language 指定 JSP 页面使用的脚本语言,默认值为 java
  • contentType 用来指定 JSP 页面的文件类型和所采用的编码方式, 默认值
    为 “text/html,ISO-8859-1”
  • import 通过该属性来引用脚本语言中使用到的类文件,导入多个类或包用逗号分隔。 JSP 引擎自动导入 java.lang.;java.servlet.;javax.servlet.jsp.;javax.servlet.http.
  • pageEncoding 指定 JSP 页面的编码方式, 默认值为 “ISO-8859-1”
  • session 用来说明是否创建 session 对象,默认为 true
  • buffer 用来指定 out 对象是否创建 buffer 缓冲区,并指定缓冲区大小。默认为
    8kb, none 表示不创建缓冲区。
  • autoFlush 缓冲区是否自动刷新,默认为 true,如果为 false,缓冲区满后不手动刷
    新会包异常。
  • info 定义一个字符串常量,使用 getServletInfo 方法可以打印。
  • errorPage 指定异常处理页。也可以在 web.xml 中使用元素为整个 WEB 应用程序设置处理页面,其中的子元素指定异常类的完全限定名,元素指定以 "/" 开头的错误处理页面的路径。如果设置了某个 JSP 页面的 errorPage 属性,那么在 web.xml 文件中这是的错误处理将不对该页面起作用。
  1. include 指令:用于引入其他 JSP 页面,如果使用 include 指令引入了其他 JSP 页面,那么 JSP 引擎将 把这两个 JSP 翻译成一个 Servlet,所以 include 指令引入通常也成为静态引入。

    <%@ include file=“被包含组件的绝对URL或相对URL"%>
    

被引入的文件必须遵循 JSP 语法。被引入的文件可以是任意扩展名,即使其扩展名是 html,JSP 引擎 也会按照处理 jsp 页面的方式处理它里面的内容,为了见名知意,JSP 规范建议使用.jspf (JSP fragments) 作为静态引入文件的扩展名。由于使用 include 指明将会涉及到 2 个 JSP 页面,并会把 JSO 翻译成一个 Servlet,所以这两个 JSP 页面的指令不能冲突 (pageEncoding 和导包除外)。

  • taglib 指令:使用标签库定义显得自定义标签,在 JSP 页面中启用定制行为。

表达式#

在 JSP 页面中执行的表达式 <%=表达式%>,注意表达式不以分号结束。例如,当前时间: <%= new java.util.Date() %>

脚本片段#

在 JSP 页面中插入多行 java 代码 <% Java代码 %>,JSP 引擎在翻译 JSP 页面时,会将 JSP 脚本片段中的 Java 代码原封不动的放到 Servlet 的_jspServlet 方法中,所以,<% %>中的 Java 代码必须严格遵循 java 语法。

声明#

在 JSP 页面中定义变量或者方法 <%! Java代码 %>,声明中的 Java 代码被翻译到_jspService 方法的 外面,属于类,所以可以声明成员变量并初始化,也可以声明方法或定义方法,同时还可以声明静态代 码块。 JSP 隐式对象的作用范围仅限于 Servlet 的_jspService 方法,所以在 JSP 声明中不能使用这些隐式对象

<%!
static {
  System.out.println("loading Servlet!");
}
private int globalVar = 0;
public void jspInit() {
  System.out.println("initializing jsp!");
}
%>
<%!
public void jspDestroy() {
  System.out.println("destroying jsp!");
}
%>

注释 (3 种方式)#

  1. HTML 注释
  2. JSP 注释: <%--JSP注释,客户端不可见--%>
  3. JSP 脚本注释: 即 java 注释 //单行 ,/*多行 */

静态内容#

<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%>
<html>
<head>
  <title>index.jsp page</title>
</head>
<body>
  <h1>大家好</h1><hr>
  <!-- 我是HTML注释,在客户端可见 -->
  <%-- 我是JSP注释,在客户端不可见 --%>
    <%!
  String s = "张三";
//声明了一个字符串变量
int add(int x,int y) {
  //声明了一个返回整型的函数,实现两个整数的求和。
  return x+y;
}
%>
  <%
    //单行注释
/*多行注释*/
out.println("大家好");
%>
  <br>
  你好,<%=s %><br>
  x+y=<%=add(10,5) %><br>
</body>
</html>

JSP 运行原理及生命周期#

用户第一次请求 Tomcat 会将 JSP 文件编程成一个 Servlet 的 java 文件,并将 java 文件编译成 class 文件,加载到内存,生成文件在 Tomcat 的 work 目录的对应项目文件夹。如果 JSP 页面发生了修改,JSP 引擎会对其进行重新编译并加载到内存,以方便用户请求。注意,用户第一次请求一个 JSP 页面时,首先被执行的方法是构造方法。

_jspService () 方法被调用来处理客户端的请求。对每一个请求,JSP 引擎创建一个线程来处理该请求。如果有多个客户端同时请求该 JSP 文件,则 JSP 引擎会创建多个线程。每个客户端请求对应一个线程。以多线程方式执行可以大大降低对系统资源的需求,提高系统的并发量及响应时间。但也要主要多线程的编程带来的额同步问题,由于该 Servlet 始终驻于内存,所以响应是非常快的。

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

JSP 9 个内置对象#

内置对象简介#

JSP 内置对象是 Web 容器创建的一组对象,不使用 new 关键字就可以使用的内置对象。

四种作用域范围#

  1. application_SCOPE: 作用于整个 Web 应用,多个用户之间共享。
  2. session_SCOPE: 作用于整个 Web 应用,单个用户之间共享。
  3. request_SCOPE: 作用于请求,转发间请求共享。
  4. page_SCOPE: 作用于当前页面,当前页面可见。

out 对象#

缓冲区: Buffer,即内存中的一块区域用来保存临时数据。

out 对象: 是 JspWriter 类的实例,是向客户端发送文本常用的对象,是通过调用 pageContext 对象的 getOut 方法返回的,其作用和用法与 ServletResponse.getWriter 方法返回的 PrintWriter 对象非常相 似。JSP 页面中的 out 隐式对象的类型为 JspWriter,JspWriter 相当于一种带缓存功能的 PrintWriter,设 置 JSP 页面的 page 指令的 buffer 属性可以调整它的缓存大小,甚至关闭它的缓存。当缓冲区满足如下条 件是才会写入 Servlet 引擎提供的缓冲区:设置 page 指令的 buffer 属性关闭了 out 对象的缓存功能;out 对象的缓冲区已满。整个 JSP 页面结束。

<%
  out.println("aaa");
  response.getWriter().write("bbb");
%>
"bbb会比aaa先输出"

常用方法:

  • void println (); 向客户端打印字符串
  • void clear (); 清除缓冲区的内容,如果在 flush 之后调用会抛出异常。
  • void clearBuffer (); 清除缓冲区的内容,如果在 flush 之后调用不会抛出 异常
  • void flush (); 将缓冲区内容输出到客户端
  • int getBufferSize (); 返回缓冲区以字节数的大小,如不设缓冲区则为 0
  • int getRemaining (); 返回缓冲区还剩余多少可用
  • boolean isAutoFlush (); 返回缓冲区满是,是自动清空还是抛出异常
  • void close (); 关闭输出流

request/response 对象#

表单的两种提交方式

  1. Get: 以明文的方式通过 URL 提交数据,数据在 URL 中可以看到。提交的数据最多不超过 2KB。安全 性较低,但效率比 post 方式高。适合提交数据量不大,安全性高的数据。比如:搜索、查询等功能。

  2. Post:将用户提交的信息封装在 HTML header 内。适合提交数据量大,安全性高的用户信息。比 如:注册、修改、上传等功能。

request 对象#

客户端的请求信息被封装在 request 对象中,通过它才能了解到客户端的需求,然后做出响应。它是 HttpServletRequest 类的实例。request 对象具有请求域,即完成客户端的请求之前,该对象一直有效。

request 对象常用方法

  1. String getParameter (); 返回指定参数的参数值
  2. String [] getParameterValues (); 返回指定参数的所有值
  3. void setAttribute (); 存储此请求中的属性
  4. object getAttribute (); 返回指定属性的属性值
  5. String getContentType (); 得到请求体的 MIME 类型
  6. String getProtocol (); 返回请求用的协议及版本号
  7. String getServerName (); 返回接受请求的服务器主机名
  8. int getServerPort (); 返回服务器接受此请求的端口号
  9. String getCharacterEncoding (); 返回字符编码方式
  10. void setContentEncoding (); 设置请求的字符编码方式
  11. int getContentLength (); 返回请求体的长度(以字节数)
  12. String getRemoteAddr (); 返回发送此请求的客户端 IP 地址
  13. String getRealPath (String path); 返回一个虚拟路径的真实路径或相对路径的绝对路径
  14. StringgetContextPath (); 返回上下文路径,即项目的根目录
    中文乱码问题: request.setCharacterEncoding("UTF-8");
    URL 中中文乱码问题: Tomcat的/conf/server.xml 的添加属性

response 对象#

response 对象包含了响应客户请求的有关信息,但在 JSP 中很少直接用到它。它是 HttpServletResponse 类的实例。response 对象具有页面作用域,及访问一个页面时,该页面内的 response 对象只能对这次访问有效,其他的 response 对象对当前页面无效。

response 对象常用方法

  1. String getCharacterEncoding (); 返回响应用的是何种字符编码
  2. void setContentType (); 设置响应的 MIME 类型,一般为 "text/html, charset=UTF-8"
  3. PrintWriter getWriter (); 返回可以向客户端输出字符的一个对象 (“注意比较:PrintWriter 与内置 out 对象的区别,PrintWriter 对象的其输出总是提前于内置 out 对象,或者在 out 中手动 flush”)
  4. sendRedirect (loaction); 重新定向客户端的请求

请求重定向: 是客户端行为,response。sendRedirect (), 从本质上将等同于两次请求,前一次的 请求对象不会保存,地址栏的 URL 地址会改变。

请求转发: 是服务器行为,request.getRequestDispatcher ().forward (); 是一次请求,转发后请求 对象会保存,地址栏的 URL 地址不会改变。

session 对象#

session 表示客户端与服务器的一次会话,Web 中的 session 指的是用户在浏览某个网站时,从进入网 站到浏览器关闭所经过的这段时间,也就是用户浏览这个网站所花费的时间。

在服务器的内存中,为不同的用户保存着不同的 session。

session 对象是一个 JSP 内置的对象。

session 对象在第一个 JSP 页面被装载是自动创建,完成会话期管理。

从一个客户打开浏览器并连接到服务器开始,到客户关闭浏览器离开这个服务器结束,被称为一个会 话。

当一个客户访问一个服务器时,肯能会在服务器的几个页面之间切换,服务器应当通过某种办法知道 这是一个客户,就需要 session 对象。

session 对象是 HttpSession 类的实例。

session 的常用方法

  1. long getCreationTime (); 返回 session 创建时间
  2. String getId (); 返回 session 创建时 JSP 引擎为它设的唯一 ID 号
  3. Object setAttribute (); 使用指定名称将对象绑定到此会话
  4. Object getAttribute (); 返回与此会话中的指定名称绑定在一起的对象,没有返回 null
  5. String [] getValueNames (); 返回一个包含此 session 中所有可用属性的数组
  6. int getMaxInactiveInterval (); 返回两次强求间隔多长时间此 session 被取消(单位秒)
  7. void setMaxInactiveInterval (); 设置 session 存活时间。

session 的生命周期

  1. 创建:当客户端第一次访问某个 jsp 或者 Servlet 时候,服务器会为当前会话创建一个 SessionId,每次客户端向服务端发送请求时,都会将此 SessionId 携带过去,服务端会对此 SessionId 进行校验。
  2. 活动: 某次会话当中通过超链接打开的新页面属于同一次会话。只要当前会话页面没有全部关闭, 重新打开新的浏览器窗口访问同一项目资源时属于同一次会话。除非本次会话的所有页面都关闭后,在 重新访问某个 jsp 或者 Servlet 将会创建新的会话 (但此时原有会话还存在,这个就的 SessionId 仍然存在于 服务端,只不过再也没有客户端会携带它然后教育服务端校验,直到该会话超时。)。
  3. 销毁:有三种销毁方式
  • 调用了 session.invalidate () 方法
  • Session 过期(超时)可以在 web.xml 中配置 Session 超时时间 1 单位是分钟
  • 服务器重新启动

application 对象#

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

application 的常用方法

  1. void setAttribute (); 使用指定名称将对象绑定到此会话
  2. Object getAttribute (); 返回与此会话中的指定名称绑定在一起的对象,如果没有,返回 null
  3. Enumeration getAttributeNames (); 返回所有可用属性名的枚举
  4. String getServerInfo (); 返回 JSP (Servlet) 引擎名及版本号

page 对象#

page 对象就是指向当前 jsp 页面本身,有点像类中的 this 指针,它是 java.lang.Object 类的实例。常
用方法就是 Object 类的成员方法。

pageContext 对象#

pageContext 对象是 JSP 技术中最重要的一个对象,它代表 JSP 页面的运行环境,这个对象不仅封装了对其他 8 个隐式对象的引用,其自身还是一个域对象,可以用来保存数据。并且,这个对象还封装了 web 开发中经常涉及到的一些常用操作,例如 include,forward 其他资源、检索其他域对象中的属性等。

pageContext 对象提供了对 jsp 页面内所有的对象及名字空间的访问。该对象可以访问到本页所在的 Session,也可以取本页所在的 application 中的属性值。该对象相当也页面中所有功能的集大成者。该对象的本类名也叫 pageContext。

pageContext 的常用方法

  1. JspWriter getOut (); 返回当前客户端响应被使用的 out 对象
  2. HttpSession getSession (); 返回当前页中的 Session 对象
  3. Object getPage (); 返回当前页的 page 对象
  4. ServletRequest getRequest (); 返回当前页的 Request 对象
  5. ServletResponse getResponse (); 返回当前页的 Response 对象
  6. void setAttribute (); 设置属性及属性值
  7. Object getAttribute (); 在指定范围内取属性的值
  8. int getAttributeScope (); 返回某属性的作用范围
  9. void forward (); 跳转到另一个页面,地址栏不变
  10. void include (); 包含另一个页面,
  11. PageContext.APPLICATION_SCOPE 代表各个域的常量
  12. PageContext.SESSION_SCOPE
  13. PageContext.REQUEST_SCOPE
  14. PageContext.PAGE_SCOPE
  15. findAttribute (); 查找各个域中的属性

Config 对象#

Config 对象是在一个 Servlet 初始化时,JSP 引擎向它传递信息用的,此信息包括 Servlet 初始化时所要用到的参数(通过属性名和属性值构成)以及服务器的有关信息(通过传递一个 ServletContext 对象)

Config 的常用方法

  1. ServletContext getServletContext (); 返回含有服务器信息的 ServletContext 对象
  2. String getInitParameter (); 返回初始化参数的值
  3. Enumeration getInitparameterNames (); 返回 Servlet 初始化所需所有参数的枚举

Exception 对象#

Exception 对象是一个异常对象,当一个页面在运行过程中发生了异常,就产生这个对象。如果一个 jsp 页面要应用此对象,就必须报 isErrorPage 设为 true,否则无法编译。它实际上是 java.lang.Throwable 的对象。页面要想在有异常时得到处理,就要指定异常处理页面 <% page errorPage=“exception.jsp”%>

exception 的常用方法

  1. String getMessage (); 返回描述异常的消息
  2. String toString (); 返回关于异常的简短描述消息
  3. void printStackTrace (); 显示异常及其栈轨迹
  4. ThrowableFillInStackTrace (); 重写异常的执行栈轨迹

JSP 动作标签#

  1. JSP 动作元素 (action elements): 动作元素为请求处理阶段提供信息。动作元素遵循 XML 元素的语法,有一个包含元素名的开始标签,可以有属性、可选的内容、与开始标签匹配的结束标签。
    JSP 标签也称之为 JSP Action(JSP 动作)元素,它用于在 JSP 页面中提供业务逻辑功能,避免在 JSP 页面中直接编写 java 代码,造成 jsp 页面难以维护。

  2. JSP 动作元素包含五大类

    • 与存储 JavaBean 有关的:jsp, jsp, jsp.
    • JSP1.2 规范就有的 6 个基本动作元素:jsp, jsp, jsp, jsp, jsp, jsp.
    • JSP2.0 新增加,主要与 JSP Document 有关的 6 个动作元素:jsp, jsp, jsp, jsp, jsp, jsp.
    • JSP2.0 新增加,主要永磊动态生成 XML 元素标签的值,包括 3 个动作:jsp, jsp, jsp.
    • JSP2.0 新增加,只要用在 Tag File 中:jsp, jsp.
  3. JSP 常用标签

    • include: 该标签用于把另外一个资源的输出内容插入进当前 JSP 页面的输出内容中,这种在 JSP 页面执行时的引入方式称之为动态引入。<jsp:include page="relativeURL | <%=expression%>" flush="true|false" />。flush 属性指定在插入其他资源的输出内容时,是否先将当前 JSP 页面的已输出的内容刷新到客户端。

    • jspinclude指令比较: jsp标签是动态引入, jsp标签涉及到的 2 个 JSP 页面会被翻译成 2 个 servlet,这 2 个 servlet 的内容在执行时进行合并。而 include 指令是静态引入,涉及到的 2 个 JSP 页面会被翻译成一个 servlet,其内容是在源文件级别进行合并。不管是 jsp标签,还是 include 指令,它们都会把两个 JSP 页面内容合并输出,所以这两个页面不要出现重复的 HTML 全局架构标签,否则输出给客户端的内容将会是一个格式混乱的 HTML 文档。但 include 指令要比 jsp标签效率高些。可以从下面的表格中更直观的看到两者的区别.

      includejsp
      语法格式<%@ include file=“…” %>< jsp page=“…” >
      发生作用的时间页面转换期间请求期间
      包含的内容文件的实际内容页面的输出
      转换成的 servlet主页面和包含页面转换成一个 Servlet主页面和包含页面转换为独立的 Servlet
      编译时间较慢 - 资源必须被解析较快
      执行时间稍快较慢 - 每次资源必须被解析
    • jsp: 该标签用于把请求转发给另外一个资源。<jsp page=“relativeURL | <%=expression%>” />。等同于 request。getRequestDispatcher (“/url”).forward (request,response)。即执行服务器内部跳转操作。

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

<jsp:include page="relativeURL | <%=expression%>">
<jsp:param name="parameterName" value="parameterValue|<%= expression %>"/>
</jsp:include>
可以使用多个<jsp:param>标签来传递多个参数。
  1. 映射 JSP

映射 JSP 就是将一个 JSP 映射成其他任意形式的 URL,在 web.xml 文件配置

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

JavaBeans#

  1. Javabean 简介

    Javabeans 就是符合某种特定规范的 Java 类。使用 Javabeans 的好处是解决代码重复编写,减少代码冗余,功能区分明确,提高了代码的可维护性。

  2. Javabean 设计原则

    必须是共有类;
    必须包含一个无参的共有构造方法;
    所有属性必须私有;
    使用 getter 和 setter 访问器对属性访问封装。

    public class Book {
     //一个符合要求的Javabean类
     private String bookName;
     private String author;
     private double price;
     public Book() {
     }
     public String getBookName() {
       return bookName;
     }
     public void setBookName(String bookName) {
       this.bookName = bookName;
     }
     public String getAuthor() {
       return author;
     }
     public void setAuthor(String author) {
       this.author = author;
     }
     public double getPrice() {
       return price;
     }
     public void setPrice(double price) {
       this.price = price;
     }
    }
    
  3. JSP 中如何使用 Javabean

    第一种方式:像使用普通 java 类一样,创建 javabean 实例。
    第二种方式:在 JSP 页面中通常使用 jsp 动作标签使用 javabean。

  4. scope

    作用:在 jsp 页面中实例化或者在指定范围内使用 javabean

    <jsp:useBean id="标识符" class="java类名" scope="作用范围"/> 
    <!-- scope默认为page。 -->
    
  5. property

作用:给已经实例化的 Javabean 对象的属性赋值,一共有四种形式:

<jsp:setProterty name="Javabean实例名" property="*"/>(跟表单关联)
<jsp:setProterty name="Javabean实例名" property="Javabean属性名"/>(跟表单关联)
<jsp:setProterty name="Javabean实例名" property="Javabean属性名" value="BeanValue"/>(手工设置)
<jsp:setProterty name="Javabean实例名" property="propertyName" param="request对象中的参数名"/>(跟request参数关联)通过url地址传递的参数
  1. name

作用:获取指定 Javabean 对象的属性值。

<jsp:getProperty name="Javabean实例名" property="属性名"/>
  1. Javabean 的四个作用域范围

    使用 useBeans 的 scope 属性可以用来指定 javabean 的作用范围。
    page:仅在当前页面有效
    request:可以通过 request.getAttribute 方法取得 JavaBean 对象
    session:可以通过 session.getAttribute 方法取得 JavaBean 对象
    application:可以通过 application.getAttribute 方法取得 JavaBean 对象

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.