三、JSP九大内置对象
什么是内置对象?
JSP的内置对象是指在JSP页面系统中已经默认内置的Java对象,这些对象不需要开发人员显式声明即可使用。在JSP页面中,可以通过存取JSP内置对象实现与JSP页面和Servlet环境的互相访问。每个内部对象均有对应所属的ServletAPI类型。
3.1 out对象
-
out对象的作用
Out对象是javax.servlet.jsp.JspWriter类的实例,主要用于向客户端浏览器输出数据;
在使用out对象输出数据时,可以对数据缓冲区进行操作,及时清除缓冲区中的残余数据,为其他的输出让出缓冲空间,待数据输出完毕后,要及时关闭输出流。 -
out对象的常用方法
方法名 描述 void print() 输出数据,不换行。 void println() 输出数据,换行(但是浏览器目前不识别此换行符,如果希望浏览器显示换行,应当向浏览器写入**< br >**来换行)。 void newLine() 输出一个换行符。 void flush() 输出缓冲区里的数据。 void close() 关闭输出流。 void clear() 清除缓冲区中的内容,不将数据发送至客户端。 void clearBuffer() 将数据发送至客户端后,清除缓冲区中的内容。 int getBufferSize() 获得缓冲区的大小。 void getRemaning() 获取缓冲区里没有使用的空间大小。 public boolean isAutoFlush() 获取用<%@ page is AutoFlush=“true/false”%>设置的AutoFlush值。 <% out.print("这是登录页面!"); out.println();//表示换行,在页面中不显示换行,只在源代码中显示换行1 out.print("println()后页面!"); out.newLine();//表示输出一个换行符,仍然是在源代码中才换行哦^_^! out.print("newLine()后页面"); out.print("</br>br换行后的页面");//目前只有br换行符对页面才起作用! out.print("</br>调用clearBuffer前"); out.flush(); out.clearBuffer(); out.print("</br>调用clearBuffer后"); out.print("</br>调用clear前"); out.flush(); /** * flush()和clear()一起使用时报错: * 产生错误的原因是两者同时具有对缓冲区清空的能力,当clear()位于flush()之后使用, * 会造成二次清空缓冲区的情况出现,从而导致clear()方法无效,故而报错。 */ out.clear();//此时在调用clear()时会发生错误 out.print("</br>调用clear后"); %>
小贴士:
- 避免调用容易抛出异常的方法(close()和flush()方法后接clear()方法),产生错误的原因是两者同时具有对缓冲区清空的能力,当clear()或close()位于flush()之后使用,会造成二次清空缓冲区的情况出现,从而导致clear()方法或close()方法无效,故而报错。
- 在数据没有清空之前,中途调用close()方法会使数据丢失造成异常,这时我们需要调用flush()方法强制将数据全部输出,从而清空缓冲区,最后再调用close()方法关闭输出流即可。
3.2 request对象
-
request对象的作用
- request 对象是 javax.servlet.httpServletRequest类型的对象。
- 该对象代表了客户端的请求信息,主要用于接受通过HTTP协议传送到服务器的数据。(包括头信息、系统信息、请求方式以及请求参数等)。
- request对象的作用域为一次请求。
-
request对象的常用方法
方法名 描述 object getAttribute() 返回指定属性的属性值 void setAttribute() 设置属性的属性值 String getParameter() 返回指定参数的参数值 String getParameterValues() 返回包含参数的所有值得数组 String getMethod() 返回提交方式 Enumeration getAttributeNames() 返回所有可用属性名的枚举 Enumeration getParameterNames() 返回所有可用参数名的枚举 -
request常用方法的使用
<body> 请求的URL地址: <%=request.getRequestURI() %><br> 协议名称: <%=request.getProtocol() %><br> 客户端请求服务器文件的路径: <%=request.getServletPath() %><br> /** *url的查询部分指的是此链接后面的参数 *http://localhost:8080/ebuy/index.jsp?id=1&&name=z **/ URL的查询部分: <%=request.getQueryString() %><br> 服务器的名称: <%=request.getServerName() %><br> 服务器口号: <%=request.getServerPort() %><br> 远程客户端的IP地址: <%=request.getRemoteAddr()%><br> 获得发出请求的客户端地址: <%=request.getRequestURI()%><br> 提交方式: <%=request.getMethod() %><br> 请求的URL地址: <%=request.getRequestURI() %><br> </body>
- Enumeration getAttributeNames():我们可以通过req.getParameter()方法获取到输入框中的值,但当输入框有无数多个的时候,很明显采用一个一个获取的效率是很慢的,这时我们可以通过req.getParameterMap()方法来获取一个输入框中值的集合,再遍历集合就可以得到各个值。
/**
* 我们可以通过req.getParameter()方法获取到输入框中的值,但是!
* 当输入框有无数多个的时候,很明显采用一个一个获取的效率是很慢的,这时我们可以通过
* req.getParameterMap()方法来获取一个输入框中值得集合,再遍历集合就可以得到各个值。
*/
Map<String,String[]> map = req.getParameterMap();
for (String key:map.keySet()){
System.out.println(key+"-------"+req.getParameter(key));
}
-
转发和重定向
- 转发:由服务器端内部执行机制进行的页面跳转,一般使用request作用域存储数据。
req.getRequestDispatcher("/地址").forward(req,resp):
转发的特点:- 地址栏不发生变化,显示的是上一个页面的地址;
- 请求次数:只有一次请求;
- 根目录:http://localhost:8080/项目地址/,包含了项目的访问地址;
- 请求域中数据不会丢失。
- 重定向:由浏览器端进行的页面跳转,一般使用全局作用域session存储数据。
response.sendRedirect("/地址");
重定向的特点:- 地址栏显示新的地址;
- 请求次数:两次;
- 根目录:http://localhost:8080/没有项目额名字;
- 请求域中的数据会丢失,因为发生了两次请求。
重定向和转发的区别:
区别 转发forward() 重定向sendRedirect() 根目录 包含项目访问地址 没有项目访问地址 地址栏 不会发生变化 会发生变化 哪里跳转 服务器端进行的跳转 浏览器端进行的跳转 请求域中数据 不会丢失 会丢失 小贴士:
- 什么时候使用转发,什么时候使用重定向?
如果以后要求保留请求域中的数据,使用转发,否则使用重定向;
以后访问数据库,增删改使用重定向,查询使用转发。 - 转发或重定向后续的代码是否还会运行?
无论转发或重定向后续的代码都会执行。
//使用转发,作用域为request request.setAttribute("xxx",xxx); request.getRequestDispatcher("xxx.jsp").forward(request,response); //使用重定向,作用域为session request.getSession().setAttribute("xxx",xxx); response.sendRedirect("xxx.jsp");
-
request中的中文乱码问题
- 以get方式提交数据
<% //读取用户名和密码 String name = request.getParameter("name"); //对请求数据进行字符编码 name = new String(name.getBytes("ISO-8859-1"),"UTF-8"); %>
- 以post方式提交数据
//设置读取请求信息的字符编码为utf-8 request.setCharacterEncoding("utf-8"); //读取用户名和密码 String name = request.getParameter("name"); String pwd = request.getParameter("pwd");
3.3 response对象
-
response对象
response对象用于响应客户请求并向客户端返回信息。 response是Servlet.service方法的一个参数,类型为javax.servlet.http.HttpServletResponse。在客户端发出每个请求时,服务器都会创建一个response对象,并传入给Servlet.service()方法。response对象是用来对客户端进行响应的,这说明在service()方法中使用response对象可以完成对客户端的响应工作。 -
response对象的作用
方法名 描述 void addCookie() 添加一个Cookie对象。 void setContentType() 改变contentType的属性值。 void addHeader() 添加http文件头。 boolean containsHeader 判断http文件头是否存在。 void flushBuffer() 强制把当前缓冲区的内容发送到客户端。 void setHeader() 根据http头文件的名字来设定它的值。 void setIntHeader() 根据http文件头的名字来设定它的值。 void sendError() 传送状态码,错误信息。 void sendRedirect() 页面重定向,用来实现页面跳转。 //相应头文件类型 resp.setContentType("text/html;charset=utf-8"); resp.setContentType("application/json;charset=utf-8"); PrintWriter out = resp.getWriter(); //只有火狐浏览器可以直接识别json数据格式 out.println("{\"id\":\"1\",\"name\":\"zs\"}");
-
JSON数据格式
public static void main(String[] args) { /** * map集合 */ Map<Object,Object> map = new HashMap<>(); map.put("id","1"); map.put("name","zs"); System.out.println("map集合:"+JSON.toJSON(map)); /** * list集合 */ List list = new ArrayList(); list.add("1"); list.add("2"); System.out.println("list集合:"+list); /** * 对象 */ User user = new User(); user.setUserId("1"); user.setUserName("张三"); user.setPassword("123654"); user.setEmail("15234152@qq.com"); System.out.println("User对象:"+JSON.toJSON(user)); /** * 将多个对象添加到集合中,用json格式输出 */ User user2 = new User(); user2.setUserId("2"); user2.setUserName("李四"); user2.setPassword("74589654"); user2.setEmail("74585965@163.com"); list.add(user); list.add(user2); System.out.println("多个对象用JSON输出:"+JSON.toJSON(list)); }
3.4 session对象
-
session对象的作用
Session是用于存放用户与web服务器之间的会话,即服务器为客户端开辟的存储空间。-
什么是会话?
会话就是浏览器与服务器之间的一次通话。 -
为什么使用会话?
为了弥补HTTP协议的不足。HTTP协议是无状态的,他不能保存上次访问该页面的用户,当然也就无法针对用户进行一对一的通信,会话可以保存用户的信息和IE进行交互。
-
-
session对象的原理
session对象的原理在于,服务器可以为客户端创建并维护一个session对象,用于存放数据。在创建session对象的同时,服务器将会为该对象产生一个唯一编号sessionID。服务器以cookie的方式将sessionID存放在客户端。当浏览器再次访问该服务器时,会将sessionID作为Cookie信息带到服务器,服务器可以通过该sessionID检索到以前的session对象,并对其进行访问。
注意:
cookie中仅仅保存了一个sessionID,而相对较多的会话数据保存在服务器对应的session对象中,由服务器来统一维护,这样一定程度保证了会话数据安全性,但增加了服务器端的内存开销。 -
session对象的生命周期
session存储在服务器的内存中(为了高速存取)。
-
session何时生效?
session在用户第一次访问服务器的时候创建,需要注意只有JSP、Servlet等程序时才会创建session,只访问HTML、IMAGE等静态资源并不会创建session,可调用request.getSession(true)强制生成session。 -
session何时失效?
1. 服务器会把长时间没有活动的session从服务器内存中清除,此时session便失效。Tomcat中session的默认失效时间为20分钟。
2. 调用session的invalidate方法。HttpSession session = request.getSession(); session.invalidate();//注销该request的所有session
-
session的过期时间是从什么时候开始计算的?是从一登录就开始计算还是说从停止活动开始计算?
session的过期时间是从session不活动的时候开始计算,如果session一直活动,session就总不会过期;
从该session未被访问开始计时,一旦session被访问,计时清零。 -
设置session的失效时间
(1) web.xml中<session-config> <session-timeout>30</session-timeout> </session-config>
(2) 在程序中手动设置
session.setMaxInactiveInterval(30*60);//设置单位为秒,设置-1为永不过期 request.getSession().setMaxInactiveInterval(-1);//设置永不过期
(3) tomcat也可以修改session过期时间,在server.xml中定义context时采用如下定义:
<Context path="/livsorder" docBase="/home/httpd/html/livsorder" defaultSessionTimeOut="3600" isWARExpanded="true" isWARValidated="false" isInvokerEnabled="true" isWorkDirPersistent="false"/>
小贴士:发生下面这四种情况之一,session将失效
- 用户关闭当前正在使用的浏览器;
- 关闭网页服务器;
- 用户未向服务器提出请求超过预设的时间;
- 运行程序结束session。
注意:当浏览器关闭时,不会向服务器发送信息,这次会话关联的所有会话数据并不会马上被删除,知道该会话超市时才会被删除。当用户再次打开浏览器时,服务器无法将新请求与以前的会话关联起来,一次会创建一个新的会话。
-
-
session对象的常用方法
方法名 描述 String getId() 返回session创建时的唯一ID号 long getCreationTime() 返回session创建时间 long getLastAccessedTime() 返回此session的最近一次请求时间 void invalidate() 取消session,使session不可用 object getAttribute() 从session对象中提取指定的对象 void setAttribute() 将对象添加到session对象中 void removeAttribute() 从session对象中删除指定的对象 void setMaxInactiveInterval() 设置session对象的生存空间 boolean isNew() 判断是否是一个新的用户 /** * Servlet请求页面 */ protected void login(HttpServletRequest req,HttpServletResponse resp)throws ServletException,IOException{ HttpSession session = req.getSession(); String username = req.getParameter("userName"); String password = req.getParameter("passWord"); session.setAttribute("username",username); session.setAttribute("password",password); resp.sendRedirect("index.jsp"); } /** * index.jsp页面 */ <% out.println("</br>"); out.println("</br>"); out.println("用户名:"+session.getAttribute("username")); out.println("密码:"+session.getAttribute("password")); out.println("</br>"); out.println("返回session创建时的唯一ID:"+session.getId()); out.println("</br>"); out.println("返回session创建时间:"+session.getCreationTime()); out.println("</br>"); out.println("返回此session的最近一次请求时间:"+session.getLastAccessedTime()); out.println("</br>"); out.println(); %>
3.5 application对象
-
application对象的作用
- application对象:当Web服务器启动时,Web服务器会自动创建一个application对象。application对象一旦创建,它将一直存在,直到Web服务器关闭。
- 一个Web服务器通常有多个Web服务目录 (网站),当Web服务器启动时,它自动为每个Web服务目录都创建一个application对象,这些application对象各自独立,而且和Web服务目录一一对应。
- 访问同一个网站的客户都共享一个application对象,因此,application对象可以实现多客户间的数据共享,可以存放全局变量。 访问不同网站的客户,对应的application对象不同。
-
application对象的生命周期
从Web服务器启动,直到Web服务器关闭。注意:
一个Web应用程序启动后,将会自动创建一个application对象,而且在整个应用程序的运行过程中只有一个application对象,也即所有访问该网站的客户都共享一个application对象。 -
application对象的作用范围
application对象是一个应用程序级的对象,它作用于当前Web应用程序,也即作用于当前网站,所有访问当前网站的客户都共享一个application对象。
具体来说:不管哪个客户来访问网站A,也不管客户访问网站A下哪个页面文件,都可以对网站A的application对象进行操作,因为,所有访问网站A的客户都共用一个application对象。
因此,当在application对象中存储数据后,所有访问网站A的客户都能够对其进行访问,实现了多客户之间的数据共享。 -
application对象的常用方法
方法名 描述 Object getAttribute() 从application中获取指定的对象 void setAttribute() 往application中保存指定的对象 String getRealPath() 返回指定虚拟路径的真实路径 void removeAttribute() 从application中删除指定的对象 String getServerInfo() 返回JSP(SERVLET)引擎名及版本号 <body> JSP(SERVLET)引擎名及版本号: <%=application.getServerInfo()%><br> 服务器支持的 Server API 的最大版本号: <%=application.getMajorVersion ()%><br> 服务器支持的 Server API 的最小版本号: <%=application.getMinorVersion ()%><br> 指定资源(文件及目录)的 URL 路径: <%=application.getResource("index.jsp")%><br> 返回 Test.jsp 虚拟路径的真实路径: <%=application.getRealPath("index.jsp")%> </body>
-
application简单应用——站点计数器
<body> <% //获得num对象的值 Object num = application.getAttribute("num"); //初始值设定为0 if (num == null){ application.setAttribute("num","0"); } String nums = (String) application.getAttribute("num"); //每访问一次,给num值自增1 int n = Integer.parseInt(nums)+1; //将累加后的值赋给num对象 application.setAttribute("num",String.valueOf(n)); %> 访问次数是:<%=n%> </body>
3.6 page对象
page是java.lang.Object类的一个实例,它指的是JSP实现类的实例,也就是说,它是JSP本身。相当于JSP编译生成servlet后是servlet类的this对象,实际上很少用到。
page作用域指本JSP页面的范围。
3.7 pageContext对象
pageContext对象提供了对JSP页面所有的对象的访问,pageContext对象的方法可以访问除本身以外的8个JSP内部对象。pageContext对象相当于JSP程序中所有对象功能的集成者。但其他的8个内置对象也都可以直接访问,所以pageContext对象应用较少。
3.8 config对象
config对象代表当前JSP配置信息,但JSP页面通常无需配置,因此也就不存在配置信息。该对象在JSP页面中非常少用,但在servlet则用处相对较大。因为servlet需要配置在web.xml文件中,可以指定配置参数。
3.9 exception对象
-
exception对象的作用
exception对象this专门负责处理JSP在执行过程中出现的异常问题的。但要注意exception对象一般要和page指令一起配合使用,只有在异常处理页面(在页面指令里有isErrorPage=true的页面)中才可以使用,把JSP文件执行时所有发生的错误和异常都集中到异常处理页面去处理。这不仅提高了系统的统一性,程序流程也变得更加简单清晰。 -
exception对象的常用方法
方法名 描述 String getMessage() 返回描述异常的消息 String toString() 返回关于异常的尖端描述信息 void printStackTrace() 显示异常及其栈轨迹 Throwable FillInStackTrace() 重写异常的执行栈轨迹 -
注意
<%@ page import="cn.ebuy.pojo.User" isErrorPage="true" errorPage="error.jsp" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <body> <% User user = (User) session.getAttribute("users"); if(user == null){ response.sendRedirect("login.jsp"); } %> 用户名=<%=user.getUserName()%> </body>
注意:
当用户不登录时,直接访问index.jsp页面时
页面中不加:isErrorPage=“true” errorPage=“error.jsp” 时会报空指针错误!
如果不加入的话, 错误处理文件就被当作正常文件处理, 这样的话,假定服务器端出错, 返回的状态码应该是 “500”, 但是因为出错后转到了错误处理页面并把出错页面当作正常页面返回给客户端,返回的 http status code 就变成了 200, 这样客户端就没有办法发现问题。
而加入 isErrorPage="true"后, 错误处理页面会被当作出错页面处理, 返回的状态码"500"会原封不动的返回到客户端,利于客户端发现问题。