首页 > 其他分享 >Spring Boot RestController接口如何输出到终端

Spring Boot RestController接口如何输出到终端

时间:2023-09-25 22:45:42浏览次数:30  
标签:输出 RestController Spring writer Boot 任务 output 应急 response

背景

公司项目的批处理微服务,一般是在晚上固定时段通过定时任务执行,但为了预防执行失败,我们定义了对应的应急接口,必要时可以通过运维在终端中进行curl操作。然而,部分任务耗时较长,curl命令执行后长时间没有输出,如果不查看日志,无法知道系统当前的状态,因此有必要研究一下如何在curl命令调用接口时,在终端输出部分信息,已告知运维人员当前命令的执行状态。

原理

使用 HttpServletResponse 类,可以自定义输出,也就是模拟网页输出的效果,只不过我们输出的内容是纯文本。

代码

  1. 新建一个Spring Boot项目,建立一个 TestController,作为我们的应急接口。
@RestController
@Slf4j
public class EmergencyController {
    @Resource
    private TestService testService;

    @GetMapping("/test")
    public void test(HttpServletResponse response) throws IOException {
        response.setContentType("text/plain;charset=utf-8");
        try {
            boolean result = testService.emergencyOperation(response);
            response.getWriter().println(CommonResult.success(null, "应急任务处理成功!").toString());
        } catch (IOException e) {
            log.error("应急任务处理失败!", e);
            response.getWriter().println(CommonResult.fail(null, "应急任务处理失败!").toString());
        }
    }
}

这里的一个坑是:如果使用了这种方法输出,那么接口方法不能再有任何返回值,不然会让Spring Boot以为重复调用了 response.getWriter() 函数,于是报错。需要将原本的输出内容(如通用返回体CommonResult类,或字符串String)也放入 response.getWriter() 进行输出。

其中 TestService 是我们的批处理业务接口,无论是应急接口还是定时任务,都需要使用该接口进行实际的业务操作。其实现类 TestServiceImpl 代码如下:

/**
 * 模拟应急操作方法
 */
@Override
public boolean emergencyOperation(HttpServletResponse response) throws IOException {
    // 如果是定时任务,则该参数传入null,不在终端输出
    boolean canOutput = response != null;
    PrintWriter writer = createPrintWriter(canOutput, response);
    log.info("开始执行应急操作任务");
    output(canOutput, writer, "开始执行应急操作任务");
    for (int i = 0; i < 20; i++) {
        output(canOutput, writer, "完成第" + (i+1) + "批次");
        log.info("完成第 {} 批次", i+1);
        try {
            Thread.sleep(500L);
        } catch (InterruptedException e) {
            log.warn("应急操作任务失败");
            output(canOutput, writer, "应急操作任务失败");
            return false;
        }
    }
    log.info("完成应急操作任务");
    output(canOutput, writer, "应急操作任务完成");
    return true;
}

其中 createPrintWriter() 方法设置 HttpServletResponse 对象的 ContentType 属性,我们输出的是纯文本,因此需要设置为 text/plain;charset=utf-8,具体代码如下:

private PrintWriter createPrintWriter(boolean output, HttpServletResponse response) throws IOException {
    if (output) {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/plain;charset=utf-8");
        return response.getWriter();
    }
    return null;
}

在需要使用的地方调用 output() 方法,向控制台打印输出内容:

private void output(boolean output, PrintWriter writer, String message) throws IOException {
    if (!output) {
        return;
    }
    writer.println(message);
    writer.flush();
}

测试

使用 Maven 构建项目,在项目生成目录下运行 jar 包启动程序,另外开一个控制台窗口,执行 curl http://localhost:8080/test,可以看到控制台输出如下:

同时在运行 Spring Boot 应用的窗口,也可以看到日志成功输出:

定时任务执行情况

我们定义定时任务 EmergencyTask 如下(不要忘了在应用启动类上增加 @EnableScheduling 注解)

@Component
@Slf4j
public class EmergencyTask {
    @Resource
    private TestService testService;

    @Scheduled(cron = "0 */5 22 * * MON-FRI")
    public void emergencyTask() throws IOException {
        testService.emergencyOperation(null);
    }
}

这里我们设置的是从22点后每隔5分钟执行一次,当然实际项目中需要根据需求来确定定时任务执行时间。
启动应用,等5分钟,可以看到定时任务成功执行。

再次运行 curl http://localhost:8080/test,可以看到控制台和日志均正常输出。

总结

使用 HttpServletResponse 类,可以在使用 curl 执行 Spring Boot REST接口的同时,在控制台输出一些信息,给运维人员知道当前命令执行的状态。

标签:输出,RestController,Spring,writer,Boot,任务,output,应急,response
From: https://www.cnblogs.com/ryuasuka/p/17729040.html

相关文章

  • Spring Security 基于 JWT Token 的接口安全控制
    现在的网站开发,基本上都是前后端分离,后端提供api接口并进行权限控制。使用SpringSecurity框架可以大大简化权限控制的代码实现。对于后端接口而言,为了能够实现多节点负载均衡部署,更好的方案是不再使用Session了,绝大多数情况下,通过提交JWTToken来进行身份认证。本篇博客......
  • SpringCloud之Gateway
    1.什么是GatewaySpringCloudGateway是Spring公司基于Spring5.0,SpringBoot2.0和ProjectReactor等术开发的网关,它旨在为微服务架构提供一种简单有效的统一的API路由管理方式。它的目标是替代NetflflixZuul,其不仅提供统一的路由方式,并且基于Filter链的方式提供了......
  • spring_aop
                 ......
  • spring_ioc
                 ......
  • SpringBootAdmin_监控
    监控的意义监控服务状态是否宕机监控服务运行指标(内存、虚拟机、线程、请求等)监控日志管理服务(服务下线)监控的实施方式大部分监控平台都是主动拉取监控信息,而不是被动地等待应用程序传递信息应用程序要设置:是否能被监控、开放那些信息给显示监控信息的服务器(监控平台......
  • SpringBoot学习1(项目部署以及创建报错的解决)
    1.SpringBoot设计目的:简化Spring应用的初始搭建以及开发过程.2.空项目创建2.1查看更改自己的maven版本file-->settings有时候这里的mavenhomeusersettingsfilelocal..不是自己的maven文件夹,记得修改过来。 2.2创建modulefile-->projectstructure如果有一个module的......
  • spring5.0新特性学习
    核心容器修订:函数式编程方式注册bean;对GraalVMNativeImage的支持(可以通过运行原生代码的方式提高速度,原理是剔除了一些不需要的编译path来提高速度)对JavaRecord类模型的支持(JDK14引入的类,可以直接在数据绑定的时候,对Javabean中的变量可以省略get直接用变量名作为方法名来使用......
  • SpringBoot MongoDB操作封装
    1.引入Jar包<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId></dependency>2.MongoDbHelper操作/***MongoDBOperationclass*......
  • 使用SpringBoot+Vue3的形式实现管理系统的添加功能
    1、查看页面形式2、使用element-plus组件为添加页面引入form表单成功引入form表单组件:3、更改成自己需要的形式4、测试是否可以拿到文本框的数据拿到数据啦!!(记得vue3这里:console.log(form)//不要写this```)#5、vue界面的添加代码<el-form-item>......
  • SpringBoot WebSocket STOMP
    SpringBootWebSocketSTOMP关键词:Springboot,WebSocket,STOMP,broadcast,sendToUser,MessageMapping,SubscribeMapping,convertAndSendToUserSTOMP是一种发布订阅的模式,被订阅者发布消息以广播形式发送。如果需要一对一发送或者说指定某个客户端发送,springboot提供了con......