Spring?Boot?RestController接口輸出到終端的操作代碼
背景
公司項目的批處理微服務,一般是在晚上固定時段通過定時任務執(zhí)行,但為了預防執(zhí)行失敗,我們定義了對應的應急接口,必要時可以通過運維在終端中進行curl操作。然而,部分任務耗時較長,curl命令執(zhí)行后長時間沒有輸出,如果不查看日志,無法知道系統(tǒng)當前的狀態(tài),因此有必要研究一下如何在curl命令調用接口時,在終端輸出部分信息,已告知運維人員當前命令的執(zhí)行狀態(tài)。
原理
使用 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
是我們的批處理業(yè)務接口,無論是應急接口還是定時任務,都需要使用該接口進行實際的業(yè)務操作。其實現(xiàn)類 TestServiceImpl
代碼如下:
/** * 模擬應急操作方法 */ @Override public boolean emergencyOperation(HttpServletResponse response) throws IOException { // 如果是定時任務,則該參數傳入null,不在終端輸出 boolean canOutput = response != null; PrintWriter writer = createPrintWriter(canOutput, response); log.info("開始執(zhí)行應急操作任務"); output(canOutput, writer, "開始執(zhí)行應急操作任務"); 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 包啟動程序,另外開一個控制臺窗口,執(zhí)行 curl http://localhost:8080/test
,可以看到控制臺輸出如下:
同時在運行 Spring Boot 應用的窗口,也可以看到日志成功輸出:
定時任務執(zhí)行情況
我們定義定時任務 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分鐘執(zhí)行一次,當然實際項目中需要根據需求來確定定時任務執(zhí)行時間。
啟動應用,等5分鐘,可以看到定時任務成功執(zhí)行。
再次運行 curl http://localhost:8080/test
,可以看到控制臺和日志均正常輸出。
總結
使用 HttpServletResponse
類,可以在使用 curl 執(zhí)行 Spring Boot REST接口的同時,在控制臺輸出一些信息,給運維人員知道當前命令執(zhí)行的狀態(tài)。
到此這篇關于Spring Boot RestController接口輸出到終端的操作代碼的文章就介紹到這了,更多相關Spring Boot RestController接口內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
springboot之Duration(java.time.Duration)在yml properties中
這篇文章主要介紹了springboot之Duration(java.time.Duration)在yml properties中的配置方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12Java中由substring方法引發(fā)的內存泄漏詳解
這篇文章主要介紹了Java中由substring方法引發(fā)的內存泄漏詳解,涉及substring方法引發(fā)的內存泄漏簡介,substring的作用和實現(xiàn)原理等相關內容,具有一定借鑒價值,需要的朋友可以參考下2017-12-12Java基于迭代器模式實現(xiàn)的訪問人員列表操作示例
這篇文章主要介紹了Java基于迭代器模式實現(xiàn)的訪問人員列表操作,簡單描述了迭代器模式的概念、原理以及使用迭代器模式實現(xiàn)訪問人員列表的相關操作技巧,需要的朋友可以參考下2018-05-05Springboot使用Security實現(xiàn)OAuth2授權驗證完整過程
安全管理是軟件系統(tǒng)必不可少的的功能。根據經典的“墨菲定律”——凡是可能,總會發(fā)生。如果系統(tǒng)存在安全隱患,最終必然會出現(xiàn)問題,這篇文章主要介紹了SpringBoot使用Security實現(xiàn)OAuth2授權驗證完整過程2022-12-12