javaweb入门(一)——servlet-05-Response学习

本文介绍了Java中HttpServletResponse类的作用,区分了getWriter()和getOutputStream()的区别,以及如何设置响应头、状态码和实现文件下载功能。

HttpServletResponse

web服务器接收到客户端的http请求之后,针对于这个请求,web服务器会创建两个类HttpServletRequest以及HtppServletResponse,其中HttpServletRequest来代表请求HttpServletResponse用来代表响应
对于这两个类我们要记住:

  • 如果我们想要获取客户端传来的请求参数,我们需要找的类是HttpServletRequest
  • 如果我们想要给客户端响应信息,我们需要找的类是HttpServletResponse

对于HttpServletResponse类,我们习惯于称之为Response,也即响应类

对HttpServletResponse类中方法的一些简单分类

我们学习一个类最直接有效的方法就是先看他的代码,查看其中具体都有哪些方法,搞明白这些方法的功能都是什么。
首先我们看HttpServletResponse类,我们可以发现它继承的是ServletResponse接口。

我们可以发现,这些方法大多都是get、set以及add方法。那么我们可以将这些方法做一个简单的归类。

负责向服务器发送数据的方法

//	只可以输出字符流数据,即只可以输出字符串
    PrintWriter getWriter() throws IOException;
//	可以输出字符流数据和字节流数据,即字符串和二进制字节流
    ServletOutputStream getOutputStream() throws IOException;

这两个类都是用于获取向服务器输出数据的输出流
我们需要注意的是:
1.getWriter()方法用于输出字符流数据getOutputStream()方法用于输出字节流数据
在这里和大家解释一下什么是字节流数据字符流数据
字节流数据其实就是二进制数据,它是以字节为单位,即在很多类中都有的getBytes()方法便是将此类转换为字节流。
字符流数据其实就是我们常用的字符串,它是以字符为单位,例如我们经常使用的String类。

为了更好地理解这两个类,我们可以编写一个案例。

测试getWriter()的Servlet:

package com.kuang.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;

public class WriterServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        由于我们的message中有中文,为了防止乱码,所以要对ContentType进行设置
        resp.setContentType("text/html;charset=UTF-8");
//        获取Writer输出流
        PrintWriter writer = resp.getWriter();
        String message = "你好,我是BugMaker2000";
//      将数据使用输出流输出
        writer.write(message);
    }

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

测试getOutputStream()的Servlet:

package com.kuang.servlet;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class OutputStreamServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        对resp的ContextType设置
        resp.setContentType("text/html;charset=UTF-8");
//      获取输出流
        ServletOutputStream os = resp.getOutputStream();
        String message = "大家好,我是BugMaker2000 ";
//      这里在测试时,我发现resp中设置的字符字符标准对outputStream无效
        os.write(message.getBytes());
//      当我们需要outputsStream输出数据时候,我们需要在此设置字节流的标准
        os.write(message.getBytes(StandardCharsets.UTF_8));
    }

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

测试结果:
getWriter()的测试结果
在这里插入图片描述
getOutputStream()的测试结果
在这里插入图片描述
通过本次案例我们可以更加直观的了解到两个输出流之间功能上的差别:Writer更加注重字符的输出,OutputStream更加注重对字节的输出。

OutputStreamServlet类中尽管我们在输出流输出之前对response的ContextType中的字符进行了设置,但是outputStream输出的字节流依然是乱码。只用我们在os.write()中设置好字节流的编码格式输出的中文字符才不会变成乱码。

  1. 一个serlvet中的输出流可以选择Writer或者outputStream两者其中一种
    在一个输出流创建完毕之后,它就会随着response发送到客户端,在客户端接收之后,服务器就会自动关闭response中没有关闭的输出流

负责向浏览器发送响应头的方法

	//这些是 SerlvetResponse的方法
	void setCharacterEncoding(String var1);

    void setContentLength(int var1);

    void setContentLengthLong(long var1);

    void setContentType(String var1);

	//这些是HttpServletResponse的方法
	void setDateHeader(String var1, long var2);

    void addDateHeader(String var1, long var2);

    void setHeader(String var1, String var2);

    void addHeader(String var1, String var2);

    void setIntHeader(String var1, int var2);

    void addIntHeader(String var1, int var2);

设置响应的状态码

	void setStatus(int var1);

关于状态码,我们只需要记住:

  • 200表示响应成功
  • 3XX表示请求重定向
  • 4XX表示找不到资源
  • 5XX表示服务器代码错误

Response常见的应用——下载文件

一般来说我们使用response应用为:向客户端输出消息,客户端下载文件。其实这两个应用的本质都是客户端通过response类获取服务器传来的数据
我们此处详细讲解一下response完成下载文件的功能。
客户端下载文件,我们需要完成一下几步:
1.设置响应头,使得客户端可以接收下载文件
2.获取文件输入流
3.获取servlet的输出流
4.创建缓冲区,通过缓冲区将文件输出流写入输出流(返回给客户端)
(5.关闭流,我们十分提倡我们自己关闭输入/输出流
完成的类:

package com.kuang.servlet;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class FileDownServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

//        1.设置浏览器可以接收下载的文件
        resp.setHeader("Content-Disposition","attachment;filename=1.png");
//        2.获取文件作为输入流
        InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/1.jpeg");
//        3.获取输出流
        ServletOutputStream os = resp.getOutputStream();
//        4.创建缓冲区,通过缓冲区将文件输入流写入响应输出
        byte[] buffer = new byte[1024];
        int len = 0;
        while((len = is.read(buffer)) > 0){
//            将文件输出给客户端
            os.write(buffer,0,len);
        }
//        关闭流
        is.close();
        os.close();
    }

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

实现结果:
当我们运行下载文件的serlvet之后,浏览器就会新建下载任务
在这里插入图片描述
关于这个案例,我们需要知道这些知识点:
1.关于设置浏览器下载文件的语句

        resp.setHeader("Content-Disposition","attachment;filename=1.png");

只有在我们设置了响应头之后,浏览器才会出现新建下载任务的窗口,否则浏览器只会展示图片。要注意其中的filename=1.pngfilename=之后的内容是根据我们需要下载的文件名而改变的。
2.获取文件作为输入流
我们需要知道,获取文件作为输入流不仅仅可以通过ServletContext.getResourceAsStream来完成。我们也可通过new一个FileInputStream来完成。

FileInputStream fis = new FileInputStream(filepath);//参数是文件路径

3.关于文件输入流的输入方法inputStream.read()
我们把文件输入流通过缓冲区写入输出流的代码:

        int len = 0;
        while((len = is.read(buffer)) > 0){
//            将文件输出给客户端
            os.write(buffer,0,len);
        }

这段代码可以说是将文件输入流转换为输出流的固定格式,在服务器文件下载中经常使用,需要我们记住。
其中的is.read()方法的作用是:如果参数是byte[],那么将从输入流中获取下一段最多长度是byte[].length的字节(也有可能不够这么多),将其存放在byte[]中,将实际读取的字节数作为int类型返回,如果输入流之后没有字节,那么返回值为-1
4.我们一定要养成在使用完流之后手动将它关闭的好习惯。
5.如果我们想要下载的文件名称是中文的话,我们下载的文件名会是乱码,这个时候需要我们将响应头的设置修改一下:

        String filename = "中文名字.jpeg";
        resp.setHeader("Content-Disposition","attachment;filename=" + URLEncoder.encode(filename,"UTF-8"));

需要注意的是,SerlvetContext.getResource()中的路径是可以带有中文的,所以在将中文名称的文件作为文件流导入时直接将filename输入进去就可以了。

InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/" + filename);

在这里插入图片描述
而且我们需要知道,就算我们没有对response的响应头做处理中文乱码的设置,文件也是可以正常下载的,仅仅只是名字是乱码

基于51单片机,实现对直流电机的调速、测速以及正反转控制。项目包含完整的仿真文件、源程序、原理图和PCB设计文件,适合学习和实践51单片机在电机控制方面的应用。 功能特点 调速控制:通过按键调整PWM占空比,实现电机的速度调节。 测速功能:采用霍尔传感器非接触式测速,实时显示电机转速。 正反转控制:通过按键切换电机的正转和反转状态。 LCD显示:使用LCD1602液晶显示屏,显示当前的转速和PWM占空比。 硬件组成 主控制器:STC89C51/52单片机(与AT89S51/52、AT89C51/52通用)。 测速传感器:霍尔传感器,用于非接触式测速。 显示模块:LCD1602液晶显示屏,显示转速和占空比。 电机驱动:采用双H桥电路,控制电机的正反转和调速。 软件设计 编程语言:C语言。 开发环境:Keil uVision。 仿真工具:Proteus。 使用说明 液晶屏显示: 第行显示电机转速(单位:转/分)。 第二行显示PWM占空比(0~100%)。 按键功能: 1键:加速键,短按占空比加1,长按连续加。 2键:减速键,短按占空比减1,长按连续减。 3键:反转切换键,按下后电机反转。 4键:正转切换键,按下后电机正转。 5键:开始暂停键,按下开始,再按下暂停。 注意事项 磁铁和霍尔元件的距离应保持在2mm左右,过近可能会在电机转动时碰到霍尔元件,过远则可能导致霍尔元件无法检测到磁铁。 资源文件 仿真文件:Proteus仿真文件,用于模拟电机控制系统的运行。 源程序:Keil uVision项目文件,包含完整的C语言源代码。 原理图:电路设计原理图,详细展示了各模块的连接方式。 PCB设计:PCB布局文件,可用于实际电路板的制作。
【四旋翼无人机】具备螺旋桨倾斜机构的全驱动四旋翼无人机:建模与控制研究(Matlab代码、Simulink仿真实现)内容概要:本文围绕具备螺旋桨倾斜机构的全驱动四旋翼无人机展开研究,重点进行了系统建模与控制策略的设计与仿真验证。通过引入螺旋桨倾斜机构,该无人机能够实现全向力矢量控制,从而具备更强的姿态调节能力和六自由度全驱动特性,克服传统四旋翼欠驱动限制。研究内容涵盖动力学建模、控制系统设计(如PID、MPC等)、Matlab/Simulink环境下的仿真验证,并可能涉及轨迹跟踪、抗干扰能力及稳定性分析,旨在提升无人机在复杂环境下的机动性与控制精度。; 适合人群:具备定控制理论基础和Matlab/Simulink仿真能力的研究生、科研人员及从事无人机系统开发的工程师,尤其适合研究先进无人机控制算法的技术人员。; 使用场景及目标:①深入理解全驱动四旋翼无人机的动力学建模方法;②掌握基于Matlab/Simulink的无人机控制系统设计与仿真流程;③复现硕士论文级别的研究成果,为科研项目或学术论文提供技术支持与参考。; 阅读建议:建议结合提供的Matlab代码与Simulink模型进行实践操作,重点关注建模推导过程与控制器参数调优,同时可扩展研究不同控制算法的性能对比,以深化对全驱动系统控制机制的理解。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值