Spring Boot RestController接口输出到终端的操作代码
作者:飞鸟_Asuka
背景
公司项目的批处理微服务,一般是在晚上固定时段通过定时任务执行,但为了预防执行失败,我们定义了对应的应急接口,必要时可以通过运维在终端中进行curl操作。然而,部分任务耗时较长,curl命令执行后长时间没有输出,如果不查看日志,无法知道系统当前的状态,因此有必要研究一下如何在curl命令调用接口时,在终端输出部分信息,已告知运维人员当前命令的执行状态。
原理
使用 HttpServletResponse
类,可以自定义输出,也就是模拟网页输出的效果,只不过我们输出的内容是纯文本。
代码
- 新建一个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接口的同时,在控制台输出一些信息,给运维人员知道当前命令执行的状态。
到此这篇关于Spring Boot RestController接口输出到终端的操作代码的文章就介绍到这了,更多相关Spring Boot RestController接口内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!