Java程序员从笨鸟到菜鸟(二十四)Java Web 九大内置对象

目录

JSP运行原理

  • 每当有JSP页面访问请求WEB容器时,容器将该访问请求交给JSP引擎取处理,Tomcat的JSP引擎就是一个servlet程序,它负责解释和执行JSP页面
  • 每个JSP页面在第一次被访问时,JSP引擎先将它翻译成一个Servlet源程序,接着再编译成Servlet的class文件,然后再由WEB容器装载和解释执行这个由JSP页面翻译成的Servlet程序

JSP执行过程

执行JSP文件需要经过两个时期:转译时期请求时期
转译时期:JSP转译成Servlet类(.class文件)
请求时期:Servlet类执行后,将结果响应至客户端

  1. 客户端发出请求
  2. Web容器将JSP转译成Servlet源码
  3. Web容器将产生的源码进行编译
  4. Web容器加载编译后的代码并执行
  5. 将执行结果响应至客户端

JSP九大内置对象

序号 内置对象 类型
1 request javax.servlet.http.HttpServletRequest
2 response javax.servlet.http.HttpServletResponse
3 session javax.servlet.http.HttpSession
4 pageContext javax.servlet.jsp.PageContext
5 application javax.servlet.ServletContext
6 config javax.servlet.ServletConfig
7 out javax.servlet.jsp.JspWriter
8 page java.lang.Object
9 exception java.lang.Throwable

request常用方法

  1. 获取客户端信息,例如请求URL、主机IP、资源等
  2. 获取客户端请求头信息
  3. 获取客户端请求参数

解决提交数据中文乱码问题:

  • 提交方式为get,设置request对象编码是无效的,request对象还是以ISO8859-1编码接收数据,需要做转换
String data = request.getParameter("paramName");
byte[] source = data.getBytes("ISO8859-1");
data = new String(source, "UTF-8");
  • 提交方式为post,只需在服务端设置request对象编码即可,设置成和客户端提交一样的编码就行
request.setCharacterEncoding("UTF-8");

request对象实现请求转发:

请求转发:指一个web资源收到客户端请求后,通知服务器区去调用另外一个web资源进行处理

实现请求转发的两种方式:

  1. 通过ServletContext的getRequestDispatcher(“path”),该方法返回一个RequestDispatcher对象,调用forward方法实现请求转发
  2. 通过request提供的getRequestDispatcher(“path”),该方法返回一个RequestDispatcer对象,调用forward方法实现请求转发

请求重定向和请求转发的区别:

  • 一个web资源收到客户端请求之后,通知服务器取调用另外一个web资源进行处理,是服务器行为,一次request,称为请求转发
  • 一个web资源收到客户端请求之后,通知服务器取访问另外一个web资源进行处理,是客户端行为,两次request,称为请求重定向

解释:
背景:办理营业执照
重定向:你先去了A局,A局看了之后,说:“这个不归我们管,去B局”,然后你转车去了B局
转发:你先去了A局,A局看了之后,知道这个事情由B局管,但是没有把你叫去B局,而是叫你等一下,然后联系了B局的人,让他们把事情办好后,送过来

response常用方法

web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代替请求的request对象和代表响应的response对象,request获取客户端提交的数据,response向客户端输出数据

  1. 负责向客户端发送数据的相关方法
  2. 负责向客户端发送响应头的相关方法
  3. 负责向客户端发送状态码的相关方法
  4. 响应状态码的常量

常见应用

  • 使用OutputStream流向客户端浏览器输出中文数据
String str = "中国";
OutputStream outputStream = response.getOutputStream(); // 获取OutputStream输出流
response.setHeader("content-type", "text/html;charset=UTF-8"); // 通过设置响应头控制浏览器以UTF-8的编码显示数据,如果不加这句话,那么浏览器显示的将是乱码
byte[] dataByteArr = str.getBytes("UTF-8"); // 将字符转换成字节数组,指定以UTF-8编码进行转换
47         outputStream.write(dataByteArr); // 使用OutputStream流向客户端输出字节数组
  • 使用PrintWriter流向客户端浏览器输出中文数据
String str = "我爱你";
response.setCharacterEncoding("UTF-8"); // 设置将字符以"UTF-8"编码输出到客户端浏览器
PrintWriter out = response.getWriter(); // 获取PrintWriter输出流
out.write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'/>");
out.write(data);//使用PrintWriter流向客户端输出字符
  • 实现文件下载
    • 获取要下载文件的绝对路径
    • 获取要下载的文件名
    • 设置content-disposition响应头控制浏览器以下载的形式打开文件
    • 获取要下载的文件输出流
    • 创建缓冲区
    • 通过response对象获取OutputStream流
    • 将FileInputStream流写入buffer缓冲区
    • 使用OutputStream将缓冲流的数据输出到客户端
String realPath = this.getServletContext().getRealPath("/download/张家界国家森林公园.JPG"); // 获取要下载的文件的绝对路径
String fileName = realPath.substring(realPath.lastIndexOf("\\")+1); // 获取要下载的文件名
// 设置content-disposition响应头控制浏览器以下载的形式打开文件,中文文件名要使用URLEncoder.encode方法进行编码,否则会出现文件名乱码
response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(fileName, "UTF-8"));
InputStream in = new FileInputStream(realPath); // 获取文件输入流
// 使用PrintWriter流下载文件
// FileReader in = new FileReader(realPath);
int len = 0;
byte[] buffer = new byte[1024];
OutputStream out = response.getOutputStream();
// PrintWriter out = response.getWriter();
while ((len = in.read(buffer)) > 0) {
    out.write(buffer,0,len); // 将缓冲区的数据输出到客户端浏览器
}
in.close();

分析:使用PrintWriter流处理字节数据,会导致丢失,下载文件时要使用OutputStream流,OutputStream是字节流,可以处理任意类型的数据,而PrintWriter是字符流,只处理字符数据

  • 生成随机图片作为验证码
    主要使用BufferedImage类

  • 设置http响应头控制浏览器禁止缓存当前内容

response.setDataHeader("express", -1);
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
  • 设置http响应头控制浏览器定时刷新网页

    response.setHeader("refresh", "5"); // 控制浏览器每隔5秒刷新一次
  • 实现请求重定向
    应用场景:用户登录界面,登录成功后,跳转指定界面,这个过程就是重定向
    实现方式:

response.sendRedirect(String path);

servlet:生命周期:

  • 初始化,调用init()方法
  • 响应客户端请求,调用service()方法(doGet/doPost)
  • 终止阶段:调用destroy()方法
session常用方法

会话概念:用户开一个浏览器,点击多个超链接,访问web资源,然后关闭浏览器,整个过程称为会话;有状态会话:能记住某人曾经访问过

会话可以解决的问题:保存用户数据

保存会话的两种技术:
Cookie:客户端技术,程序把每个用户数据以cookie的形式写给用户各自浏览器,当用户使用浏览器再去访问服务器的web资源时,就会带着各自的数据去

Seession:是服务端技术,服务器可以为每个用户的浏览器创建一个其独享的session对象,多那个用户去访问服务器中的其它web资源时,其它资源再从用户名各自的session中取出数据为用户服务

cookie使用范例:

// 设置服务端以UTF-8编码进行输出
        response.setCharacterEncoding("UTF-8");
        //设置浏览器以UTF-8编码进行接收,解决中文乱码问题
        response.setContentType("text/html; charset=utf-8");
        PrintWriter out = response.getWriter();
        // 获取浏览器访问服务器传递过来的cookie数组
        Cookie[] cookies = request.getCookies();
        // 如果用户是第一次访问,那么得到的cookies将是null
        if (null != cookies) {
            out.write("上次的访问时间是:");
             //  out.write(URLDecoder.decode(cookies[i].getValue(), "UTF-8")); 显示中文,要进行解码操作
            for (int i = 0; i < cookies.length; i++) {
                Cookie cookie = cookies[i];
                if ("lastAccessTime".equals(cookie.getName())) {
                    Long lsatAccessTime = Long.parseLong(cookie.getValue());
                    Date date = new Date(lsatAccessTime);
                    out.write(date.toLocaleString());
                }
            }
        } else {
            out.write("第一次访问本站");
        }

        // 用户访问过后重新设置访问时间,存储cookie中,然后发送到客户端浏览器
        Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis() + ""); // 新建一个cookie

// Cookie cookie1 = new Cookie("userName", URLEncoder.encode("中国", "utf-8")); 中文显示

        // 设置cookie的有效期为1天,如果未设置有效期,关闭浏览器之后就失效了,设置有效期,在关闭浏览器之后仍然有效,如设置有效期为0,则为删除cookie的操作
         cookie.setMaxAge(24 * 60 * 60);

        // 将cookie对象添加到response对象中,这样服务器在输出response对象中的内容时就会把cookie也输出到客户端
        response.addCookie(cookie);

Session简介

session和cookie的区别

  1. cookie是吧用户的数据写给用户浏览器
  2. session是吧数据写到用户独占的session中
  3. session对象由服务器创建,开发人员可使用request对象的getSession方法得到session对象

session 实现原理

服务器创建session之后,会把session的id号,以cookie的形式回写给客户端,只要客户端浏览器不关,再次访问服务器时,都会带着session的id号去,服务器发现客户端带session的id过来,就会使用内存中与之对应的session为之服务

session 创建

response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
// 使用request对象的getSession()获取session,如果不存在就创建一个
HttpSession session = request.getSession();
// 将数据存储到session中
session.setAttribute("str", "中国");
// 获取session的id
String sessionId = session.getId();
// 判断session是不是新建的
if (session.isNew()) {
    response.getWriter().print("session创建成功,sessionId是:" + sessionId);
} else {
    response.getWriter().print("服务器已存在该session, session的id是:" + sessionId);
}

session销毁

自动销毁:默认情况下30分钟不使用
人工销毁:

  1. 在web.xml中
<session-config>
    <session-timeout>15</session-timeout> // 设置有效时间,单位为:分钟
</session-config>
  1. 在程序中

    session.invalidate();

浏览器禁用cookie之后session处理

解决方案:URL重写

response.encodeRedirectURL(String url); // 用于对sendRedirect方法后的url地址进行重写
response.encodeURL(Stirng url); // 用于对表单action和超链接的url地址进行重写

application常用方法

application 对象用来在多个程序或者是多个用户之间共享数据,服务器一旦启动就会自动创建application对象,并一直保持下去,直至服务器关闭,application会自动消失,不需要麻烦垃圾回收机制。

servlet三大域对象

  • request:一个用户可以有多个
  • session:一个用户就一个
  • application(ServletContext):servletContext所有用户公用一个,要考虑到线程安全问题

application

以一个网站的访问量来演示application的用法:
未使用application对象

// 直接在方法上加synchronized关键字,放置资源竞争
int countor = 0; // 初始化计数器
countor++; // 计数器自增

运行效果:每刷新一次页面,计数器加1,正常逻辑是有新用户访问网站,计数器进行加1操作,而不是刷新页面一次就为一次访问

加入application对象

protected synchronized void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext application = this.getServletContext(); // 获取servletContext对象
        Integer number = (Integer)application.getAttribute("Count");
        if(null == number) {
            number = new Integer(1); // 实例化number对象
            application.setAttribute("Count", number);
        } else {
            number=new Integer(number.intValue()+1);
            application.setAttribute("Count", number);
        }
        Integer numberCount = (Integer)application.getAttribute("Count");
        application.setAttribute("number", numberCount);
        response.sendRedirect("/applicationtest.jsp");
    }

前台页面:applicationtest.jsp

<body>
欢迎访问本站,你是第${number }个访问用户
</body>

运行效果:刷新当前页面,计数器并不会做自增操作,只有重新访问这个页面之后,才会进行加1操作

pageContext常用方法

四大容器

容器 作用域
pageContext 仅仅是当前页面,无法传参
request 当前页面,可以传参
session 同一个SESSIONID共用一个
application 只要服务器没有重新启动,就一直存在

pageContext对象时JSP技术中最重要的一个对象,它代表JSP页面的运行环境,代表页面上下文,主要用于访问JSP之间的共享数据,不仅封装了8大隐式对象的引用,自身还是一个域对象,可以用来存储数据,可以操作另外三个域(request,session,servletContext)

获得其它对象

getRequest()方法返回request隐式对象
getResponse()方法返回response隐式对象
getSession()方法返回session隐式对象
getServletContext()方法返回application隐式对象
getServletConfig()方法返回config隐式对象
getOut()方法返回会out隐式对象
getPage()方法返回page隐式对象
getException()方法返回exception隐式对象

pageContext对象封装了访问其他域的方法

代表各个域的常量

  • PageContext.APPLICATION_SCOPE
  • PageContext.SESSION_SCOPE
  • PageContext.REQUEST_SCOPE
  • PageContext.PAGE_SCOPE
    例如:
pageContext.getAttribute("name", PageContext.SESSION_SCOPE);

PageContext跳转到其它资源

 pageContext.getRequest().getRequestDispatcher("/index.jsp").forward(request, response);

config常用方法

config代表当前JSP的配置信息,到那时JSP页面通常无需配置,也就不存在配置信息,比较少用,但是在Servlet则是用处相对较大

out常用方法

  1. out对象用于向客户端发送文本数据
  2. out对象通过调用pageContext对象的getOut()方法返回
  3. JSP页面中的out对象类型为JspWriter,JspWriter相当于一种带缓存功能的PrintWriter,设置JSP页面的page指令的buffer属性可以调整它的缓存大小

page常用方法

page对象表示当前一个JSP页面,可以理解为一个对象本身

exception常用方法

exception对象是一个异常对象,当页面在存储过程中发生了异常,就产生这个对象,如果JSP页面应用此对象,必须把isErrorPage设置成true

通常用法

  1. exception.getMessage() 返回描述异常消息
  2. exception.toString() 返回关于异常的简短描述消息
  3. exception.printStackTrace() 显示异常及其栈轨迹

原文转载自:https://www.cnblogs.com/xdp-gacl/p/3779872.html

猜你喜欢

转载自blog.csdn.net/u013090299/article/details/80513712
今日推荐