学习Request和Response这一篇就够啦~2

简介: 学习Request和Response这一篇就够啦~

运行后在网页中输入如下内容:

点击回车,我们发现这里并没有显示我们刚输入的值,则证明为post请求方式:

控制台输出:

验证成功说明上述方法对于post请求和get请求均适用!

既然代码都是完全相同的,那么我们不必同样的代码书写两边,修改如下:

//当为post请求方式时,我们只需要调用doget方法
this.doGet(req,resp);

验证如下:

运行后在网页中输入如下内容:

回车,确实为post请求方式:

控制台输出:

这样也能够正确使用不同的请求方式,并且这种方式代码量更少!

解决中文乱码问题:

当我们在表单中填写的值为中文时,会出现乱码问题,而这种乱码问题与请求方式是没有关系的,无论是post还是get都会出现乱码问题

举例:

控制台输出:

解决POST请求方式出现的乱码问题:使用setCharacterEncoding设置字符输入流

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 Myservlet4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
    //一定要写在第一行!!!
        req.setCharacterEncoding("UTF-8");//设置字符输入流的编码
        String username=req.getParameter("username");
        System.out.println(username);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            this.doGet(req,resp);
    }
}

乱码问题被解决:

如果还没有解决的小伙伴请检查自己web文件中的请求方式是不是错写成get了,或者可以试试设置为GBK

解决GET请求方式出现的乱码问题:

如下所示:

<configuration>
            <uriEncoding>${project.build.sourceEncoding}</uriEncoding>
</configuration>
Request请求转发:

请求转发[forword]:一种在服务器内部的资源跳转方式

实现方式:req.getRequestDispatcher("资源B路径").forword(req,resp);

举例:

新创建Myservlet5类:

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("/demo5")
    public class Myservlet5 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("demo5.............");
            //请求转发---我们所能改变的内容为转发的资源路径,也就是下一个要执行的servlet类
            req.getRequestDispatcher("/demo6").forward(req,resp);
        }
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            this.doGet(req,resp);
        }
    }

新创建Myservlet6类:

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("/demo6")
public class Myservlet6 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("demo6.............");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

打开浏览器访问demo5,控制台输出如下:

请求转发资源共享数据,使用Request对象:

void setAttribute(String name,Object o):存储数据到request域中
Object getAttribute(String name):根据key,获取值
void removeAttribute(String name):根据key,删除该键值对

在上述创建的Myservlet5和Myservlet6的基础上进行如下步骤:

举例:

1:在Myservlet5中添加数据

在Myservlet6中添加下述代码:


打开浏览器访问demo5,控制台输出:

请求转发特点:

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

Response(响应):

Response:设置响应数据功能介绍

响应数据分为3部分:

1:响应行:HTTP/1.1 200 OK

void setStatus(int sc):设置响应状态码

2:响应头:Content-Type:text/html

void setHeader(String name,String value):设置响应头键值对

3:响应体<html><head><head><body></body></html>

PrintWriter getWriter():获取字符输出流
ServeltOutputStream getOutputStream():获取字节输出流

重定向:一种资源跳转方式

实现方式:

resp.setStatus(302);
resp.setHeader("location","资源B的路径");

举例:

创建MyResponse1类:

package 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("/res1")
public class MyResponse1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                System.out.println("res1..........");
        //重定向
        //1:设置响应状态码:302
       resp.setStatus(302);
        //设置响应头Location
        resp.setHeader("Location","res2");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }

创建MyResponse2类:

package 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("/res2")
public class MyResponse2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("res2..........");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

当在浏览器访问res1:

回车,重定向至res2:

控制台输出:

如果有小伙伴的控制台只输出了res1,如下所示:

错误的原因为:响应头的路径书写错误,有可能是多加了“/”,有可能是忘记写虚拟路径,也就是项目的名称,我这里没写项目名称的原因是因为我的IDE为2021版本的,可以直接写另一个资源的名称

resp.setHeader("Location","res2");

除了上述方法可以进行重定向外,我们还可以使用下述这种简化的方式进行重定向,这种方法的输出结果上述完全相同

resp.sendRedirect("res2");

重定向的特点:

1:浏览器地址栏路径发生变化—>在上述案例中我们已经指出了

2:可以重定向到任意位置的资源(服务器内部,外部均可)

上述案例的资源即为服务器内部,我们也可以将其定位到服务器外部,如下所示,我们将重定向的路径定位至百度:

resp.sendRedirect("https://www.baidu.com/");

浏览器依然访问res1资源:

点击回车,浏览器地址栏路径发生不仅变为了百度的网址,而且页面也是跳转到了百度

3:两次请求,不能在多个资源使用request共享数据

由于浏览器发送了两次请求,是两个不同的request对象,就无法通过request对象进行共享数据

Resopnse响应字符数据:

使用:

1:通过Response对象获得字符输出流

PrintWriter writer=resp.getWriter();

2:写数据

writer.writer("aaa");

举例:

新建servlet类:

package 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;
import java.io.PrintWriter;
@WebServlet("/res3")
public class MyResponse3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         //获取字符输出流
         //该流不需要关闭,当最后程序结束时,response对象被销毁的时候,该流自动关闭
        PrintWriter writer=resp.getWriter();
        writer.write("aaa");
        writer.write("<h1>aaa</h1>");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

浏览器打开运行:

这样看似好像没什么问题,但仔细看,我们写入的<h1>aaa<h1>的标签本质是想将其以标题的形式显示,但是这里并非如此,而是将其按照文本直接输出了,针对上述问题,解决方法如下:

//将其解析为html文件
resp.setHeader("content-type","text/html");

显示如下:

解决中文乱码问题:

上述实例中,我们所写的字符都是英文的,那么如果是中文的,会出现乱码问题吗?

测试如下:

writer.write("你好");

输出如下所示:

我们看到,你好此时被解析为了两个问号

针对上述问题的解决方法如下:

在doGET方法的第一行加入下述代码:

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

输出如下:乱码被解决

Resopnse响应字节数据:

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

ServletOutputStream outputStream=resp.getOutputStream();

2:写数据

outputStream.write(字节数据);

举例:

package Response;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
@WebServlet("/res4")
public class MyResponse4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //读取文件
        FileInputStream fileInputStream = new FileInputStream("E://开心的微笑.jpg");
        //获取response字节输出流
        ServletOutputStream os = resp.getOutputStream();
        //完成流的copy
        byte[] buff = new byte[1024];
        int len = 0;
        while ((len = fileInputStream.read(buff)) != -1) {
            os.write(buff, 0, len);
        }
        fileInputStream.close();
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

访问res4资源,显示如下:

上述流的copy只是为了巩固基础,为了简化代码,我们可以直接使用工具类,步骤如下:

首先在pom.xml文件中导入下述依赖:

<dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.6</version>
</dependency>

2:将上述中流copy的部分改为下述代码:

IOUtils.copy(fileInputStream,os);

在浏览器中再次访问res4资源,发现依然可以成功输出,但下述这种方式明显简单许多:

相关文章
|
5月前
|
编解码 应用服务中间件
技术笔记:Resonse9_Response对象2
技术笔记:Resonse9_Response对象2
|
6月前
|
存储 前端开发 Java
JavaWeb:Request & Response
在JavaWeb开发中,Request(请求)和Response(响应)是非常重要的概念。它们分别代表着客户端向服务器发送请求和服务器向客户端返回响应的过程。Request对象是由服务器创建的,用于封装来自客户端的请求信息。它包含了请求的HTTP方法(如GET或POST),URL,请求头部、参数等信息。你可以通过Request对象获取客户端发送的表单数据、URL参数、HTTP头部和Cookies等。Response对象则是服务器用来向客户端发送响应的工具。它包含了HTTP状态码、响应头部和响应体等信息。你可以使用Response对象设置响应的状态码、设置响应头部
81 3
 JavaWeb:Request & Response
|
Web App开发 Java 应用服务中间件
学习Request和Response这一篇就够啦~1
学习Request和Response这一篇就够啦~
|
前端开发 Java 应用服务中间件
细谈JavaWeb中的Request和Response
request:获取请求数据 浏览器会发送HTTP请求到后台服务器[Tomcat] HTTP的请求中会包含很多请求数据[请求行+请求头+请求体] 后台服务器[Tomcat]会对HTTP请求中的数据进行解析并把解析结果存入到一个对象中 所存入的对象即为request对象,所以我们可以从request对象中获取请求的相关参数 获取到数据后就可以继续后续的业务,比如获取用户名和密码就可以实现登录操作的相关业务
285 0
|
SQL 前端开发 Java
🤓 Request&Response(三)
🤓 Request&Response(三)
101 0
|
存储 前端开发 Java
🤓 Request&Response(二)
🤓 Request&Response
119 0
|
前端开发 Java 应用服务中间件
🤓 Request&Response(一)
🤓 Request&Response
79 0
|
存储 前端开发 Java
《JavaWeb篇》08.Request&Response看这一篇就够了(二)
《JavaWeb篇》08.Request&Response看这一篇就够了(二)
298 0
《JavaWeb篇》08.Request&Response看这一篇就够了(二)
|
前端开发 Java 应用服务中间件
《JavaWeb篇》08.Request&Response看这一篇就够了(一)
《JavaWeb篇》08.Request&Response看这一篇就够了(一)
252 0
《JavaWeb篇》08.Request&Response看这一篇就够了(一)
|
SQL 前端开发 Java
《JavaWeb篇》08.Request&Response看这一篇就够了(三)
《JavaWeb篇》08.Request&Response看这一篇就够了(三)
106 0
《JavaWeb篇》08.Request&Response看这一篇就够了(三)