JavaWeb(二)jsp运行原理,九大内置对象

JSP运行原理:

每个JSP页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理。JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet) ,然后按照servlet的

调用方式进行调用。

由于JSP第一次访问时会翻译成servlet,所以第一次访问通常会比较慢,但第二次访问,JSP引擎如果发现JSP没有变化,就不再翻译,而是直接调用,所以程序的执行效率不会受到影响。

JSP引擎在调用JSP对应的_jspServlet时,会传递或创建9个与web开发相关的对象供_jspServlet使用。JSP技术的设计者为便于开发人员在编写JSP页面时获得这些web对象的引用,特

意定义了9个相应的变量,开发人员在JSP页面中通过这些变量就可以快速获得这9大对象的引用。

Jsp九大隐式对象

内置对象/作用域(每一种作用域的生命周期是不一样的): 1, application 全局作用域 2, session 会话作用域 3, request 请求作用域 4, pageContext 页面作用域 内置对象 5, response 响应对象 6, out 输出流对象 7, page 当前页面对象的实例 8, exception 异常 9, config ServletConfig/FilterConfig对象

优先级 (按照生命周期的长短): application > session > request > pageContext

request对象:

request对象是HttpServletRequest这个类的实例 常用方法:‘’

String getParameter(String name)---返回name指定的参数的值 String[] getParameterValues(String name)---返回一个数组, 是包含那个参数名的所有的人,复选框等提交内容

<%@ 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 action="test2.jsp" method="post">
    username: <input type="text" name="username" /><br>
    password: <input type="text" name="password" /><br>
    
    1<input type="checkbox" name="ct" value="1" /><br>
    2<input type="checkbox" name="ct" value="2" /><br>
    3<input type="checkbox" name="ct" value="3" /><br>
    4<input type="checkbox" name="ct" value="4" /><br>
    5<input type="checkbox" name="ct" value="5" /><br>
    
    <input type="submit" value="提交" />
</form>
</body>
</html>
<%@ 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 username = request.getParameter("username");
String password = request.getParameter("password");
String[] cts = request.getParameterValues("ct");

out.print("request.getParameter()接收到的参数: " + username+"<br>");
out.print("request.getParameter()接收到的参数: " + password);

for (String s : cts) {
    out.print("<br>"+"复选框的值: " + s );
}
%>
</body>
</html>

void setAttribute(String, Object)---设置某个作用域中的属性 Object getAttribute(String name)---获取某个作用域中的属性

//设置某个作用域中的属性 
<%request.setAttribute("req", 123); %>
//获取某个作用域中的属性 
<%=request.getAttribute("req")%>

String getRealPath(String path)---返回传入的这个路径的物理路径 String getContextPath()---返回上下文路径 String getServerName()---返回请求服务器的主机名 String getContentType()---返回请求体的MIME类型 String getprotocol()---返回请求用的协议类型和版本号 int getServerPort()---获取服务器的端口号 int getContentLength()---返回请求体的长度(单位是字节) String getRemoteAddr()---返回发送此请求的客户端的IP地址

<%@ 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>
<br>
--String getRealPath(String path)---返回传入的这个路径的物理路径
<%=request.getRealPath("/") %>
<br>
--String getContextPath()---返回上下文路径
<%=request.getContextPath() %>    
<br>
--String getServerName()---返回请求服务器的主机名
<%=request.getServerName() %>    
<br>
--String getContentType()---返回请求体的MIME类型
<%=request.getContentType() %>    
<br>
--String getprotocol()---返回请求用的协议类型和版本号
<%=request.getProtocol() %>    
<br>
--int getServerPort()---获取服务器的端口号
<%=request.getServerPort() %>    
<br>
--String getRemoteAddr()---返回发送此请求的客户端的IP地址
<%=request.getRemoteAddr() %>            
<br>
--int getContentLength()---返回请求体的长度(单位是字节)
<%=request.getContentLength() %>    
</body>
</html>

解决request中出现中文乱码的问题 post方式: 通过使用request.setCharacterEncoding("utf-8")来设置 get方式: 通过修改Tomcat服务器中的server.xml配置文件来设置

<%
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
%>

Session对象

session指的是用户在进入一个网站开始到关闭浏览器的时间, Tomcat服务器默认的session有效时间是30分钟, 也就是说, 打开一个网站30分钟之内没有动作, session对象同样也会失效 session存在服务器的内存中, 服务器中不同的用户对应的session也是不同的, 所以服务器用来判断当前登录的用户是否是同一个的时候就需要session session对象是HttpSession的实例 常用方法: long getCreationTime()---返回session对象创建的时间 String getId()---返回一个sessionid, 是唯一的 void setAttribute()---设置一个属性和一个属性值 Object getAttribute()---获取某个属性的属性值 String[] getValueNames()---以数组的形式获取session对象中所有可用属性的属性名 setMaxInactiveInterval()---设置session经过多长时间之后失效(默认30分钟) getMaxInactiveInterval()---设置session的失效时间(单位是秒)

session的生命周期: 创建: 当用户第一次访问某个jsp或者servlet的时候, 服务器就会为当前的访问创建一个session, 并生成一个sessionId, 每次客户端向服务器发送请求的时候, 都会将这个sessionId带过去进行验证

活动: 在这个页面的各种活动, 比如通过超级连接打开另一个页面, 或者进行各种增删改查的操作, session失效除非要等到浏览器的相关页面全部关闭, 或者session超时, 当再次访问的时候会创建一个新的session, 但是原来的session还会存在, 只不过没有任何请求再带着那个旧的sessionId让服务器去验证了

销毁: 三种方法可以销毁session 1, 调用session.invalidate()方法 2, session自己过期了 设置session过期时间也可以在web.xml中设置 <session-conf> <session-timeout> 10<!-- 单位是分钟 ! --> </session-timeout> </session-conf> 3, 服务器重新启动

            if(obj!=null) {
            User u = (User)obj;
            if(password.equals(u.getPassword())) {
                session.setAttribute("currentUser", u);//设置验证登录,如果直接访问主页,验证时获取不到user,跳转
                response.sendRedirect("main.jsp");
            } else {
                out.print("密码不对啊 !");
            }
        }        
<%    
    Object obj1 = session.getAttribute("currentUser");
    if (obj1 == null) {
        response.sendRedirect("denglu.jsp");
    }
%>

application对象

application对象是一个全局对象, 生命周期为服务器启动一直到服务器停止, 在这个对象里面可以存放一些全局变量

setAttribute(String, Object)---设置某个属性和属性值 getAttribute(String)---获得某个属性的值 getAttributeNames()---获取application对象中所有的属性名

if(obj==null){
            List list =new ArrayList();
            list.add(says);
            application.setAttribute("liuyanjihe",list);
        }else{
            List<Says> list=(List)obj;
            list.add(says);
            application.setAttribute("liuyanjihe",list);
        }
Object obj=application.getAttribute("liuyanjihe");

pageContext对象

pageContext对象是JSP技术中最重要的一个对象,它代表JSP页面的运行环境.

这个对象不仅封装了对其它8大隐式对象的引用,

它自身还是一个域对象,可以用来保存数据。

并且,这个对象还封装了web开发中经常涉及到的一些常用操作,例如引入和跳转其它资源、检索其它域对象中的属性等。

通过pageContext获得其他对象:

getException方法返回exception隐式对象

getPage方法返回page隐式对象

getRequest方法返回request隐式对象

getResponse方法返回response隐式对象

getServletConfig方法返回config隐式对象

getServletContext方法返回application隐式对象

getSession方法返回session隐式对象

getOut方法返回out隐式对象

pageContext对象的方法

public void setAttribute(java.lang.String name,java.lang.Object value)

public java.lang.Object getAttribute(java.lang.String name)

public void removeAttribute(java.lang.String name)

pageContext对象中还封装了访问其它域的方法

public java.lang.Object getAttribute(java.lang.String name,int scope)

public void setAttribute(java.lang.String name, java.lang.Object value,int scope)

public void removeAttribute(java.lang.String name,int scope)

代表各个域的常量

PageContext.APPLICATION_SCOPE

PageContext.SESSION_SCOPE

PageContext.REQUEST_SCOPE

PageContext.PAGE_SCOPE

response对象

response对象是HttpServletResponse的实例 常用方法: setCharacterEncoding(String name)---设置响应页面使用的字符编码 setContentType("text/html; charset=utf-8")---设置(MIME类型)请求头 response.getWriter().append(String content)---向页面输出一段字符串

out对象

out对象的类型是JspWriter, 而response.getWriter()是一个PrintWriter, out对象也可以通过pageContext.getOut()获得, 这两个对象的类型不一样 out.print()可能会抛出异常 PrintWriter.print()不会抛出异常

JspWriter是一个抽象类, PrintWriter是一个继承了Writer的普通类

getWriter()方法可以在页面上输出一串字符, out也是一个输出对象, 两者的区别在于, getWriter()方法的执行结果, 总是优先于out对象, 可以使用out.flush()方法, 强行属性缓冲区的内容, 将out对象的输出结果先输出出来

造成这种现象的原因: out对象实际上对PrintWriter是有依赖的, 他需要先将需要输出的内容存到response的缓冲区里面, 然后等待jsp页面中的out满足一定条件之后, 才会调用输出的方法把内容直接输出到页面上

而PrintWriter是可以直接输出出来的

转发和重定向(面试98%会问)

response.sendRedirect(String location)---请求重定向 客户端行为, 从本质上讲相当于两次请求, 第一次请求的对象不会被保存, 地址栏的Url地址会改变 request.getRequestDispatcher().forward(request, response)---请求转发 服务器行为, 相当于一次请求, 转发后请求对象会被保存, 地址栏url不会改变

out和response(了解)

在JSP页面中不应该使用response.getWriter()这个流。

out对象是JspWriter类型,它与response.getWriter()返回的PrintWriter都是底层响应流的包装。用来向客户端响应字符数据。

但是,在页面中不应该使用response.getWriter()来响应,而是使用隐藏对象out。因为Tomcat总是会先把response.getWriter()中的数据输出给我响应端,然后才是隐藏对象out输出的数据!这会导致使用response.getWriter()输出的数据出现在<html>之前!

如果想看到错误的结果,可以在JSP中使用response.getWriter(),以及out穿插输出。然后使用HttpWatch来查看响应结果。

config和page(了解)

page对象,它只是表示当前JSP“真身”的当前实例,即this。

config是ServletConfig类型,在JSP中一般不会在web.xml文件中配置,但也是可以配置的!就像是配置Servlet配置一样的方法!

  <servlet>
      <servlet-name>e</servlet-name>
      <jsp-file>/e.jsp</jsp-file>
      <init-param>
          <param-name>test</param-name>
          <param-value>jsp test value</param-value>
      </init-param>
  </servlet>
  <servlet-mapping>
      <servlet-name>e</servlet-name>
      <url-pattern>/e.jsp</url-pattern>
  </servlet-mapping>


    <%=config.getInitParameter("test")%>

exception

exception对象不是所有页面都可以使用的,只能在错误页中可以使用。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏雨尘分享

5.Block的内存管理 内存管理内存管理block的循环引用

18240
来自专栏Android 研究

Retrofit解析5之代理设计模式

即Proxy Pattern,23种常用的面向对象软件设计模式之一。(设计模式的说法源自<设计模式>一书,原名<Design Patterns:Elements...

14930
来自专栏Danny的专栏

【SpringDataJPA】——SpringDataJPA入门实例

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/...

15520
来自专栏祝威廉

Spark SQL操作JSON字段小Tips

很多时候,比如用structure streaming消费kafka数据,默认可能是得到key,value字段,key是偏移量,value是一个byte数组。很...

9120
来自专栏老马说编程

(87) 类加载机制 / 计算机程序的思维逻辑

上节,我们探讨了动态代理,在前几节中,我们多次提到了类加载器ClassLoader,本节就来详细讨论Java中的类加载机制与ClassLoader。 类加载...

20580
来自专栏DOTNET

【翻译】MongoDB指南/引言

【原文地址】https://docs.mongodb.com/manual/ 引言 MongoDB是一种开源文档型数据库,它具有高性能,高可用性,自动扩展性 1...

28660
来自专栏Java 源码分析

JavaWeb基础

1. XML xml一般就用来存放少量的数据,或者是作为配置文件。 xml的声明<?xml version=”1.0” encoding=”utf-8”?> ...

35850
来自专栏null的专栏

挑战数据结构和算法——跳台阶问题

题目来源“数据结构与算法面试题80道”。在此给出我的解法,如你有更好的解法,欢迎留言。 ? image.png 方法: int get_kind(int n...

28860
来自专栏Java学习网

Java中application对象的19个常用方法

applicaton表示一个javax.servlet.ServletContext对象。他实现了用户间数据的共享,可存放全局变量。它开始于服务器的启动,直到服...

25550
来自专栏蓝天

RPC的实现

RPC全称为Remote Procedure Call,即远过程调用。如果没有RPC,那么跨机器间的进程通讯通常得采用消息,这会降低开发效率,也会增加网络...

25730

扫码关注云+社区

领取腾讯云代金券