【java web篇】Servlet处理请求和响应
创始人
2025-06-01 07:48:49

📋 个人简介

  • 💖 作者简介:大家好,我是阿牛,全栈领域优质创作者。😜
  • 📝 个人主页:馆主阿牛🔥
  • 🎉 支持我:点赞👍+收藏⭐️+留言📝
  • 📣 系列专栏:java 小白到高手的蜕变🍁
  • 💬格言:要成为光,因为有怕黑的人!🔥
    请添加图片描述

目录

    • 📋 个人简介
  • 前言
    • Request
      • Request 继承体系
      • Request 获取请求参数
      • 获取请求参数的通用方式
      • Request 请求转发
    • Response
      • Response继承体系
      • Response 设置响应数据功能
      • Respones 请求重定向
      • 请求转发和重定向的区别
      • Response 响应数据
  • 结语

前言

web开发最重要的之一不就是处理请求与响应吗,那么这节就来总结Servlet是如何处理的,在请求与响应这块基本都差不多,浅浅的过一下!

Request

request:获取请求数据

  • 浏览器会发送HTTP请求到后台服务器[Tomcat]
  • HTTP的请求中会包含很多请求数据[请求行+请求头+请求体]
  • 后台服务器[Tomcat]会对HTTP请求中的数据进行解析并把解析结果存入到一个对象中
  • 所存入的对象即为request对象,所以我们可以从request对象中获取请求的相关参数
  • 获取到数据后就可以继续后续的业务,比如获取用户名和密码就可以实现登录操作的相关业务!

Request 继承体系

在这里插入图片描述
所以ServletRequest和HttpServletRequest是继承关系,并且两个都是接口,接口是无法创建。
对象,这个时候就引发了下面这个问题:
在这里插入图片描述
这个时候,我们就需要用到Request继承体系中的RequestFacade :

  • 该类实现了HttpServletRequest接口,也间接实现了ServletRequest接口。
  • Servlet类中的service方法、doGet方法或者是doPost方法最终都是由Web服务器[Tomcat]来调用的,所以Tomcat提供了方法参数接口的具体实现类,并完成了对象的创建。
  • 要想了解RequestFacade中都提供了哪些方法,我们可以直接查看JavaEE的API文档中关于ServletRequest和HttpServletRequest的接口文档,因为RequestFacade实现了其接口就需要重写接口中的方法。

所以,你可以打印这个参数resquest,可以看到这个对象是由RequestFacade创建的!

Request 获取请求参数

1.请求行包含三块内容,分别是请求方式、请求资源路径、HTTP协议及版本
在这里插入图片描述
对于这三部分内容,request对象都提供了对应的API方法来获取!

2.对于请求头的数据,格式为key: value如下:
在这里插入图片描述
3.获取请求体数据
浏览器在发送GET请求的时候是没有请求体的,所以需要把请求方式变更为POST!
对于请求体中的数据,Request对象提供了如下两种方式来获取其中的数据,分别是:
获取字节输入流,如果前端发送的是字节数据,比如传递的是文件数据,则使用该方法:

ServletInputStream getInputStream()

获取字符输入流,如果前端发送的是纯文本数据,则使用该方法:

BufferedReader getReader()

以上java代码如下:

@WebServlet("/req1")
public class RequestDemo1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// String getMethod():获取请求方式: GETString method = req.getMethod();System.out.println(method);//GET// String getContextPath():获取虚拟目录(项目访问路径):/request-demoString contextPath = req.getContextPath();System.out.println(contextPath);// StringBuffer getRequestURL(): 获取URL(统一资源定位符):http://localhost:8080/request-demo/req1StringBuffer url = req.getRequestURL();System.out.println(url.toString());// String getRequestURI():获取URI(统一资源标识符): /request-demo/req1String uri = req.getRequestURI();System.out.println(uri);// String getQueryString():获取请求参数(GET方式): username=zhangsanString queryString = req.getQueryString();System.out.println(queryString);//------------// 获取请求头:user-agent: 浏览器的版本信息String agent = req.getHeader("user-agent");System.out.println(agent);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取post 请求体:请求参数//1. 获取字符输入流BufferedReader br = req.getReader();//2. 读取数据String line = br.readLine();System.out.println(line);}
}

对于post请求,可以写一个html表单测试!

获取请求参数的通用方式

对于请求参数的获取,常用的有以下两种:

GET:

String getQueryString()

POST:

BufferedReader getReader();

但通常情况写,有可能我们get或post处理的业务逻辑是相同的,但请求方式有不同,怎么办呢?

在这里插入图片描述
当然,也可以在doGet中调用doPost,在doPost中完成参数的获取和打印,另外需要注意的是,doGet和doPost方法都必须存在,不能删除任意一个。
GET请求和POST请求获取请求参数的方式不一样,在获取请求参数这块该如何实现呢?要想实现,我们就需要思考:
GET请求方式和POST请求方式区别主要在于获取请求参数的方式不一样,是否可以提供一种统一获取请求参数的方式,从而统一doGet和doPost方法内的代码?

解决方法一:

在这里插入图片描述

这样不就好了,但是以后每个Servlet我们都要这样这样写,还是麻烦!

解决方案二:
request对象已经将上述获取请求参数的方法进行了封装,并且request提供的方法实现的功能更强大,以后只需要调用request提供的方法即可,在request的方法中都实现了哪些操作呢?

在这里插入图片描述
如图,request将获取到的内容进行分割,然后将分割后的数据存到Map集合中!
在这里插入图片描述
基于此,request提供了以下api,直接上案例代码了哦:

package com.aniu;import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.util.Map;/*** request 通用方式获取请求参数*/
@WebServlet("/demo3")
public class ServletDemo3 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//GET请求逻辑System.out.println("get....");//1. 获取所有参数的Map集合Map map = req.getParameterMap();for (String key : map.keySet()) {// 例如username:zhangsan lisiSystem.out.print(key+":");//获取值,遍历数组String[] values = map.get(key);for (String value : values) {System.out.print(value + " ");}System.out.println();  //换行}System.out.println("------------");//2. 根据key获取参数值,数组String[] hobbies = req.getParameterValues("hobby");for (String hobby : hobbies) {System.out.println(hobby);}//3. 根据key 获取单个参数值String username = req.getParameter("username");String password = req.getParameter("password");System.out.println(username);System.out.println(password);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//POST请求逻辑System.out.println("post...");this.doGet(req,resp);}
}

b.html



Title




游泳 爬山

在这里插入图片描述
可以看到出现汉字乱码问题!
解决请看:
https://guanzhu-aniu.blog.csdn.net/article/details/129466518

Request 请求转发

请求转发(forward):一种在服务器内部的资源跳转方式。
在这里插入图片描述

(1)浏览器发送请求给服务器,服务器中对应的资源A接收到请求
(2)资源A处理完请求后将请求发给资源B
(3)资源B处理完后将结果响应给浏览器
(4)请求从资源A到资源B的过程就叫请求转发

@WebServlet("/req5")
public class RequestDemo5 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("demo5...");//存储数据request.setAttribute("msg","hello");// 请求转发request.getRequestDispatcher("/req6").forward(request,response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}
}
@WebServlet("/req6")
public class RequestDemo6 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("demo6...");//获取数据Object msg = request.getAttribute("msg");System.out.println(msg);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}
}

Response

response:设置响应数据

  • 业务处理完后,后台就需要给前端返回业务处理的结果即响应数据
  • 把响应数据封装到response对象中
  • 后台服务器[Tomcat]会解析response对象,按照[响应行+响应头+响应体]格式拼接结果
  • 浏览器最终解析结果,把内容展示在浏览器给用户浏览

Response继承体系

在这里插入图片描述

Response 设置响应数据功能

HTTP响应数据总共分为三部分内容,分别是响应行、响应头、响应体,对于这三部分内容的数据,
respone对象都提供了方法来进行设置。

1.响应行

对于响应头,比较常用的就是设置响应状态码:

void setStatus(int sc);

2.响应头

设置响应头键值对:

void setHeader(String name,String value);

3.响应体

对于响应体,是通过字符、字节输出流的方式往浏览器写,
获取字符输出流:

PrintWriter getWriter();

获取字节输出流

ServletOutputStream getOutputStream();

Respones 请求重定向

Response重定向(redirect):一种资源跳转方式。
在这里插入图片描述

(1)浏览器发送请求给服务器,服务器中对应的资源A接收到请求
(2)资源A现在无法处理该请求,就会给浏览器响应一个302的状态码+location的一个访问资源B的
路径
(3)浏览器接收到响应状态码为302就会重新发送请求到location对应的访问地址去访问资源B
(4)资源B接收到请求后进行处理并最终给浏览器响应结果,这整个过程就叫重定向

重定向方法一:

resp.setStatus(302);
resp.setHeader("location","资源访问路径");

重定向方法二:

//重定向
resposne.sendRedirect("资源访问路径");

请求转发和重定向的区别

在这里插入图片描述

Response 响应数据

响应字符数据:

//设置响应的数据格式及数据的编码
response.setContentType("text/html;charset=utf-8");
writer.write("你好");

响应字节数据:

1.通过Response对象获取字节输出流:

ServletOutputStream outputStream = resp.getOutputStream();

2.通过字节输出流写数据:

outputStream.write(字节数据);
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1. 读取文件FileInputStream fis = new FileInputStream("d://a.jpg");//2. 获取response字节输出流ServletOutputStream os = response.getOutputStream();//3. 完成流的copybyte[] buff = new byte[1024];int len = 0;while ((len = fis.read(buff))!= -1){os.write(buff,0,len);}fis.close();
}

结语

如果你觉得博主写的还不错的话,可以关注一下当前专栏,博主会更完这个系列的哦!也欢迎订阅博主的其他好的专栏。

🏰系列专栏
👉软磨 css
👉硬泡 javascript
👉flask框架快速入门

相关内容

热门资讯

分享实测“哪吒重生到底有透视挂... 您好:哪吒重生这款游戏可以开挂,确实是有挂的,需要软件加微信【5951795】,很多玩家在哪吒重生这...
玩家必备“神皇辅助工具有挂”!... 亲,神皇这款游戏可以开挂的,确实是有挂的,很多玩家在这款游戏中打牌都会发现很多用户的牌特别好,总是好...
玩家亲测(鱼扑克)外挂透明挂辅... 你好.鱼扑克这款游戏可以开挂的,确实是有挂的,很多玩家在这款游戏中打牌都会发现很多用户的牌特别好,总...
科普实测“白金岛手游放炮罚透视... 您好:白金岛手游放炮罚这款游戏可以开挂,确实是有挂的,需要软件加微信【5951795】,很多玩家在白...
玩家亲测(线上德州WPK)外挂... 玩家亲测(线上德州WPK)外挂透明挂辅助黑科技,太坑了确实是有挂的(有挂技巧)-哔哩哔哩亲,有的,a...