Request和Response对象

Request和Response都是Servlet的service方法的参数,Request负责获取请求数据,而Response负责设置相应数据~


一.Request

1.继承体系

Tomcat负责解析数据,因此由Tomcat来提供实现类~

2.获取请求数据

  • 请求行
  • 请求头
  • 请求体

需要注意的是只有Post方法才有请求体。因此请求体的方法应该写到Servlet的doPost方法中~

3.通用方式获取请求参数

尝试一下,先写一个用户表单:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
  <form action="//Servlet_F1_war/demo2" >
    <input type="text" name="username"><br/>
    <input type="password" name="password"><br/>
      <input type="checkbox" name="gender" value="男">男<br/>
    <input type="checkbox" name="gender" value="女">女<br/>
    <input type="submit" ><br/>
  </form>
</body>
</html>

注意, 第一个斜杠后面是项目的访问路径(也就是名称),第二个是自愿路径(这里是一个Servlet的注解!)

Servlet的代码如下(只演示第一个方法:)

java 复制代码
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("此时调用的是get方法~");
        Map<String,String[]> map = req.getParameterMap();
        //键入:iter 快速遍历
        for (String key : map.keySet()) {
            System.out.print(key+" ");
            String[] values = map.get(key);
            for(String value : values)
            {
                System.out.print(value + ",");
            }
            System.out.println();
        }
    }

Get方法将参数提交到Url里面:

打印成功:

然后将表单的提交方式改为post,doGet方法修改如下:

java 复制代码
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String m =req.getMethod();
        System.out.println("此时调用的是"+m+"方法~");
        Map<String,String[]> map = req.getParameterMap();
        //键入:iter 快速遍历
        for (String key : map.keySet()) {
            System.out.print(key+" ");
            String[] values = map.get(key);
            for(String value : values)
            {
                System.out.print(value + ",");
            }
            System.out.println();
        }
    }

然后doPost直接调用doGet:

java 复制代码
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }

post方法将参数隐藏在请求体中:

请求成功(中文有些乱码,暂时忽略):

完整的代码如下,经供参考:

java 复制代码
package Myweb;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

@WebServlet("/demo2")
public class ServletDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String m =req.getMethod();
        System.out.println("此时调用的是"+m+"方法~");
        Map<String,String[]> map = req.getParameterMap();
        //键入:iter 快速遍历
        for (String key : map.keySet()) {
            System.out.print(key+" ");
            String[] values = map.get(key);
            for(String value : values)
            {
                System.out.print(value + ",");
            }
            System.out.println();
        }
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

4.解决乱码

post的解决非常简单,只需要如下代码设置字符流的输入编码,即可完美解决:

java 复制代码
req.setCharacterEncoding("UTF-8");

搞定~

对于汉字类型的数据,在get方式中会通过Url编码变为16进制数据。乱码的原因是Tomcat在解码时默认使用ISO-8859-1。这里给出一个通用的方式,假设中文数据的名称为username:

java 复制代码
username = new String(username.getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8);

也可以解决post方式。

不过,Tomcat8版本之后已经默认解决了GET方式乱码的问题,大家不需要操心~

5.请求转发

一种在服务器内部的资源跳转方式。

新建Servlet3号和4号如下:

java 复制代码
package Myweb;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/demo3")
public class ServletDemo3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("使用的是Servlet3号~");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
java 复制代码
package Myweb;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/demo4")
public class ServletDemo4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("使用的是Servlet4号~");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

在Servlet3中书写请求转发到Servlet4的代码:

java 复制代码
req.getRequestDispatcher("/demo4").forward(req,resp);

访问Servlet3成功后,Servlet4也会一起成功:

请求转发的特点:

  • 浏览器地址栏路径不发生变化
  • 只能转发到当前服务器的内部资源
  • 一次请求可以在转发的资源间使用request共享数据

二.Response

1.设置响应数据

2.完成重定向

重定向是一种资源跳转方式。状态码是:302。 位置的格式是**:响应头Location:xxx**

定义两个Servlet:

java 复制代码
package Myweb.Response;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/respd1")
public class RespDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("访问的是Response1~");
        resp.setStatus(302);
        resp.setHeader("Location","/Servlet_F1_war/respd2");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
java 复制代码
package Myweb.Response;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/respd2")
public class RespDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      System.out.println("重定向的Resp2也被访问了~");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

虚拟路径一定要写对,这是易错点。

如上,访问1号2号也会被重定向~

java 复制代码
resp.sendRedirect("/Servlet_F1_war/respd2");

如上是一种简化写法。

重定向的特点:

  • 浏览器地址栏路径发生变化
  • 可以重定向到任意位置的资源(服务器内部、外部均可)
  • 两次请求,不能在多个资源使用request共享数据

重定向与请求转发的特点完全相反~

针对于虚拟路径:

  • 浏览器使用:需要加虚拟目录(项目访问路径)
  • 服务端使用:不需要加虚拟目录
java 复制代码
String contextPath = request.getContextPath();
response.sendRedirect(contextPath+"/resp2");

如上是动态配置虚拟目录的方式~

3.响应字符数据

java 复制代码
        PrintWriter writer=resp.getWriter();
//获取字符输出流
        writer.write("啦啦啦~");
        writer.write("<h1>HELLO</h1>");

通过Response对象获取字符输出流,并写出数据~

存在乱码现象,且按照普通文本的读取方式~

java 复制代码
resp.setContentType("text/html;charset=UTF-8");

设置头的解析方式,并设置流的编码为UTF-8。

成功。

(流不需要关闭,Response对象销毁后服务器会将其自动关闭~)

4.响应字节数据

XML 复制代码
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>

引入工具类坐标。

java 复制代码
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      //1、读取文件
        FileInputStream fis=new FileInputStream("E:\\照片//德拜.jpg");
      //2、获取字节输出流
        ServletOutputStream os = resp.getOutputStream();
      //3、完成流的复制
        IOUtils.copy(fis,os);
    }

如上。

即可成功读取图片~

相关推荐
多多*12 分钟前
OJ在线评测系统 登录页面开发 前端后端联调实现全栈开发
linux·服务器·前端·ubuntu·docker·前端框架
hai4058714 分钟前
Spring Boot中的响应与分层解耦架构
spring boot·后端·架构
卑微的码蚁15 分钟前
服务器相关问题
运维·服务器
博洋科技16 分钟前
网站建设的服务器该如何选择?
运维·服务器·网站建设·保定响应式网站建设·保定h5网站建设·保定网站建设
人类群星闪耀时21 分钟前
服务器管理:从零开始的服务器安装与配置指南
运维·服务器
陈大爷(有低保)33 分钟前
UDP Socket聊天室(Java)
java·网络协议·udp
kinlon.liu1 小时前
零信任安全架构--持续验证
java·安全·安全架构·mfa·持续验证
王哲晓1 小时前
Linux通过yum安装Docker
java·linux·docker
java6666688881 小时前
如何在Java中实现高效的对象映射:Dozer与MapStruct的比较与优化
java·开发语言
Violet永存1 小时前
源码分析:LinkedList
java·开发语言