六、JSP中的9个内置对象

Servlet中,request、response两个对象是_jspService()方法的形参,当Tomcat调用该方法时会初始化这两个对象。而page、pageContext、application、config、session、out都是_jspService()方法的局部变量,由该方法完成初始化,只有当页面的page指令的isErrorPage属性为true时,才可以使用exception对象。
由于JSP内置对象都是在_jspService()方法中完成初始化的,因此只能在JSP脚本,JSP输出表达式中使用这些内置对象,千万不要在JSP声明中使用它们,否则,系统将提示找不到这些变量。

服务器对客服端请求的处理:

  • 启动单独的线程。
  • 使用I/O流读取用户请求的二进制流数据。
  • 从请求数据中解析参数。
  • 生成响应数据。
  • 使用IO流向客户端发送请求数据。

WEB提供的4个类似Map结构:

  • appliction:对整个Web应用有效,一旦JSP、Servlet将数据放入application中,该数据可以被整个引用中的JSP,Servlet访问。
  • session:仅对一次会话有效,一旦JSP、Servlet将数据放入session中,该数据可以被本次会话中的JSP,Servlet访问。
  • request:仅对本次请求有效,一旦JSP、Servlet将数据放入request中,该数据可以被该次请求中的JSP,Servlet访问。
  • page:仅对当前页面有效,一旦JSP、Servlet将数据放入page中,该数据只可以被当前页面的JSP脚本,声明部分访问。

JSP中的application、session、request和pageContext4个内置对象分别用于操作application、session、request和page范围内的数据。

6.1application对象

application的两个作用:

  • 在整个Web应用中的多个JSP、Servlet之间共享数据。
  • 访问Web应用的配置参数。
让多个JSP、Servlet共享数据
  • getAttribute(String attName)
  • setAttribute(String attName,String attValue)
  • getInitParameter(String paramName)
<body>
<!--JSP声明--->
<%!
int i;
%>
<!--将i值自加后放入applicatioin的变量内-->
<%
application.setAttribute("counter","String.valueOf(++i);")
%>
<!--输出值-->
<%=i%>
</body>
<body>
<!--直接输出application的值-->
<%=application.getAttribute("counter")%>
</body>

application不仅用于两个JSP页面间共享数据,还可以用于JSP和Servlet之间共享数据。

Servlet中访问appliction里的变量:

ServletContext sc=getServletConfig().getServletContext();
out.println(sc.getAttribute("counter"));

每个Web应用中只有一个ServletContext实例,在JSP中可以通过application内置对象访问该实例,而Servlet中则必须通过代码获取,由于application代表整个Web应用,所以通常只应该吧WEB应用的状态数据放入application里。

获得Web应用配置参数

application可用于获取Web应用的配置参数

<body>
<%
//从配置参数中获取驱动
String driver=application.getInitParameter("driver");
//从配置参数中获取数据库url
String url=application.getInitParameter("url");
//从配置参数中获取用户名
String user=application.getInitParameter("user");
//从配置参数中获取密码
String pass=application.getInitParameter("pass");
//注册驱动
Class.forName(driver);
//获取数据库连接
Connection conn=DriverManager.getConnection(url,user,pass);
//创建Statement对象
Statement stmt=conn.createStatement();
//执行查询
ResultSet rs=stmt.executeQuery("select * from news_inf");
%>
<table>
<%
//遍历结果集
while(rs.next())
{
%>
    <tr>
      <td><%=rs.getString(1)%></td> 
      <td><%=rs.getString(2)%></td> 
    </tr>
<%
}
%>
</table>    
</body>

application的getInitParameter(String paramName)来获取WEB应用的配置参数,这些配置参数应该在web.xml文件使用context-patam元素配置。

  • param-name:配置Web参数名。
  • param-value:配置Web参数值。
    web.xml
  <context-param>
   <context-name>driver</context-name>
   <context-value>com.mysql.jdbc.Driver</context-value>
</context-param>
<!--相应地配置所有的参数-->

6.2config对象

config对象代表当前JSP配置信息,一般JSP页面比较少用该对象。Servlet用处相对较多,因为Servlet需要在web.xml文件中进行配置,可以知道配置参数。
JSP页面中:

<body>
  <!--直接输出config的getServletName的值,输出jsp-->
  <%=config.getServletName()%>
</body>

config对象是ServletConfig的实例,该接口用于获取配置参数的方法是getInitParameter(String paramName)

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

JSP页面配置在WEB应用中:

<servlet>
  <!--指定Servlet的名字-->
  <servlet-name>config</servlet-name>
  <!--指定将哪个JSP页面配置成Servlet-->
  <jsp-file>/configTest2.jsp</jsp-file>
  <!--配置名为name的参数-->
  <init-param>
    <param-name>name</param-name>  
    <param-value>zhangsan</param-value>
  </init-param>
  <!--配置名为age的参数-->
  <init-param>
    <param-name>age</param-name>  
    <param-value>18</param-value>
  </init-param>
</servlet>
<servlet-mapping>
  <!--指定将config Servlet配置到/config路径-->
  <servlet-name>config</servlet-name>
  <url-pattern>/config</url-pattern>
</servlet-mapping>

如果希望JSP页面可以获取web.xml配置文件中的配置信息,则必须通过该JSP配置路径来访问该页面,因为只有这样访问JSP页面才会让配置参数起作用。

6.3exception对象

exception对象是Throwable的实例,代表JSP中产生的错误和异常,是JSP页面异常机制的一部分。-jspx_page_context对异常的处理非常简单:如果页面的page指令指定了errorPage属性,则请求forward到errorPage属性指定的页面,否则使用系统页面来输出异常信息。由于只有JSP脚本、输出表达式才会对应于_jspService()方法里的代码,所以两个部分的代码无需处理checked异常。但JSP的声明部分依然需要处理checked异常,JSP的异常处理机制对JSP声明不起作用。

page异常

<!--通过errorPage属性来指定异常处理页面-->
<%@ page contextType="text/html";charset="utf-8" language="java" errorPage="error.jsp"%>
......
<body>
<%
int a=6;
int c=a/0;
%>
</body>
......
<%@ page contextType="text/html";charset="utf-8" language="java" isErrorPage="true"%>
......
<body>
异常类型是:<%=exception.getClass()%></br>
异常信息是:<%=exception.getMessage()%></br>
</body>
......

JSP页面page指定的isErrorPage为true时,该页面就会提供application内置对象。

6.4out对象

out对象代表一个页面输出流,通常用于在页面上输出变量值和常量。

out.println("<table>");
out.println("<tr>");
out.println("<td>");
out.println("</td>");
out.println("</tr>");
out.println("</table>");

<%=...%>表达式的本质就是out.write(...);

6.5pageContext对象

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

pageContext是pageContext类的实例,它提供了如下两个方法来访问page、request、session、application范围的变量。

  • getAttribute(String name):取得page范围内的name属性。
  • getAttribute(String name,int scope):取得指定范围内的name属性,其中scope可以如下4个值。
    1.PageContext.PAGE_SCOPE
    2.PageContext.REQUEST_SCOPE
    3.PageContext.SESSION_SCOPE
    4.PageContext.APPLICATION_SCOPE

与PageContext也提供了两个对应的setAttribute()方法,用于将指定变量放入page、request、session、application范围内。

例:

<body>
<%
pageContext.setAttribute("name","hello");
out.println(pageContext.getAttribute("name"));
%>
</body>

pageContext还可用于获取其他内置对象:

  • ServletRequest getRequest():获取request对象。
  • ServletResponse getResponse():获取response对象。
  • ServletConfig getConfig():获取config对象。
  • ServletContext getServletContext():获取application对象。
  • ServletSession getSession():获取session对象。

6.6request对象

获取请求头/请求参数

每个request对象封装着一次用户请求,并且所有的请求参数都封装在request对象中,request是HttpServletRequest接口的实例。
获取请求参数的方法:

  • String getParameter(String paramName):获取paramName请求参数的值。
  • Map getParameterMap():获取所有参数名和参数值组成的Map对象。
  • Enumeration getParameterNames():获取所有参数名所组成的Enumeration对象。
  • String[] getParameterValues(String name):paramName请求参数的值,当请求参数有多个值时,返回多个值所组成的数组。

HttpServletRequest获取请求头的方法:

  • String getHeader(String name):获取指定请求头的值。
  • java.util.Enumeration<String> getHeaderNames():获取所有请求头的值。
  • java.util.Enumeration<String> getHeaders(String name):获取指定请求头的多个值。
  • int getIntHeader(String name):获取指定请求头的值,并将该值转为整数。

客户端发送请求参数两种情况:

  • GET方式的请求。
  • POST方式的请求。

form.jsp:

<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8" %>
<!DOCTYPE html>
<html>
<head>
     <title>手机参数的表单页</title>
</head>
<body>
   <form id="form1" method="post" action="request1.jsp">
   用户名:<br/>
   <input type="text" name="name" /><hr />
   性别:<br />
   男:<input type="radio" name="gender" value="男" />
   女:<input type="radio" name="gender" value="女" />
   喜欢的颜色:<br />
   红:<input type="checkbox" name="color" value="红" />
   绿:<input type="checkbox" name="color" value="绿" />
   蓝:<input type="checkbox" name="color" value="蓝" />
   <hr/>
   来自的国家:<br/>
   <select name="country">
      <option value="中国">中国</option>
      <option value="美国">美国</option>
      <option value="印度">印度</option>
   </select><hr/>
   <input type="submit" value="提交" />
   <input type="reset" value="重置" />
   </form>
</body>
</html>

表单域和请求参数的关系:

  • 每个有name属性的表单域对应一个请求参数。
  • 如果多个表单域有相同的name属性,则多个表单域只生成一个值,只是该参数有多个值。
  • 表单域的name属性指定参数名,value指定请求参数值。
  • 如果每个表单域设置了disabled="disabled"属性,则该表单域不再生成请求参数。

request1.jsp:

<%@ page language="java" import="java.util.*" contentType="text/html; charset=GBK" %>
<!DOCTYPE html>
<html>
<head>
     <title>获取请求头/请求参数</title>
</head>
<body>
<%
//获取所有请求头的名称
Enumeration<String> headerNames=request.getHeaderNames();
while(headerNames.hasMoreElements())
{
    String headerName=headerNames.nextElement();
    //获取每个请求
    out.println(headerName+"--->"+request.getHeader(headerName)+"<br/>");
}
out.println("<hr/>");
//设置编码方式,对于简体中文,使用GBK编码。
request.setCharacterEncoding("GBK");
//获取表单域的值
String name=request.getParameter("name");
String gender=request.getParameter("gender");
//如果每个请求参数有多个值,将使用该方法获取多个值。
String[] color=request.getParameterValues("color");
String national=request.getParameter("country");
%>
<!--输出表单域的值-->
你的名字:<%=name%><hr/>
您的性别:<%=gender%><hr/>
您喜欢的颜色:
<%
for(String c:color)
{
    out.println(c+" ");
}
%>
<hr/>
你来自的国家:<%=national%><hr/>
</body>
</html>

重编码:

//获取原始的请求参数值
String rawName= request.getParameter("name");
//将请求参数值使用"ISO-8859-1"字符串分解成字节数组
byte[] rawBytes=rawName.getBytes("ISO-8859-1");
//将字节数组重新解码成字符串
String name=new String("rawBytes","UTF-8");

操作request范围的属性

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

  • setAttribute(String attName,Object attValue):将attValue设置成request范围的属性。
  • Object getAttribute(String attName):获取request范围的属性。

当forward用户请求时,请求的参数和请求的属性都不会丢失。

执行forward或include

HttpServletRequest类提供了一个getRequestDispatcher(String path)方法,其中path就是forward或者include的目标路径,该方法返回RequestDispatcher:

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

将a.jsp页面include到本页面中:

getRequestDispatcher("/a.jsp").include(request,reponse);

将a.jsp页面forward到本页面中:

getRequestDispatcher("/a.jsp").forward(request,reponse);

6.7response对象

response响应生成非字符串响应

需要生成非字符响应的情况,应该使用response来响应客服端的请求,response是HttpServletResponse接口的实例,该接口提供了一个getOutputStream(),该方法返回响应输出字符流。

重定向

**response重定向与forward不同的是,重定向会丢失所有的请求参数和request范围的属性,因为重定向将生成第二次请求。
HttpServletResponse提供了sedRedirect(String path)方法,path指向重定向的资源文件。

<body>
<%
response.sedRedirect("redirect-result.jsp");
%>
</body>

增加Cookie

Cookie通常用于网站记录客户的某些信息,比如客户的用户名及客户的喜好等。session会随浏览器的关闭而失效,但Cookie会一直存放在客户端机器上,除非超出Cookie的生命期限。
增加Cookie也是使用response内置对象完成的

  • void addCookie(Cookie cookie):增加Cookie。

增加Cookie的步骤:

  • 创建Cookie实例,Cookie的构造器为Cookie(String name,String value)。
  • 设置Cookie的生命期限,即Cookie在多长时间内有效。
  • 向客户端写Cookie。
<body>
<%
Cookie c=new Cookie("username",name);
c.setMaxAge(24*3600);
response.addCookie(c);
%>
</body>

访问客户端Cookie使用request对象,request提供getCookies()方法。

<body>
<%
Cookie[] cookies=request.getCookies();
for(Cookie c:cookies)
{
    if(c.getName().equals("username"))
     {
        out.println(c.getValue());
     }
}
%>
</body>

使用Cookie对象时必须设置器生存周期,否则Cookie会随浏览器的关闭而关闭。
Cookie值不允许出现中文字符,如果需要中文内容的Cookie,需要借助于URLEncoder对中文字符串进行编码,然后使用ERLDecoder对其进行解码。

session对象

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容