Javaweb之Request对象与ServletContext对象

简介: Request对象功能:设置响应消息ServletContext对象概念代表整个web应用,可以和程序的容器(Tomcat服务器)来通信

Request对象

功能:设置响应消息

1. 设置响应行

  1. 格式:协议/版本 响应状态码 状态码状态
  2. 设置状态码:setStatus(int sc)

2. 设置响应头

setHeader(String name,String value)

3. 设置响应体

  1. 获取输出流(相对于当前程序来讲这是输出东西到客户端)
    字符输出流:PrintWriter getWriter()
    字节输出流:ServletOutputStream getOutputStream()
  2. 使用输出流,将数据输出到客户端浏览器

4. 响应重定向

       //重定向到responseServlet2

       /*

       //1.设置状态码为302

       response.setStatus(302);

       //2.设置响应头location

       response.setHeader("location", "/responseServlet2");

       */

       //鉴于上述重定向代码参数大都固定,封装有更为简单的重定向方法

       response.sendRedirect("/responseServlet2");

5. redirect和forward的区别?

重定向redirect的特点

  1. 地址栏发生变化
  2. 重定向可以访问其他站点(服务器)的资源
  3. 重定向是两次请求,不能使用request域对象来共享数据(request域对象仅作用 于一次请求的范围内)

转发forward的特点

  1. 转发地址栏不变
  2. 转发只能访问当前服务器的资源
  3. 转发是一次请求,可以使用request域对象来共享数据

6. 相对路径与绝对路径

相对路径

  1. 通过相对路径不可以唯一确定资源
  2. 相对路径以 . 开头,如 ./index.html
  3. ./为当前目录
  4. ../为上一级目录
  5. 如果相对路径开头什么都没有,那么默认为当前目录 ./    如 index.html=./index.html

绝对路径(常用)

  1. 通过绝对路径可以唯一确定资源
  2. 绝对路径以/开头,如 /responseServlet2
  3. 给浏览器使用的绝对路径中需要添加虚拟目录(项目的访问路径)

HTML页面中的链接是一定要加虚拟目录的

服务器端servlet中只有重定向需要加虚拟目录,因为重定向是给浏览器看的(因此有两次请求,用session来共享数据)

服务器端的请求转发不需要加虚拟目录,因为将请求转发是给服务器看的(因此只有一次请求,用request来共享数据)

  1. 超链接a<a href="/test/checkCodeServlet">超链接</a>
  2. form表单<form action="/test/loginServlet">
  3. 服务器响应给浏览器的重定向
    虚拟目录动态获取:request.getContextPath()

//需要动态获取虚拟目录

response.sendRedirect(request.getContextPath()+"/responseServlet2");

  1. 给服务器使用,绝对路径中不需要添加虚拟目录
  1. 服务器进行请求转发

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

相对路径与绝对路径的区别

  1. 在HTML中使用相对路径,浏览器会在地址栏内容上加上相对路径

1.HTML文件中的超链接

<ahref="hello">relative</a>

2.当前地址栏内容(当前虚拟目录是springmvc01)

http://localhost:8080/springmvc01/

3.点击超链接后,地址栏内容为

http://localhost:8080/springmvc01/hello

  1. 在HTML中使用绝对路径,浏览器会在域名:端口后加上绝对路径

1.HTML文件中的超链接

<ahref="/hello">absolute</a>

2.当前地址栏内容(当前虚拟目录是springmvc01)

http://localhost:8080/springmvc01/

3.点击超链接后,地址栏内容为

http://localhost:8080/hello

7. 服务器输出字符流

中文数据乱码问题

  1. PrintWriter pw = response.getWriter();获取的流的默认编码是ISO-8859-1
  2. response.setContentType("text/html;charset=utf-8");输出流之前设置响应消息体的数据格式以及编码

       //设置响应消息体的数据格式以及编码

       //response.setHeader("content-type", "text/html;charset=utf-8");

       //上述代码的简单形式

       response.setContentType("text/html;charset=utf-8");

       //1.获取字符输出流

       PrintWriterwriter=response.getWriter();

       //2.输出数据

       writer.write("你好啊啊啊,dominus!");

8. 服务器输出字节流

       //告诉浏览器该流使用的编码

       response.setContentType("text/html;charset=utf-8");

       //1.获取字节输出流

       ServletOutputStreamsos=response.getOutputStream();

       //2.输出数据

       sos.write("你好 dominus!".getBytes("utf-8"));

9. 验证码

       intwidth=100;

       intheight=50;

       //1.创建一个对象,在内存中生成图片

       BufferedImageimage=newBufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

       //2.美化图片

       //2.1填充背景色

       Graphicsg=image.getGraphics();//画笔对象 graphics:图像

       g.setColor(Color.PINK);//设置画笔颜色

       g.fillRect(0, 0, width, height);//填充矩形

       //2.2画边框

       g.setColor(Color.BLUE);

       g.drawRect(0,0,width-1,height-1);

       //2.3画验证码

       Stringstr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

       Randomran=newRandom();

       for (inti=1; i<=4; i++) {

           intindex=ran.nextInt(str.length());//返回[0,str,length)之间的随机整数

           charc=str.charAt(index);//随机字符

           g.drawString(String.valueOf(c), width/5*i, height/2);

       }

       //2.4画干扰线

       g.setColor(Color.GREEN);

       for (inti=0; i<10; i++) {

           intx1=ran.nextInt(width);

           intx2=ran.nextInt(width);

           inty1=ran.nextInt(height);

           inty2=ran.nextInt(height);

           g.drawLine(x1, y1, x2, y2);

       }

       //3.将图片输出到浏览器

       ImageIO.write(image, "jpg", response.getOutputStream());

<script>

   window.onload=function (){

       //获取超链接对象和图片对象

       vara=document.getElementById(`a`);

       varimage=document.getElementById("image");

       //绑定单机事件

       a.onclick=function () {

           //加时间戳

           vardate=newDate().getTime();

           //当超链接被点击时,更换img标签的src属性

           //并且为了浏览器不访问上次缓存的图片,要给绝对路径加上时间戳这个参数

           image.src="/checkCodeServlet?"+date;

       }

   }

</script>

ServletContext对象

概念

代表整个web应用,可以和程序的容器(Tomcat服务器)来通信

获取

  1. 通过request对象获取request.getServletContext()
  2. 通过HttpServlet获取     this.getServletContext()

在同一个web应用中,以上两种方式获取的ServletContext对象为同一个

功能

1. MIME类型

  1. 在互联网通信过程中定义的一种文件数据类型
  2. 格式:大类型/小类型text/htmlimage/jpeg
  3. 获取:String getMimeType(String filename)

2. 域对象:共享数据

  1. 方法:
  1. void setAttribute(String name,Object obj):存储数据
  2. Object getAttribute(String name):通过键获取值
  3. void removeAttribute(String name):通过键移除键值对
  1. ServletContext域对象范围:所有用户所有请求的数据

3. 获取文件的真实(服务器)路径

src目录下的文件都在WEB-INF的classes文件夹中

  1. 方法:String getRealPath(String path)
  2. context.getRealPath("/b.txt");//web目录下资源访问
  3. context.getRealPath("/WEB-INF/c.txt");//WEB-INF目录下的资源访问
  4. context.getRealPath("/WEB-INF/classes/a.txt");//src目录下的资源访问

classPath类路径

在编译打包后的项目中,根目录是META-INFWEB-INF

WEB-INF/classes 就是类路径,包含src下的所有文件

文件下载案例

       //1.获取请求参数:文件名称

       Stringfilename=request.getParameter("filename");

       System.out.println(filename);

       //2.使用字节输入流加载文件进内存

       //2.1找到文件的服务器路径

       ServletContextservletContext=this.getServletContext();

       Stringpath=servletContext.getRealPath("/img/"+filename);

       //2.2用字节流关联

       FileInputStreamfis=newFileInputStream(path);

       //3.设置response的响应头

       //3.1设置响应头:content-type

       StringmimeType=servletContext.getMimeType(filename);

       response.setContentType(mimeType);

       //3.2设置响应头:打开方式content-disposition

       //解决中文文件名问题

       //获取user-agent请求头

       Stringua=request.getHeader("user-agent");

       //使用工具类方法编码文件名即可

       filename=DownLoadUtils.getFileName(ua, filename);

       response.setHeader("content-disposition", "attachment;filename="+filename);//将文件以附件的形式弹出下载框

       //4.将输入流数据写到输出流

       ServletOutputStreamsos=response.getOutputStream();

       byte[] buff=newbyte[1024*8];

       intlen=0;

       //fis.read(buff)从此输入流中将最多buff.length个字节的数据读入一个byte数组中,如果因为已经到达文件末尾而没有更多的数据,则返回 -1

       while ((len=fis.read(buff))!=-1){

           sos.write(buff, 0, len);

       }

       fis.close();

//HTML文件

<body>

<ahref="/ggbond/downloadServlet?filename=小鸡.jpg">下载</a>

</body>

//解决中文文件名编码问题的工具类

packagecn.upeveryday.util;

importsun.misc.BASE64Encoder;

importjava.io.UnsupportedEncodingException;

importjava.net.URLEncoder;

publicclassDownLoadUtils {

   publicstaticStringgetFileName(Stringagent, Stringfilename) throwsUnsupportedEncodingException {

       if (agent.contains("MSIE")) {

           // IE浏览器

           filename=URLEncoder.encode(filename, "utf-8");

           filename=filename.replace("+", " ");

       } elseif (agent.contains("Firefox")) {

           // 火狐浏览器

           BASE64Encoderbase64Encoder=newBASE64Encoder();

           filename="=?utf-8?B?"+base64Encoder.encode(filename.getBytes("utf-8")) +"?=";

       } else {

           // 其它浏览器

           filename=URLEncoder.encode(filename, "utf-8");

       }

       returnfilename;

   }

}


目录
相关文章
|
7天前
|
存储 Java
Java中判断一个对象是否是空内容
在 Java 中,不同类型的对象其“空内容”的定义和判断方式各异。对于基本数据类型的包装类,空指对象引用为 null;字符串的空包括 null、长度为 0 或仅含空白字符,可通过 length() 和 trim() 判断;集合类通过 isEmpty() 方法检查是否无元素;数组的空则指引用为 null 或长度为 0。
|
26天前
|
Java
Java快速入门之类、对象、方法
本文简要介绍了Java快速入门中的类、对象和方法。首先,解释了类和对象的概念,类是对象的抽象,对象是类的具体实例。接着,阐述了类的定义和组成,包括属性和行为,并展示了如何创建和使用对象。然后,讨论了成员变量与局部变量的区别,强调了封装的重要性,通过`private`关键字隐藏数据并提供`get/set`方法访问。最后,介绍了构造方法的定义和重载,以及标准类的制作规范,帮助初学者理解如何构建完整的Java类。
|
25天前
|
安全 Java
Object取值转java对象
通过本文的介绍,我们了解了几种将 `Object`类型转换为Java对象的方法,包括强制类型转换、使用 `instanceof`检查类型和泛型方法等。此外,还探讨了在集合、反射和序列化等常见场景中的应用。掌握这些方法和技巧,有助于编写更健壮和类型安全的Java代码。
38 17
|
29天前
|
前端开发 Java 数据库连接
【潜意识Java】深度解读JavaWeb开发在Java学习中的重要性
深度解读JavaWeb开发在Java学习中的重要性
30 4
|
1月前
|
Java
java代码优化:判断内聚到实体对象中和构造上下文对象传递参数
通过两个常见的java后端实例场景探讨代码优化,代码不是优化出来的,而是设计出来的,我们永远不可能有专门的时间去做代码优化,优化和设计在平时
32 15
|
3月前
|
安全 Java 编译器
Java对象一定分配在堆上吗?
本文探讨了Java对象的内存分配问题,重点介绍了JVM的逃逸分析技术及其优化策略。逃逸分析能判断对象是否会在作用域外被访问,从而决定对象是否需要分配到堆上。文章详细讲解了栈上分配、标量替换和同步消除三种优化策略,并通过示例代码说明了这些技术的应用场景。
Java对象一定分配在堆上吗?
|
3月前
|
存储 缓存 NoSQL
一篇搞懂!Java对象序列化与反序列化的底层逻辑
本文介绍了Java中的序列化与反序列化,包括基本概念、应用场景、实现方式及注意事项。序列化是将对象转换为字节流,便于存储和传输;反序列化则是将字节流还原为对象。文中详细讲解了实现序列化的步骤,以及常见的反序列化失败原因和最佳实践。通过实例和代码示例,帮助读者更好地理解和应用这一重要技术。
98 0
|
3天前
|
Java 程序员 开发者
Java社招面试题:一个线程运行时发生异常会怎样?
大家好,我是小米。今天分享一个经典的 Java 面试题:线程运行时发生异常,程序会怎样处理?此问题考察 Java 线程和异常处理机制的理解。线程发生异常,默认会导致线程终止,但可以通过 try-catch 捕获并处理,避免影响其他线程。未捕获的异常可通过 Thread.UncaughtExceptionHandler 处理。线程池中的异常会被自动处理,不影响任务执行。希望这篇文章能帮助你深入理解 Java 线程异常处理机制,为面试做好准备。如果你觉得有帮助,欢迎收藏、转发!
39 14
|
6天前
|
安全 Java 程序员
Java 面试必问!线程构造方法和静态块的执行线程到底是谁?
大家好,我是小米。今天聊聊Java多线程面试题:线程类的构造方法和静态块是由哪个线程调用的?构造方法由创建线程实例的主线程调用,静态块在类加载时由主线程调用。理解这些细节有助于掌握Java多线程机制。下期再见! 简介: 本文通过一个常见的Java多线程面试题,详细讲解了线程类的构造方法和静态块是由哪个线程调用的。构造方法由创建线程实例的主线程调用,静态块在类加载时由主线程调用。理解这些细节对掌握Java多线程编程至关重要。
35 13
|
7天前
|
安全 Java 开发者
【JAVA】封装多线程原理
Java 中的多线程封装旨在简化使用、提高安全性和增强可维护性。通过抽象和隐藏底层细节,提供简洁接口。常见封装方式包括基于 Runnable 和 Callable 接口的任务封装,以及线程池的封装。Runnable 适用于无返回值任务,Callable 支持有返回值任务。线程池(如 ExecutorService)则用于管理和复用线程,减少性能开销。示例代码展示了如何实现这些封装,使多线程编程更加高效和安全。