使用HttpServletResponse实现curl接口时控制台输出(续)

使用,httpservletresponse,实现,curl,接口,控制台,输出 · 浏览次数 : 6

小编点评

**解决方案:** 1. **构造一个全局的 HttpServletResponse 对象:** - 在 `WebUtil` 中添加一个 `@Autowired` 注解注入的 `HttpServletResponse` 对象属性。 - 在 `output()` 方法中注入 `webUtil` 对象。 2. **在其他所有需要使用 `HttpServletResponse` 的地方自动注入:** - 在 `TestServiceImpl` 中使用 `@Autowired` 注解注入 `webUtil` 对象。 - 使用 `webUtil` 对象的 `output()` 方法进行控制台输出。 **代码示例:** ```java // WebUtil.java @Component @Resource private HttpServletResponse httpServletResponse; // TestServiceImpl.java @Service @Slf4j public class TestServiceImpl implements TestService { @Autowired private WebUtil webUtil; @Override public boolean emergencyOperation() throws IOException { // ... webUtil.output( "开始执行应急操作任务" ); // ... return true; } } ``` **注意:** - 确保 `webUtil` 在整个应用程序范围内可用。 - 使用 `@Autowired` 注解进行自动注入,确保 `webUtil` 对象被正确注入。 - 使用 `@Resource` 注解指定 `HttpServletResponse` 的属性名称。 - 在 `output()` 方法中使用 `setContentType()` 和 `setCharacterEncoding()` 方法设置输出内容的类型和编码。

正文

上一篇文章的问题

在上一篇文章 Spring Boot RestController接口如何输出到终端 中讨论了如何使用 HttpSerlvetResponse 写入输出流,使应急接口通过 curl 调用时可以在控制台输出信息,使运维人员知道命令执行情况。

但是上一篇文章的问题是,HttpServletResponse 是 Controller 的参数,这就使得如果要在其调用的 Service 方法中也要实现控制台输出,就必须让所有涉及到的 Service 方法都带上 HttpServletResponse 参数,这对业务的侵入实在太大,对于实际业务可能包含多个 Service、Component 之间的相互引用,改造成本是不可容忍的。

本文的解决思路

那么笔者就在想,如何构造一个全局的 HttpServletResponse 对象,使它能够在各个 Controller、Service、Component 之前传递呢?经过查阅资料发现,HttpServletResponse 对象本身是可以被 @Autowired@Resource 注解注入的!那么我们就可以构造一个带有自动注入的 HttpServletResponse 对象的 Component,然后在其他所有需要使用的地方去自动注入这个 Component 即可。

代码

代码实现如下:

@Component
public class WebUtil {
    @Resource
    private HttpServletResponse httpServletResponse;

    public void output(String message) {
        if (httpServletResponse == null) {
            return;
        }
        try {
            httpServletResponse.setContentType("text/plain;charset=utf-8");
            httpServletResponse.setCharacterEncoding("UTF-8");
            PrintWriter writer = httpServletResponse.getWriter();
            writer.println(message);
            writer.flush();
        } catch (Exception e) {
            return;
        }
    }
}

由于我们的目的只是为了实现控制台输出,所以如果该方法抛出异常(主要是 IOExceptionIllegalStatesException),那么直接返回即可。这个问题主要出在定时任务中,因为定时任务是不含 HttpServletResponse 对象的,如果在定时任务中调用该方法的时候会抛出 IllegalStatesException

在要使用该方法的类中使用自动注入,注入 WebUtil 类,然后使用它的对象(而不是这个类本身)的output方法即可。

@Service
@Slf4j
public class TestServiceImpl implements TestService {
    @Resource
    private WebUtil webUtil;

    @Override
    public boolean emergencyOperation() throws IOException {
        log.info("开始执行应急操作任务");
        webUtil.output( "开始执行应急操作任务");
        for (int i = 0; i < 20; i++) {
            webUtil.output( "完成第" + (i+1) + "批次");
            log.info("完成第 {} 批次", i+1);
            try {
                Thread.sleep(500L);
            } catch (InterruptedException e) {
                log.warn("应急操作任务失败");
                webUtil.output( "应急操作任务失败");
                return false;
            }
        }
        log.info("完成应急操作任务");
        webUtil.output( "应急操作任务完成");
        return true;
    }
}

经过测试发现,curl调用接口可以实现控制台输出,定时任务也执行正常,没有预期外的异常产生。

与使用HttpServletResponse实现curl接口时控制台输出(续)相似的内容:

使用HttpServletResponse实现curl接口时控制台输出(续)

上一篇文章的问题 在上一篇文章 Spring Boot RestController接口如何输出到终端 中讨论了如何使用 HttpSerlvetResponse 写入输出流,使应急接口通过 curl 调用时可以在控制台输出信息,使运维人员知道命令执行情况。 但是上一篇文章的问题是,HttpServl

使用Cloudflare Worker加速docker镜像

前言 开发者越来越难了,现在国内的docker镜像也都️了,没有镜像要使用docker太难了,代理又很慢 现在就只剩下自建镜像的办法了 GitHub上有开源项目可以快速搭建自己的镜像库,不过还是有点麻烦,还好Cloudflare暂时还活着‍ 本文记录一下使用 Cloudf

使用C#/.NET解析Wiki百科数据实现获取历史上的今天

创建一个webapi项目做测试使用。 创建新控制器,搭建一个基础框架,包括获取当天日期、wiki的请求地址等 创建一个Http请求帮助类以及方法,用于获取指定URL的信息 使用http请求访问指定url,先运行一下,看看返回的内容。内容如图右边所示,实际上是一个Json数据。我们主要解析 大事记 部

Pybind11和CMake构建python扩展模块环境搭建

使用pybind11的CMake模板来创建拓展环境搭建 从Github上下载cmake_example的模板,切换分支,并升级pybind11子模块到最新版本 拉取pybind11使用cmake构建工具的模板仓库 git clone --recursive https://github.com/mr

说说RabbitMQ延迟队列实现原理?

使用 RabbitMQ 和 RocketMQ 的人是幸运的,因为这两个 MQ 自身提供了延迟队列的实现,不像用 Kafka 的同学那么苦逼,还要自己实现延迟队列。当然,这都是题外话,今天咱们重点来聊聊 RabbitMQ 延迟队列的实现原理,以及 RabbitMQ 实现延迟队列的优缺点有哪些? 很多人

使用FModel提取游戏资产

目录前言FModel简介FModel安装FModel使用初次使用资产预览资产导出附录dumperDumper-7生成usmap文件向游戏中注入dll 前言 这篇文章仅记录我作为初学者使用FModel工具提取某款游戏模型的过程。 FModel简介 FModel是一个开源软件,可以用于查看和提取UE4-

使用GSAP制作动画视频

GSAP 3Blue1Brown给我留下了深刻印象。利用动画制作视频,内容简洁,演示清晰。前两天刚好碰到一件事,我就顺便学习了一下怎么用代码做动画。 以javascrip为例,有两个动画引擎,GSAP和Animajs。由于网速的原因,询问了GPT后,我选择了GSAP来制作我的第一个动画视频。 制作动

使用ML.NET训练一个属于自己的图像分类模型,对图像进行分类就这么简单!

前言 今天大姚给大家分享一个.NET开源、免费、跨平台(支持Windows、Linux、macOS多个操作系统)的机器学习框架:ML.NET。并且本文将会带你快速使用ML.NET训练一个属于自己的图像分类模型,对图像进行分类。 ML.NET框架介绍 ML.NET 允许开发人员在其 .NET 应用程序

使用libzip压缩文件和文件夹

简单说说自己遇到的坑: 分清楚三个组件:zlib、minizip和libzip。zlib是底层和最基础的C库,用于使用Deflate算法压缩和解压缩文件流或者单个文件,但是如果要压缩文件夹就很麻烦,主要是不知道如何归档,在zip内部形成对应的目录。这时就需要用更高级别的库,也就是minizip或li

使用gzexe加密shell脚本

使用 gzexe 加密 shell 脚本是一个相对简单的过程。以下是具体的步骤: 编写你的 shell 脚本:首先,你需要有一个 shell 脚本文件,比如 myscript.sh。 确保脚本可执行:使用 chmod 命令确保你的脚本文件是可执行的: chmod +x myscript.sh 使用