JavaEE学习之路—–JSP(四)

1. JSP脚本中的9个内置对象

JPS脚本中包含9个内置对像,这9个内置对象都是Servlet API接口的实例。它们已经是对象,可以直接使用。
它们分别是:

  • application:javax.servlet.ServletContext的实例,该实例代表JSP所属的Web应用本身,可用于JSP、Servlet之间的数据共享。
  • config:javax.servlet.ServletConfig的实例,该实例代表JSP的配置信息。
  • exception:java.lang.Throwable的实例,该对象代表其他页面的异常或错误,只有该页面是错误处理页面时,该对象才能使用。
  • out:javax.servlet.jsp.JspWriter的实例,该实例代表JSP页面是输出流,用于输出内容,形成HTML页面。
  • page:代表页面本身,通常没有什么用。
  • pageContent:javax.servlet.jsp.PageContent的实例,该对象代表JSP页面的上下文,使用该实例能访问该界面的共享数据。
  • request:javax.servlet.http.HttpServletRequest的实例,该对象封装了一次请求,客户端访问服务器的参数被封装在这个对象里面,要获取客户端请求必须使用该对象。
  • response:javax.servlet.http.HttpServletResponse的实例,该对象代表服务器对客户端的响应,一般除非是非字符响应,否则不会使用该对象直接返回,而是使用out对象返回。
  • session:javax.servlet.http.HttpSession的实例,该对象代表一次会话。当客户端与服务器建立连接时,会话开始;当客户端关闭浏览器时会话结束。

request、response是由Tomcat初始化并传入_jspService()函数中的,而page、pageContent、application、config、session、out都是_jspService()的局部变量。
他们的作用域分别是:

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

1.1 application对象

application通常有两个作用:

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

application使用setAttribute(String attrName,Object value)方法将一个值设置成application的attrName属性,该属性的值对整个Web应用有效,该应用下的所有JSP、Servlet都能访问该属性,访问该属性的方法是getAttribute(String attrName)。
下面的代码在application中设置了count属性,并且没调用一次这个页面,count值加一。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<%! int i = 0; %>
<body>
<%application.setAttribute("count", i++); %>
</body>
</html>

同一个web应用中有下面这个JSP,该JSP访问application的count属性并输出,通过实验知道,每次调用上面的JSP页面再调用该界面时,count值都加一。由此可见它们访问的是同一个属性,因此,application中的属性值是可以在JSP、Servlet之间共享的。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%=application.getAttribute("count") %>
</body>
</html>

注意
虽然使用application(ServletContext实例)可以方便多个JSP、Servlet共享数据,但不要仅为了JSP、Servlet共享数据就将数据放入到application中。由于application代表整个Web应用,所以通常只把Web应用的状态数据放入到application中。

1.1.2 获得Web应用配置参数

application还可以获取web.xml文件中的Web配置信息。例如web.xml文件中有如下属性:

<context-param>
    <param-name>driver</param-name>
    <param-value>com.mysql.jdbc.Driver</param-value>
</context-param>
<context-param>
    <param-name>url</param-name>
    <param-value>jdbc:mysql://localhost:3306/javaee</param-value>
</context-param>
<context-param>
    <param-name>user</param-name>
    <param-value>root</param-value>
</context-param>
<context-param>
    <param-name>pass</param-name>
    <param-value>1234</param-value>
</context-param>

通过application可以轻松地取出这些属性:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<% 

String driver = application.getInitParameter("driver");
String url = application.getInitParameter("url");
String user = application.getInitParameter("user");
String pass = application.getInitParameter("pass");
out.append("driver:").append(driver).append("url:").append(url).append("user:").append(user).append("pass:").append(pass);

%>
</body>
</html>

可见在JSP页面中将web.xml文件中是属性获取出来并显示在客户端浏览器。

1.2 config对象

config对象代表当前JSP页面的配置信息,但常常JSP页面无须配置,因此也就不存在配置信息,所以config对象在JSP中不常用。但是在Servlet中却很常用,因为Servlet需要配置。
如下代码输出了Servlet的名字,所有的JSP页面都有一个相同的Servlet名:jsp;

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%=config.getServletName() %>
</body>
</html>

因此,这段代码输出的结果是:jsp。
config对象通过getInitParameter(String paramName)方法获取配置参数。
JSP也是在web.xml文件中配置的,JSP被当作Servlet配置。

<servlet>
    <servlet-name>myconfig</servlet-name>
    <jsp-file>config.jsp</jsp-file>
    <init-param>
        <param-name>name</param-name>
        <param-value>value</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>myconfig</servlet-name>
    <url-pattern>/myconfig</url-pattern>
</servlet-mapping>

上面的配置信息,将config.jsp的JSP页面配置为myconfig的Servlet,设置初始参数:参数名:name,值:value。并将该JSP映射到/myconfig,客户端可以使用这个映射直接访问config.jsp页面。

1.3 exception对象

exception对象是Throwable的实例,代表JSP脚本中产生的错误和异常,是JSP异常机制的一部分。
JSP脚本中无须处理异常,所以的异常都交给错误处理也面处理。因为所以的JSP脚本都被try…catch起来了,异常处理界面处理catch中捕捉到的异常。如果该页面指定的errorPage,则将请求forward到errorPage指定的页面,如果没有指定,则由系统页面来输出异常信息。
注意
JPS异常处理机制只对_jspService()方法中的内容有效,因此JSP异常处理机制对JSP声明不起作用。

<%@ page language="java" contentType="text/html; charset=UTF-8" isErrorPage="true"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%=exception.getClass() %>
<%=exception.getMessage() %>
</body>
</html>

如上面的代码所示,当page指令中的isErrorPage设置为true的时候,JSP会创建exception内置对象,该内置对象中包含了其他页面传递过来的异常信息。

1.4 out对象

out代表一个页面的输出流,通常用来输出用于显示的信息,如变量或常量值等。一般使用输出表达式的地方都能使用out。

<%@ page language="java" contentType="text/html; charset=UTF-8" isErrorPage="true"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%=exception.getClass() %>
<%out.print(exception.getClass()); %>
<%=exception.getMessage() %>
<%out.print(exception.getMessage()); %>
</body>
</html>

这是一个用out对象代替输出表达式的例子。

1.5 pageContext对象

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

  • gerAttribute(String name);取得page范围内的name属性。
  • getAttribute(String name,int scope);取得指定范围内的name属性,scope可以取如下值:
    • PageContext.PAGE_SCOPE:对应于page范围;
    • PageContext.REQUEST_SCOPE:对应于request范围;
    • PageContext.SESSION_SCOPE:对应于session范围;
    • PageContext.APPLICATION_SCOPE:对应于application范围。
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
pageContext.setAttribute("apge1", "页面", PageContext.PAGE_SCOPE);
pageContext.setAttribute("request1", "请求", PageContext.REQUEST_SCOPE);
pageContext.setAttribute("session1","会话", PageContext.SESSION_SCOPE);
pageContext.setAttribute("appclication", "应用", PageContext.APPLICATION_SCOPE);

out.println(pageContext.getAttributesScope("apge1"));
out.println(pageContext.getAttributesScope("request1"));
out.println(pageContext.getAttributesScope("session1"));
out.println(pageContext.getAttributesScope("appclication"));
%>
</body>
</html>

页面输出:1 2 3 4。
上面的代码分别将属性设置到page、request、session、application中,并且将这几个属性的作用范围输出到界面:
1:page作用域。
2:request作用域。
3:session作用域。
4:application作用域。
pageContext对象还能获取其他内置对象:

  • getRequest():获取request对象;
  • getResonse():获取response对象;
  • getServletConfig():获取config对象;
  • getServletContext():获取application对象;
  • getSession():获取session对象。

1.6 request对象

每个request对象封装一个用户请求,并且所有的请求参数都被封装到这个request请求中。另外,request可代表本次请求范围,所以可以用于操作request范围的属性。

1.6.1 获取请求头/请求参数

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

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

HttpServletRequest提供了如下几个方法来访问请求头。
- getHeader(String name):根据名字获取请求头大的值。
- getHeaderNames():获取所有请求头的名字。
- getHeaders(String name):获取指定请求头的多个值。
- getIntHeader(String name):获取指定请求头的值,并将该值转换成整型。

一般请求参数由开发人员添加,请求头由浏览器自动添加。
客户端发送请求参数通分两种情况:

  • GET方式的请求:GET方式的请求会将参数的名和值转成字符串,并且附加在UTL后,因此可以在浏览器地址栏看到请求名和值。并且GET请求一般传送的数据较小,一般不大于2Kb.
  • POST方式的请求:这种方式通常使用提交表单的方式发送,且设置form元素的method属性为post。POST方式传送的数据量大,POST发送的请求参数以及对应的值放在HTML HEADER中传输,用户不能在地址栏看到参数。
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

<form id="form1" method="post" action="request1.jsp">
用户名:<br/>
<input type="text" name="userName"/><br/>
性别:<br/>
男:<input type="radio" name="gender" value="男"/>
女:<input type="radio" name="gender" value="女"/><br/>
喜欢的颜色:<br/>
红:<input type="checkbox" name="color" value="红"/>
绿:<input type="checkbox" name="color" value="绿"/>
蓝:<input type="checkbox" name="color" value="蓝"/><br/>
来自的国家:<br/>
<select name="country">
    <option value="中国">中国</option>
    <option value="美国">美国</option>
    <option value="俄罗斯">俄罗斯</option>
</select>
<input type="submit" value="提交"/>
<input type="reset" value="重置"/>
</form>

</body>
</html>

这个页面只包含了一个表单,设置action为request1.jsp ,这表明该表单在提交请求时,将请求发送到request1.jsp页面,method属性设置为post表明使用POST请求。

request1.jsp:

<%@page import="org.apache.jasper.tagplugins.jstl.core.ForEach"%>
<%@page import="java.util.Enumeration"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

<%
    Enumeration<String> headerNames = request.getHeaderNames();
while(headerNames.hasMoreElements()) {
    String headerName = headerNames.nextElement();
    out.append(headerName).append("<br/>");
}
out.flush();
// 设置解码方式
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("userName");
String gender = request.getParameter("gender");
String [] colors = request.getParameterValues("color");
String natinal = request.getParameter("country");

%>

<hr>
名字:<%=name %><hr/>
性别:<%=gender %><hr/>
喜欢的颜色:
<%
 for(String color:colors) {
     out.append(color).append(" ");
 }
out.flush();
%>

来自的国家:
<%=natinal %>


</body>
</html>

该代码演示了如何获取请求参数和请求头,当请求参数中有非西欧字符时,要设置request的字符集setCharacterEncoding。

1.6.2 操作request范围的属性

HttpServlet的两个设置request范围属性的方法:

  • setAtrribution(String attrName,String attrValue):将attrValue设置成request范围的属性.
  • Object getAttribute(String attrName):获取request范围的属性。
    当forward用户请求时,请求参数和请求属性都不会丢失。
1.6.3 执行forward或include

request可以代替JSP所提供的forward和include指令。HttpServletRequest类提供了一个getRequestDispatcher(String path) 方法,其中path就是希望forward获取include的目标路径,该方法返回RequestDispathcher,该方法提供如下两个方法:

  • forward(ServletResquest request,ServletResponse response):执行forward。
  • include(ServletRequest request,ServletResponse response):执行include。
    将a.jsp include到本页面:
getResquestDispatcher("a.jsp").include(request,response);

将请求forward到a.jsp:

getResquestDispathcer("a.jsp").forward(request,response);

1.7 response对象

response代表服务器对客户端的响应。通常情况下,只需要out对象就能完成对客户端的响应,但是out只能输出字符流,无法输出非字符内容,此时必须使用response作为响应输出。

1.7.1 response 响应生成非字符响应

response是HttpServletResponse接口的实例,该接口提供了一个getOutputStream()方法,该方法返回响应输出字节流。

<%@page import="javax.imageio.ImageIO"%>
<%@page import="java.awt.Image"%>
<%@page import="java.awt.Font"%>
<%@page import="java.awt.Color"%>
<%@page import="java.awt.Graphics"%>
<%@page import="java.awt.image.BufferedImage"%>
<%@ page language="java" contentType="image/png; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
BufferedImage image = new BufferedImage(340,160,BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
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());
%>
</body>
</html>

上面的代码服务器响应客户端时,服务器响应了一张图片,因此必须使用response对象响应。

1.7.2 重定向

response的另外一个用处是重定向,重定向会丢失所有的请求参数和request范围的属性,因为重定向是第二次请求,于前一次请求不在同一个request范围内。
HttpServletResponse 提供了一个sendRedirect(String path)方法,该方法用于重定向path资源,即重新向path资源发送请求。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

<%
response.sendRedirect("request.jsp"); %>
</body>
</html>

上面的代码将页面重定向到了request.jsp页面重定向后,浏览器的地址栏的地址将变成重定向后的页面的地址。

1.7.3 增加Cookie

Cookie通常用于网站记录客户的某些信息,比如客户的用户名及客户的喜好等。一旦用户下次登录,网站可以获取到用户的相关信息,网站可以对客户提供更好的服务。Cookie和session的不同之处在于:session会随浏览器的关闭而失效,但Coockie会一直存在客户端机器上除非超过Cookie的生命期限。
由于安全性原因,客户端浏览器可以禁止Coockie,要使用Cookie客户端浏览器必须支持Cookie。
response提供如下方法增加Cookie:

  • addCookie(Cookie cookie):增加Cookie。

增加Cookie步骤:

  • 创建Cookie实例。
  • 设置Cookie生命期限。
  • 向客户端写Cookie.
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
String name = request.getParameter("name");
Cookie c = new Cookie("userName",name);
c.setMaxAge(24*3600);
response.addCookie(c);
%>
</body>
</html>

上面是创建Cookie的过程示例,如果浏览器支持Cookie,一个含有”name” request范围属性的请求发送到该界面,那么该页面将会向这个浏览器写入一个userName的Cookie,生命周期是24小时。
使用request的getCookies()方法可以将客户端上的所有Cookie返回。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

<%
Cookie[] cookies = request.getCookies();

for(Cookie c : cookies) {
    out.append(c.getName()).append(":").append(c.getValue()).append("<br/>");
}
out.flush();
%>
</body>
</html>

默认情况下 ,Cookie不允许出现中午字符,如果要使用中文字符,必须使用URLEncoder进行编码。

1.8 session对象

session对象代表一次会话。一次用户会话的含义是:从客户端浏览器连接服务器开始,到客户端浏览器于服务器断开为止,这个过程就是一次会话。
session通常用于跟踪用户的会话信息,如判断用户是否登录系统,或者在购物车应用中,用于跟踪用户购买的商品等。
session对象是HttpSession的实例,HttpSession有如下两个常用的方法:

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

session范围的属性在整个会话过程中有效。session机制主要用于保存客户端的状态信息,这些信息需要保存到服务器的硬盘上,因此要求这些属性值必须是可以序列化的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值