Javaweb之Request对象与ServletContext对象

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文件中的超链接

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

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

http://localhost:8080/springmvc01/

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

http://localhost:8080/springmvc01/hello

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

1.HTML文件中的超链接

<a href="/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.获取字符输出流

       PrintWriter writer = response.getWriter();

       //2.输出数据

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

8. 服务器输出字节流

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

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

       //1.获取字节输出流

       ServletOutputStream sos = response.getOutputStream();

       //2.输出数据

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

9. 验证码

        int width=100;

       int height=50;

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

       BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

       //2.美化图片

       //2.1填充背景色

       Graphics g = 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画验证码

       String str="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

       Random ran = new Random();

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

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

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

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

       }

       //2.4画干扰线

       g.setColor(Color.GREEN);

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

           int x1 = ran.nextInt(width);

           int x2 = ran.nextInt(width);

           int y1 = ran.nextInt(height);

           int y2 = ran.nextInt(height);

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

       }

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

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

<script>

   window.onload=function (){

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

       var a=document.getElementById(`a`);

       var image=document.getElementById("image");

       //绑定单机事件

       a.onclick=function () {

           //加时间戳

           var date=new Date().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/html image/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.获取请求参数:文件名称

       String filename = request.getParameter("filename");

       System.out.println(filename);

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

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

       ServletContext servletContext = this.getServletContext();

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

       //2.2用字节流关联

       FileInputStream fis = new FileInputStream(path);

       //3.设置response的响应头

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

       String mimeType = servletContext.getMimeType(filename);

       response.setContentType(mimeType);

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

       //解决中文文件名问题

       //获取user-agent请求头

       String ua = request.getHeader("user-agent");

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

       filename = DownLoadUtils.getFileName(ua, filename);

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

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

       ServletOutputStream sos = response.getOutputStream();

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

       int len=0;

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

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

           sos.write(buff, 0, len);

       }

       fis.close();

//HTML文件

<body>

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

</body>

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

package cn.upeveryday.util;

import sun.misc.BASE64Encoder;

import java.io.UnsupportedEncodingException;

import java.net.URLEncoder;

public class DownLoadUtils {

   public static String getFileName(String agent, String filename) throws UnsupportedEncodingException {

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

           // IE浏览器

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

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

       } else if (agent.contains("Firefox")) {

           // 火狐浏览器

           BASE64Encoder base64Encoder = new BASE64Encoder();

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

       } else {

           // 其它浏览器

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

       }

       return filename;

   }

}


上一篇:Linux 文件目录特殊权限设定(SUID,SGID,SBIT)


下一篇:swiper7-1.初始化配置