您的位置:首页 > Web前端 > JavaScript

JSP学习笔记(一)

2017-03-08 21:16 260 查看

一、前言

  JSP(Java Server Page)和Servlet是Java EE规范的两个基本成员,但是这两者本质是一样的,因为JSP最终必须编译成Servlet才能运行,JSP只是简化了Servlet,如果单纯用Servlet开发不信效率极为低下,而且页面的所有内容都与Java代码耦合在一起。如果用JSP开发,可以在标准的HTML页面中嵌入Java代码,其静态的部分无须Java程序控制,只有那些需要从数据库读取或需要动态生成的页面内容,才使用Java脚本控制。

  JSP脚本中可以防止任何可执行性语句,所以可以充分利用Java语言的功能,Java 脚本程序是通过<%和%>标记来嵌入到 HTML 中的。

二、基本语法

2.1 JSP注释

格式:<%-- 注释内容 --%>

注:与HTML的注释<-- 注释 -->不同的是,JSP注释不会被发送到客户端,通俗来说,就是如果通过浏览器看源代码是看不到JSP注释的。

注:我们同样可以在<%和%>标记中使用Java的注释,其实这也是Java的一部分而已。

2.2 JSP声明

格式:<%! 声明部分 %>

注:JSP声明部分定义的变量和方法可以使用private、public等访问控制符修饰,也可使用static修饰,但不能使用abstact修饰声明部分的方法,因为抽象方法将导致JSP对应Servlet变成抽象类,从而导致无法实例化。

  JSP页面会编译成一个Servlet类,每个Servlet在容器中只有一个实例,也就是多个客户端访问同一个JSP的变量是同一个。

2.3 输出JSP表达式

格式:<%= 表达式 %>

注:输出表达式语法后不能有分号。

2.4 JSP的3个编译指令

  JSP的编译指令是通知JSP引擎的消息,他不直接生成输出,编译指令都有默认值。

常见的编译指令有如下三个:

page:该指令是针对当前页面的指令
include:用于指定包含另一个页面
taglib:用于定义和访问自定义标签
语法格式:<%@ 编译指令名 属性名="属性值"... %>

2.4.1 page指令

  page指令通常位于JSP页面的顶端,一个JSP页面可以有多条page指令。page指令的语法如下:

<%@page
[language="Java"]
[extends="package.class"]
[import="package.class|package.*,..."]
[session="true|false"]
[buffer="none|8KB|size KB"]
[autoFlush="true|false"]
[isThreadSafe="true|false"]
[info=="text"]
[errorPage="relativeURL"]
[contentType="mimeType[;charset=characterSet]"|"text/html;charSet=ISO-8859-1]
[pageEncoding="ISO-8859-1"]
[isErrorPage="true|false"]
%>
下面依次介绍page指令的意义:

language:声明当前JSP页面使用的脚本语言的种类,当前也只有Java一种,所以当前来说没啥意义,可以省略。
extends:指定JSP页面编译所产生的Java类所继承的父类,或所实现的接口。
import:用来导入包。下面几个包是默认自动导入的,不需要显式导入。默认导入的包有:java.lang.*、javax.servlet.*、javax.servlet.jsp.*、javax.servlet.http.*。如果不导入包,则必须使用全限定类名—即必须带包名。
session:设定这个JSP页面是否需要HTTP Session。
buffer:指定输出缓冲区的大小。输出缓冲区的JSP内部对象:out用于缓存JSP页面对客户浏览器的输出,默认值为8KB,可以设置为none,或其它值。
autoFlush:当输出缓冲区即将溢出时,是否需要强制输出缓冲区的内容。设置为true时为正常输出;如果设置为false,则会在buffer溢出时产生一个异常。
info:设置该JSP程序的信息,也可以看做其声明,可以通过Servlet.getServletInfo()方法获取该值。如果在JSP页面中,可直接调用getServletInfo()方法获取其值,因为JSP页面的实质就是Servlet。
errorPage:指定错误处理页面。如果本页面产生了异常或者错误,而该JSP页面没有对应的处理代码,则会自动调用该属性所指定的JSP页面。
isErrorPage:设置本JSP页面是否为错误处理程序。如果该页面本身已经是错误处理页面,则通常无须指定errorPage属性。
pageEncoding:指定生成网页的编码字符集。
contentType:用来指定MIME类型以及JSP页面所采用的编码方式。默认值为“text/html,ISO8859-1”。

isThreadSafe:设置该JSP页面是否能够同时处理超过一个以上的页面请求。默认值为true,也就是可以。

isELIgnored:指定EL(表达式语言)是否被忽略。如果为true,则容器忽略"${}"表达式的计算,默认为false。

pageEncoding和contentType两种属性的区别:

pageEncoding是jsp文件本身的编码
contentType的charset是指服务器发送给客户端时的内容编码

2.4.2 include指令

  使用include指令,可以将一个外部文件嵌入到当前JSP文件中,同时解析这个页面中的JSP语句(如果有的话)。这是个静态的include语句,他会把目标页面的其他编译指令也包含进来,但动态include则不会。
  include 指令的重要性:因为页面代码冗余问题一直存在。现在可以将一些共性的内容(例如标题、导航栏和页脚消息等)写入到一个单独文件中,然后别人的 JSP 页面可以通过 include 指令进行引用。这样可以大大降低页面代码的冗余问题,并且修改也更加方便,这些共性内容只需要修改单独文件即可。

  include既可以包含静态的文本,也可以包含动态的JSP页面。静态的include的编译指令会将被包含的页面加入本页面,融合成一个页面,因此被包含页面甚至不需要是一个完整的页面

include编译指令的语法:<%@include file="relativeURLSpec" %>
注意:如果被嵌入的文件经常需要改变,建议使用<jsp:include>操作指令,因为他是动态的include语句。

注意:如果include进来的内容出现了两个不同的 contentType 属性设置,会报异常。

2.4.3 taglib指令

  Taglib 指令使用来引用一个标签库或者自定义标签。通过 taglib 指令来告诉容器此 JSP 页面将使用哪些标签库,并可以给引用的标签库指定一个前缀。在 JSP 文件中使用到这个标签库的时候,就可以使用指定的前缀来标识标签库。

  使用自定义标签的 taglib 基本语法如下:

<%@ taglib uri=”tagLibraryURL” prefix=”tagPrefix” %>
  以上设置的 taglib 指令,声明了此 JSP 文件使用了一个标签,同时指定了标签的前缀。如下代码使用 taglib 指令引用了标准标签库( JSTL)中的数据库标签:

<%@ taglib uri=”http://java.sun.com/jsp/jstl/sql” prefix=”sql” %>
<sql:query var=”books”>
Select * from books
</sql:query>


2.5 JSP的7个动作指令

  动作指令与编译指令不同,编译指令是通知Servlet引擎的处理消息,而动作指令只是运行时的动作。编译指令在将JSP编译成Servlet时起作用;而处理指令通常可替换成JSP脚本,它只是JSP脚本的标准化写法。

JSP动作指令主要有如下7个:

jsp:forward:执行页面专项,将请求的处理转发到下一个页面。
jsp:param:用于传递参数,必须与其他支持参数的标签一起使用。
jsp:include:用于动态引入一个JSP页面。
jsp:plugin:用于下载JavaBean或Applet到客户端执行。
jsp:useBean:创建一个JavaBean的实例。
jsp:serProperty:设置JavaBean实例的属性值。
jsp:getPropert:输出JavaBean实例的属性值。

2.5.1 forward指令

  forward指令用于将页面响应转发到另外的页面。既可以转发到静态的HTML页面,也可以转发到动态的JSP页面,或者转发到容器中的Servlet。

JSP的forward动作指令的格式如下:

对于JSP1.0,使用如下语法:

<jsp:forward page="{relativeURL|<%=expression%>"/>
对于JSP1.1以上规范,可使用如下语法:

<jsp:forward page="{relativeURL|<%=expression%>"/>
{<jsp:param=.../>}
</jsp:forward>
  第二种语法用于在转发时增加额外的请求参数。增加的请求参数的值可以通过HttpServletRequest类的getParameter()方法获取。

注意:执行forward指令转发请求时,客户端的请求参数不会丢失,并且地址栏没有改变。从表面上看,给我们的感觉是将用户请求“转发”到了一个新页面,但事实上并没有重新向新页面发送请求,它只是完全采用了新页面来对用户生成响应——请求依然是一次请求,所以请求参数,请求属性都不会丢失。

2.5.2 include指令

  include指令是一个动态include指令,也用于包含某个页面,他不会导入被include页面的编译指令,仅仅将被导入页面的body内容插入本页面。

include动作指令指令的格式如下:

<jsp:include page="{relativeUrl|<%=expression%>}" flush="true"/>
或者

<jsp:include page="{relativeUrl|<%=expression%>}" flush="true"/>
<jsp:param name="parameterName" value="patameterValue"/>
</jsp:include>
  flush属性用于指定输出缓存是否转移到被导入文件中。如果指定为TRUE,则包含在被导入文件中;如果指定为false,则包含在原文件中。对于JSP1.1以前版本,只能设置为false。

  对于第二种语法格式,则可在被导入页面中加入额外的请求参数。

静态导入与动态导入的区别:

静态导入是将被导入页面的代码完全融入,两个页面融合成一个整体Servlet;而动态导入则在Servlet中使用include方法来引入被导入页面的内容。
静态导入时被导入页面的编译指令会起作用;而动态导入时被导入页面的编译指令则失去作用,只是插入被导入页面的body内容。
动态包含还可以增加额外的参数。
forward动作指令与include动作指令的区别:
  执行forward时,被forward的页面将完全代替原有页面;而执行include时被include的页面只是插入原有界面。简而言之,forward拿目标页面代替原有页面,而include则拿目标页面插入原有页面。

2.5.3 useBean、setProperty、getProperty指令

  这三个指令都是JavaBean相关的指令,其中useBean指令用于在JSP页面中初始化一个Java实例,其他两个是设置与读取JavaBean实例的属性。

useBean的语法格式如下:

<jsp:useBean id="name" class="className" scope="page|request|session|application"/>
重点在scope属性,用于指定JavaBean实例的作用范围,该范围有以下4个值:

page:该JavaBean实例仅在该页面有效。
request:该JavaBean实例在本次请求有效。
session:该JavaBean实例在本次session内有效。
application:该JavaBean实例在本应用内一直有效。

setProperty指令的语法格式如下:

<jsp:setProperty name="BeanName" proterty="propertyName" value="value"/>


getProperty指令的语法格式如下:

<jsp:getProperty name="BeanName" proterty="propertyName"/>
  当然,我们也可以直接把JavaBean直接写入到JSP页面中,然而使用useBean标签时,可以直接指定scope属性,我们如果直接贴代码我们需要用代码指定范围,如下:

//JavaBean实例的引用为p
//将p放入page的生存范围中
pageContext.setAttribute("p",p);
//将p放入request的生存范围中
request.setAttribute("p",p);
//将p放入session的生存范围中
session.setAttribute("p",p);
//将p放入application的生存范围中
application.setAttribute("p",p);

2.5.4 plugin指令

  plugin指令用于下载服务器端的JavaBean或Applet到客户端执行。由于程序在客户端执行,因此客户端必须安装虚拟机。(这个指令不常用)

2.5.5 param指令

  param指令用于设置参数值,这个指令本身不能单独使用,param指令可以与下面三个指令结合使用:

jsp:include
jsp:forward
jsp:plugin

2.6 JSP脚本中的9个内置对象

  JSP脚本包含9个内置对象,这9个内置对象都是Servlet API接口的实例,只是JSP规范对它们进行了默认初始化。也就是说,它们已经是对象了,可以直接使用。这9个对象为:

application:javax.servlet.ServletContext的实例,该实例代表JSP所属的Web应用本身,可用于JSP页面,或者在Servlet之间交换信息。
config:javax.servlet.ServletConfig的实例,该实例代表该JSP的配置信息。
exception:java.lang.Throwable的实例,该实例代表其他页面中的异常和错误。只有当页面是错误处理页面,即编译指令page的isErrorPage属性为true时,该对象才可以使用。
out:javax.servlet.jsp.JspWriter的实例,该实例代表JSP页面的输出流用于输出内容。
page:代表该页面本身,通常没有太大用处。也就是Servlet中的this,其类型就是生成的Servlet类,能用page的地方就可用this。
pageContext:javax.servlet.jsp.PageContext的实例,该对象代表该JSP页面上下文,使用该对象可以访问页面中的共享数据。
request:javax.servlet.http.HttpServletRequest的实例,该对象封装了一次请求,客户端的请求参数都被封装在该对象里。
response:javax.servlet.http.HttpServletResponse的实例,代表服务器对应客户端的响应。通常很少使用该对象直接响应,而是使用out对象,除非需要生成非字符响应。而response对象常用于重定向。
session:javax.servlet.http.HttpSession的实例,该对象代表一次会话。当客户端浏览器与站点建立连接时,绘画开始;当客户端关闭浏览器时,会话结束。
  Web应用中JSP页面Servlet等程序都由Web服务器来调用,JSP、Servlet之间通常不会相互调用,那么如何交换数据?所有的Web服务器都会提供4个类似Map的结构,分别是application、session、request、page,并允许JSP、Servlet将数据放入这4个类似于Map的结构中,并允许从这4个中读取数据。

这4个Map结构的区别是范围不同:

application:对于整个Web应用有效,一旦JSP、Servlet将数据放入application中,该数据将可以被该应用下其他所有的JSP、Servlet访问。
session:仅对一次会话有效。
request:仅对本次请求有效。
page:仅对当前页面有效。

2.6.1 application对象

application对象作用:

在整个Web应用的多个JSP、Servlet之间共享数据。
访问Web应用的配置参数。

<1> 让多个JSP、Servlet共享数据

  application通过setAttribut(String attrName,Object value)设置一个属性,通过getAttribute(String attrName)访问该属性。

  JSP中的application是javax.servlet.ServletContext的一个实例,而在Servlet中并没有application内置对象,因此我们需要获取应用的ServletContext实例,每个Web应用只有一个ServletContext实例,在JSP中可以通过application内置对象访问该实例,而Servlet中则必须通过代码获取,代码如下(关键代码):

ServletContext sc=getServletConfig().getServletContext();
注意:虽然使用application(即ServletContext实例)可以方便多个JSP、Servlet共享数据,但不要仅为了JSP、Servlet共享数据就将数据放入application中!由于application代表整个Web应用,所以通常只应该吧Web应用的状态数据放入application里。

<2>获得Web应用配置参数

  application的另一个重要用处:用于获取Web应用的配置参数。这些配置参数都在web.xml中,通过application.getInitParameter("参数名");获得。

web.xml文件中使用context-param元素配置,其包含了两个子元素:

param-name:配置Web参数名
param-value:配置Web参数值

注:web.xml文件中使用context-param元素配置的参数对整个Web应用有效,所以也被称为Web应用的配置参数。与整个Web应用有关的数据,应该通过application对象来操作。

2.6.2 config对象

  config对象代表当前JSP配置信息,但JSP页面通常无需配置,因此也就不存在配置信息,所以JSP页面比较少用该对象。但在Servlet中则用处相当大,因为Servlet需要在web.xml文件中进行配置,可以指定配置参数。

示例:

编写JSP文件如下:

<body>
<!-- 输出该JSP名为name的配置参数 -->
name配置参数的值:<%=config.getInitParameter("name")%><br/>
<!-- 输出该JSP名为age的配置参数 -->
age配置参数的值:<%=config.getInitParameter("age")%>
</body>
配置web.xml如下:

<servlet>
<!-- 指定Servlet名字 -->
<servlet-name>config</servlet-name>
<!-- 指定将哪个JSP页面配置成Servlet -->
<jsp-file>/configTest.jsp</jsp-file>
<!-- 配置名为name的参数,值为crazyit.org -->
<init-param>
<param-name>name</param-name>
<param-value>crazyit.org</param-value>
</init-param>
<!-- 配置名为age的参数,值为30 -->
<init-param>
<param-name>age</param-name>
<param-value>30</param-value>
</init-param>
</servlet>
<servlet-mapping>
<!-- 指定将config Servlet配置到/config URL-->
<servlet-name>config</servlet-name>
<url-pattern>/config</url-pattern>
</servlet-mapping>
注:配置JSP也是在web.xml文件中进行的,JSP被当成Servlet配置,为Servlet配置参数使用init-param元素,该元素可以接受param-name和param-value两个子元素,分别制定参数名和参数值。web.xml中配置了两个参数name和age,并且将configTest.jsp页面配置成名为config的Servlet,并将Servlet映射到/config处,这就允许通过/config来访问该页面。如果希望获得配置信息则必须通过该JSP配置的路径来访问该页面,因为只有这样访问JSP页面才会让配置参数起作用。

2.6.3 exception对象

  exception对象是Throwable的实例,代表JSP脚本中产生的错误喝一场,是JSP页面异常机制的一部分。

注:exception独享仅在异常处理页面中才有效,即<@page isErrorPage="true">才可以。

2.6.4 out对象

  out对象代表一个页面输出流,通常用于在页面上输出变量值即常量。一般在使用输出表达式的地方,都可以使用out对象来达到同样效果。

注:<%= ... %>本质上就是out.write(...);

2.6.5 pageContext对象

  这个对象代表页面上下文,该对象主要用于访问JSP之间的共享数据。使用pageContext可以访问page、request、session、application范围的变量。

访问变量如下:

getAttribute(String name):取得page范围内的name属性。
getAttribute(String name,int scope):取得指定范围内的name属性,其中scope可以是如下4个值。
pageContext.PAGE_SCOPE:对应于page范围
pageContext.REQUEST_SCOPE:对应于request范围

pageContext.SESSION_SCOPE:对应于session范围

pageContext.APPLICATION_SCOPE:对应于application范围

示例:

<body>
<%
// 使用pageContext设置属性,该属性默认在page范围内
pageContext.setAttribute("page","hello");
// 使用request设置属性,该属性默认在request范围内
request.setAttribute("request","hello");
// 使用pageContext将属性设置在request范围中
pageContext.setAttribute("request2","hello"
, pageContext.REQUEST_SCOPE);
// 使用session将属性设置在session范围中
session.setAttribute("session","hello");
// 使用pageContext将属性设置在session范围中
pageContext.setAttribute("session2","hello"
, pageContext.SESSION_SCOPE);
// 使用application将属性设置在application范围中
application.setAttribute("app","hello");
// 使用pageContext将属性设置在application范围中
pageContext.setAttribute("app2","hello"
, pageContext.APPLICATION_SCOPE);
//下面获取各属性所在的范围:
out.println("page变量所在范围:" +
pageContext.getAttributesScope("page") + "<br/>");
out.println("request变量所在范围:" +
pageContext.getAttributesScope("request") + "<br/>");
out.println("request2变量所在范围:"+
pageContext.getAttributesScope("request2") + "<br/>");
out.println("session变量所在范围:" +
pageContext.getAttributesScope("session") + "<br/>");
out.println("session2变量所在范围:" +
pageContext.getAttributesScope("session2") + "<br/>");
out.println("app变量所在范围:" +
pageContext.getAttributesScope("app") + "<br/>");
out.println("app2变量所在范围:" +
pageContext.getAttributesScope("app2") + "<br/>");
%>
</body>
输出结果:



注:pageContext获取各属性所在的范围,其中这些范围获取的都是整型变量,这些整型变量分别对应如下4个生存范围如下:

1:对应page生存范围
2:对应request生存范围

3:对应session生存范围

4:对应application生存范围

不仅如此,pageContext还可用于获取其他内置对象,pageContext对象包含如下方法:

ServletRequest getRequest():获取request对象
ServletResponse getResponse():获取response对象
ServletConfig getServletConfig():获取config对象
ServletContext getServletContext():获取application对象
HttpSession getSession():获取session对此昂
  因此一旦在JSP、Servlet编程中获取了pageContext对象,就可以通过它提供的上面方法来获取其他内置对象。

2.6.6 request对象

  request对象是JSP中重要的对象,每个request对象封装了一次用户请求,并且所有的请求参数都被封装在request对象中,因此request对象是获取请求参数的重要途径。除此之外,request可代表本次请求范围,所以还可用于操作request范围的属性。

<1> 获取请求头/请求参数
  Web应用是请求/响应架构的应用,浏览器发送请求时通常总会附带一些请求头,还可能包含一些请求参数发送给服务器,服务器端负责解析请求头/请求参数的就是JSP/Servlet,而JSP和Servlet取得请求参数的途径就是request。request是HttpServletRequest接口的实例。
HttpServletRequest提供了如下几个方法获取请求参数:

String getParameter(String paramName):获取paramName请求参数的值
Map getParameterMap():获取所有请求参数名和采纳数值所组成的Map对象
Enumeration getParameterNames():获取所有请求参数名所组成的Enumeration对象
String[] getParameterValue(String name):paramName请求参数的值,当该请求参数有多个值时,该方法将返回多个值所组成的数组。
HttpServletRequest提供了如下方法来访问请求头:

String getHeader(String name):根据指定请求头的值
java.util.Enumeration<String> getHeaderNames():获取所有请求头的名称
java.util.Enumeration<String> getHeaders(String name):获取指定请求头的多个值
int getIntHeader(String name):获取指定请求头的值,并将该值转为整数值
注:请求头和请求参数都是由用户发送到服务器的数据,区别在于请求头通常由浏览器自动添加,因此一次请求总是包含若干请求头;而请求参数则通常需要开发人员控制添加。

  并不是每个表单域都会生成请求参数,而是有name属性的表单域才生成请求参数。关于表单域和请求参数的关系遵循如下4点:

每个有name属性的表单域对应一个请求参数
如果有多个表单域有相同的name属性,则多个表单域只生成一个请求参数,只是该参数有多个值
表单域name属性指定请求参数名,value指定请求参数值
如果某个表单域设置了disabled=“disabled”属性,则该表单域不再生成请求参数
  request中包含一个方法serCharacterEncoding("GBK"),作用是设置request编码所用的字符集,然而如果你的请求参数中包含非西欧字符,则还会发生乱码,也就是说包含中文还是乱码。

获取GET请求里的中文字符:
<%
// 获取请求里包含的查询字符串
String rawQueryStr = request.getQueryString();
out.println("原始查询字符串为:" + rawQueryStr + "<hr/>");
// 使用URLDecoder解码字符串
String queryStr = java.net.URLDecoder.decode(rawQueryStr, "GBK");
out.println("解码后的查询字符串为:" + queryStr + "<hr/>");
// 以&符号分解查询字符串
String[] paramPairs = queryStr.split("&");
for (String paramPair : paramPairs) {
out.println("每个请求参数名、值对为:" + paramPair + "<br/>");
// 以=来分解请求参数名和值
String[] nameValue = paramPair.split("=");
out.println(nameValue[0] + "参数的值是:" + nameValue[1] + "<hr/>");
}
%>
  上面的代码是获取GET请求里中文参数值的关键代码,为了获取GET请求里的中文参数值,必须借助于java.net.URLDecoder类。(注:URLDecoder与URLEncoder)

注意:我们应该用那种字符集来解码,这取决于浏览器。对于简体中文的环境来说,一般要么是UTF-8字符集,要么是GBK字符集。
  如果读者不想如上面那么做,我们还可以在获取请求参数值之后对请求参数值重新编码。也就是先将其转换成字节数组,再将字节数组重新解码成字符串。例如,可通过如下代码来取得name请求参数的参数值,如下:
//获取原始的请求参数值
String rawName=request.getParameter("name");
//将请求参数值使用ISO-8859-1字符串分解成字节数组
byte[] rawBytes=rawName.getBytes("ISO-8859-1");
//将字节数组重新解码成字符串
String name=new String(rawBytes,"UTF-8");
<2> 操作request范围的属性

  HttpServletRequest还包含如下两个方法,用于设置和获取request范围的属性。

setAttribute(String attName,Object attVale):将attValue设置成request范围的属性
Object getAttribute(String attName):获取request范围的属性
注:当forward用户请求时,请求的参数和请求属性都不会丢失。

<3> 执行forward或include
  request还有一个功能就是执行forward和include,也就是代替JSP所提供的的forward和include动作指令。
  HttpServletRequest类提供了一个getRequestDispatcher(String path)方法,其中path就是希望forward或者include的目标路径,该方法返回RequestDispatch,该对象提供了如下两个方法:

forward(ServletRequest request,ServletResponse response):执行forward
include(ServletRequest request,ServletResponse response):执行include

如下代码行可以将a.jsp页面include到本页面中:
getRequestDispatcher("/a.jsp").include(request,response);
如下代码行则可以将请求forward到a.jsp页面:
getRequestDispatcher("/a.jsp").forward(request,response);
注意:使用request的getRequestDispatcher(String path)方法时,该path字符串必须以斜线开头。

2.6.7 response对象

<1> response响应生成非字符相应

  对于生成非字符响应的情况,就应该使用response来响应客户端请求。下面的jsp页面将在客户端产生一张图片。response是HttpServletResponse接口的实例,该接口提供了一个getOutputStream()方法,该方法返回响应输出字符流。
<%-- 通过contentType属性指定响应数据是图片 --%>
<%@ page contentType="image/png" language="java"%>
<%@ page import="java.awt.image.*,javax.imageio.*,java.io.*,java.awt.*"%>
<%
// 创建BufferedImage对象
BufferedImage image = new BufferedImage(340 ,
160, BufferedImage.TYPE_INT_RGB);
// 以Image对象获取Graphics对象
Graphics g = image.getGraphics();
// 使用Graphics画图,所画的图像将会出现在image对象中
g.fillRect(0,0,400,400);
// 设置颜色:红
g.setColor(new Color(255,0,0));
// 画出一段弧
g.fillArc(20, 20, 100,100, 30, 120);
// 设置颜色:绿
g.setColor(new Color(0 , 255, 0));
// 画出一段弧
g.fillArc(20, 20, 100,100, 150, 120);
// 设置颜色:蓝
g.setColor(new Color(0 , 0, 255));
// 画出一段弧
g.fillArc(20, 20, 100,100, 270, 120);
// 设置颜色:黑
g.setColor(new Color(0,0,0));
g.setFont(new Font("Arial Black", Font.PLAIN, 16));
// 画出三个字符串
g.drawString("red:climb" , 200 , 60);
g.drawString("green:swim" , 200 , 100);
g.drawString("blue:jump" , 200 , 140);
g.dispose();
// 将图像输出到页面的响应
ImageIO.write(image , "png" , response.getOutputStream());
%>
  最上面的<%@ page contentType="image/png" %>设置了服务器响应数据就是image/png,这表明服务器响应是一张PNG图片。接着创建了一个BufferedImage(代表图像),并获取该BufferedImage的Graphics对象(代表笔画),然后通过Graphics向BufferedImage中绘制图形,最后一行代码将直接将BufferedImage作为响应发送给客户端。
  我们也可以使用img标签来显示这个图片页面,代码如下:
<img src="img.jsp>
  使用这种临时生成图片的方式就可以非常容易地实现网页上的图形验证码功能。不仅如此,使用response生成非字符响应还可以直接生成PDF文件、Excel文件,这些文件可直接作为报表使用。
<2> 重定向

  与forward不同的是,重定向会丢失所有的请求参数和request范围的属性,因为重定向将生成第二次请求,与前一次请求不在同一个request范围内
,所以发送一次请求的请求参数和request范围的属性全部丢失。

  HttpServletResponse提供了一个sendRedirect(String path)方法,该方法用于重定向到path资源,即重新向path资源发送请求。
注意:执行重定向动作时,地址栏的URL会变成重定向的目标URL。换句话说,重定向会丢失所有的请求参数,使用重定向的效果,与在地址栏里重新输入新地址再按回车键的效果完全一样,即发送第二次请求。
<3> 增加Cookie
  Cookie通常用于网站记录客户的信息,一旦用户下次登录,网站可以获取到客户的相关信息。Cookie与session的不同之处在于:session会随浏览器的关闭而失效,但Cookie会一直存放在客户端机器上,除非超出Cookie的生命期限。
  由于安全性原因,使用Cookie客户端浏览器必须支持Cookie才行。客户端浏览器完全可以设置禁用Cookie。
  增加Cookie也是使用response内置对象完成的,response对象提供了如下方法:void addCookie(Cookie cookie) —>增加Cookie
  正如在上面的方法中见到的,在增加Cookie之前,必须先创建Cookie对象。增加Cookie请按如下步骤进行:

创建Cookie实例,Cookie的构造器为Cookie(String name,String value)
设置Cookie的生命周期,即该Cookie在多长时间内有效
向客户端写Cookie
写入Cookie示例:
<%
// 获取请求参数
String name = request.getParameter("name");
// 以获取到的请求参数为值,创建一个Cookie对象
Cookie c = new Cookie("username" , name);
// 设置Cookie对象的生存期限为24小时
c.setMaxAge(24 * 3600);
// 向客户端增加Cookie对象
response.addCookie(c);
%>
读取Cookie:
<%
// 获取本站在客户端上保留的所有Cookie
Cookie[] cookies = request.getCookies();
// 遍历客户端上的每个Cookie
for (Cookie c : cookies)
{
// 如果Cookie的名为username,表明该Cookie是需要访问的Cookie
if(c.getName().equals("username"))
{
out.println(c.getValue());
}
}
%>
注意:使用Cookie对象必须设置其生存期限,否则Cookie将会随浏览器的关闭而自动小时。
注:默认情况下,Cookie值不允许出现出现中文字符,如果需要值为中文内容的Cookie怎么办呢?同样可以借助于java.net.URLEncoder先对中文字符串进行编码,将编码后的结果设为Cookie值。当程序要读取Cookie时,则应该先读取,然后使用java.net.URLDecoder对其进行解码。
示例:
<%
// 以编码后的字符串为值,创建一个Cookie对象
Cookie c = new Cookie("cnName"
, java.net.URLEncoder.encode("孙悟空" , "gbk"));
// 设置Cookie对象的生存期限
c.setMaxAge(24 * 3600);
// 向客户端增加Cookie对象
response.addCookie(c);

// 获取本站在客户端上保留的所有Cookie
Cookie[] cookies = request.getCookies();
// 遍历客户端上的每个Cookie
for (Cookie cookie : cookies)
{
// 如果Cookie的名为username,表明该Cookie是需要访问的Cookie
if(cookie.getName().equals("cnName"))
{
//使用java.util.URLDecoder对Cookie值进行解码
out.println(java.net.URLDecoder
.decode(cookie.getValue()));
}
}
%>

2.6.8 session对象

  session对象也是一个非常常用的独享,这个对象代表一次用户会话。一次用户会话的含义是:从客户端浏览器连接服务器开始,到客户端浏览器u服务器断开为止,这个过程就是一次会话。
  session通常用于跟踪用户的会话信息,如判断用户是否登录系统,或者在购物车应用中,用于分钟用户购买的商品等。
  session范围内的属性可以再多个页面的跳转之间共享。一旦关闭浏览器,即session结束,session范围内的属性将全部丢失。
  session对象是HttpSession的实例,HttpSession有如下两个常用的方法:

setAttribute(String attName,Object attBalue):设置session范围内attName属性的值为attValue
getAttribute(String attName):返回session范围内attName属性的值

注意:考虑session本身的目的,通常指应该吧与用户会话状态相关的信息放入session范围内。不要仅仅为了两个页面之间交换信息,就将该信息放入session范围内。如果仅仅为了两个页面交换信息,可以将该信息放入request范围内,然后forward请求即可。

注意:session机制通常用于保存客户端的状态信息,这些信息需要保存到Web服务器的硬盘上,所以要求session里的属性值必须是可序列化的,否则将会引发不可序列化的异常。
注:session的属性值可以是任何可序列化的Java对象。

参考资料:

《轻量级JavaEE 企业应用实现 第四版》
JSP页面中的pageEncoding和contentType两种属性

最后修改时间:2017年3月29日16:25:07

********************************************************************************结束语********************************************************************************************

  我在写这篇博客的时候也是一名初学者,有任何疑问或问题请留言,或发邮件也可以,邮箱为:fanxiaobin.fxb@qq.com,我会尽早的进行更正及更改。

在我写过的博客中有两篇博客是对资源的整理,可能对大家都有帮助,大家有兴趣的话可以看看!!
下载资料整理——目录:http://blog.csdn.net/fanxiaobin577328725/article/details/51894331

  这篇博客里面是我关于我见到的感觉不错的好资源的整理,里面包含了书籍及源代码以及个人搜索的一些资源,如果有兴趣的可以看看,我会一直对其进行更新和添加。
优秀的文章&优秀的学习网站之收集手册:http://blog.csdn.net/fanxiaobin577328725/article/details/52753638

  这篇博客里面是我对于我读过的,并且感觉有意义的文章的收集整理,纯粹的个人爱好,大家感觉有兴趣的可以阅读一下,我也会时常的对其进行更新。

********************************************************************************感谢********************************************************************************************
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: