web开发最重要的之一不就是处理请求与响应吗,那么这节就来总结Servlet是如何处理的,在请求与响应这块基本都差不多,浅浅的过一下!
request:获取请求数据
所以ServletRequest和HttpServletRequest是继承关系,并且两个都是接口,接口是无法创建。
对象,这个时候就引发了下面这个问题:
这个时候,我们就需要用到Request继承体系中的RequestFacade :
所以,你可以打印这个参数resquest,可以看到这个对象是由RequestFacade创建的!
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
请求转发(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:设置响应数据
HTTP响应数据总共分为三部分内容,分别是响应行、响应头、响应体,对于这三部分内容的数据,
respone对象都提供了方法来进行设置。
1.响应行
对于响应头,比较常用的就是设置响应状态码:
void setStatus(int sc);
2.响应头
设置响应头键值对:
void setHeader(String name,String value);
3.响应体
对于响应体,是通过字符、字节输出流的方式往浏览器写,
获取字符输出流:
PrintWriter getWriter();
获取字节输出流
ServletOutputStream getOutputStream();
Response重定向(redirect):一种资源跳转方式。
(1)浏览器发送请求给服务器,服务器中对应的资源A接收到请求
(2)资源A现在无法处理该请求,就会给浏览器响应一个302的状态码+location的一个访问资源B的
路径
(3)浏览器接收到响应状态码为302就会重新发送请求到location对应的访问地址去访问资源B
(4)资源B接收到请求后进行处理并最终给浏览器响应结果,这整个过程就叫重定向
重定向方法一:
resp.setStatus(302);
resp.setHeader("location","资源访问路径");
重定向方法二:
//重定向
resposne.sendRedirect("资源访问路径");
响应字符数据:
//设置响应的数据格式及数据的编码
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框架快速入门