在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

主動寫入流對@ResponseBody注解的影響

京東云 ? 來源:京東零售 柯賢銘 ? 作者:京東零售 柯賢銘 ? 2024-10-29 11:28 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

作者:京東零售 柯賢銘

問題回溯

2023年Q2某日運營反饋一個問題,商品系統商家中心某批量工具模板無法下載,導致功能無法使用(因為模板是動態變化的)

商家中心報錯(JSON串):

{"code":-1,"msg":"失敗"}

?

負責的同事看到失敗后立即與我展開討論(因為不是關鍵業務,所以不需要回滾,修復即可),我們發現新功能模板下載的代碼與之前的代碼有所不同,恰好之前的功能又可以正常運行,所以同事對現有代碼進行改造然后預發布測試完成后再次上線。

?

其他業務代碼:

/**
 * 模板下載
 */
@RequestMapping("/doBatchWareSetAd")
public void doBatchWareSetAd(@RequestParam MultipartFile file, HttpServletResponse response) {
	wareBatchBusiness.doBatchWareSetAd(file, response, getLongOrgCode(), getCurrentUserPin(), getCurrentUserId());
}

?

問題業務代碼:

/**
 * 模板下載
 */
@RequestMapping("/doBatchWareSetAdDemo")
@ResponseBody
public Map doBatchWareSetAd(@RequestParam MultipartFile file, HttpServletResponse response) {
	return wareBatchBusiness.doBatchWareSetAd(file, response, getLongOrgCode(), getCurrentUserPin(), getCurrentUserId());
}

?

上線的結果是;仍然無法使用。

其實也正常:因為兩種代碼在預發布都可以正常運行,在線上出錯只可能是因為其他原因,只不過我們不了解底層原理,害怕它 "可能" 有問題罷了,最終查詢得到的結論是權限系統管理員在線上環境沒有給我們配置相應的文件,導致請求為空,導致請求失敗。

?

探索 @ResponseBody 與主動寫入流的關系

我們都知道 @ResponseBody 注解可以幫助我們把返回對象轉化為JSON,方便展示和交互。

那它到底是如何工作的呢,請看下面的講解:

?

代碼案例1:

@RequestMapping("/test1")
@ResponseBody
public Map test1(HttpServletResponse response) {
    Map map = new HashMap();
    map.put("1", "1");
    return map;
}

// 響應
JSON報文

?

跟代碼發現其核心處理類為:RequestResponseBodyMethodProcessor.java

方法:org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor#handleReturnValue 會處理其相關返回值。

真正的核心處理方法:org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor#writeWithMessageConverters

關鍵DEBUG記錄如圖所示:

wKgaoWcgVl6ASzeIAACPuUuQfBA158.png

?

后續內容可以想象,肯定還有地方去把流按照指定的HEADER寫入,因為和本文無關所以不深究。

?

再來看代碼案例2:

@RequestMapping("/test2")
@ResponseBody
public Map test2(HttpServletResponse response) throws IOException {
    Map map = new HashMap();
    map.put("1", "1");

    response.setContentType("application/vnd.ms-excel");
    response.setHeader("Content-Disposition", String.format(
        "attachment; filename=%s_%s.xls", "Demo", System.currentTimeMillis()));

    OutputStream out = response.getOutputStream();
    out.flush();
    out.close();
    return map;
}

// 響應
提示下載文件

?

關鍵DEBUG源碼截圖:

wKgZoWcgVl-AEfpSAAA2pk7ToUA050.png

wKgaoWcgVmCADqguAAAlKaZXGoY120.png

?

可以發現Spring對這種方式操作文件流視作異常情況,然后拋出,在后續邏輯中完成整個請求,簡單來說就是 @ResponseBody 注解沒起到任何作用。

因此答案呼之欲出:當時功能不可用的罪魁禍首就是相關人員沒有配置參數導致,與寫法沒有任何關系。

?

結論與啟發

結論:

1.我們要相信自己的代碼,至少是要相信已經經過測試的代碼。

2.在委托他人或者自己配置環境參數,如權限、ZK等每次都保證預發布和線上同時配置,避免遺漏的情況。

?

啟發:

聊了這么多,那我們這種類似場景的代碼應該怎么寫?

既然主動寫入流會解除@ResponseBody的作用,反之又能發揮它的作用,那我們最佳方案是不是如下所示?

@RequestMapping("/test1")
@ResponseBody
public Map test1(HttpServletResponse response) {
    Map map = new HashMap();
    if (獲取不到文件配置 == true) {
        return map.put("msg", "獲取不到文件配置");
    }
    
    response.setContentType("application/vnd.ms-excel");
    response.setHeader("Content-Disposition", String.format(
        "attachment; filename=%s_%s.xls", "Demo", System.currentTimeMillis()));

    OutputStream out = response.getOutputStream();
    out.flush();
    out.close();
    return map;
}

?

如此一來,當發生預期之外的情況,我們有非常明顯的報錯提示,當正常時又可以完美實現功能,妙哉(我覺得)~

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 代碼
    +關注

    關注

    30

    文章

    4893

    瀏覽量

    70445
  • JSON
    +關注

    關注

    0

    文章

    122

    瀏覽量

    7338
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    如何通過注解來優化我們的Java代碼

    Java注解可以說是我們編碼過程中最常用的。本篇文章將給大家介紹Java注解的概念、作用以及如何使用注解來提升代碼的可讀性和靈活性,并介紹如何通過注解來優化我們的Java代碼。 1、什
    的頭像 發表于 09-30 11:39 ?898次閱讀

    機種新品導入流

    機種新品導入流
    發表于 08-11 10:08

    redis緩存注解怎么使用

    spring boot —— redis 緩存注解使用教程
    發表于 09-11 14:43

    HarmonyOS注解的使用方法分享

    javax.annotation.processing.Processor 文件寫入注解處理器的全稱,包括包路徑4、使用注解在entry模塊的build.gradle文件中添加依賴dependencies
    發表于 03-28 14:04

    分析java注解基本概念

    什么是注解(Annotation): Annotation(注解)就是Java提供了一種元程序中的元素關聯任何信息和著任何元數據(metadata)的途徑和方法。Annotion(注解)是一個接口
    發表于 09-27 14:53 ?0次下載

    注解定義Bean及開發

    注解本質是一個繼承了Annotation 的特殊接口,其具體實現類是Java 運行時生成的動態代理類。
    發表于 08-02 10:26 ?563次閱讀

    Spring Web MVC注解

    RequestMapping注解的主要用途是將Web請求與請求處理類中的方法進行映射。Spring MVC和Spring WebFlux都通過`RquestMappingHandlerMapping`和`RequestMappingHndlerAdapter`兩個類來提供對@RequestMapping
    的頭像 發表于 04-07 11:32 ?822次閱讀
    Spring Web MVC<b class='flag-5'>注解</b>

    Spring Dependency Inject與Bean Scops注解

    DependsOn`注解可以配置Spring IoC容器在初始化一個Bean之前,先初始化其他的Bean對象。下面是此注解使用示例代碼:
    的頭像 發表于 04-07 11:35 ?877次閱讀
    Spring Dependency Inject與Bean Scops<b class='flag-5'>注解</b>

    容器配置及Spring Boot注解

    Autowired注解用于標記Spring將要解析和注入的依賴項。此注解可以作用在構造函數、字段和setter方法上。
    的頭像 發表于 04-07 11:45 ?782次閱讀
    容器配置及Spring Boot<b class='flag-5'>注解</b>

    Springboot常用注解合集

    前幾章,在系統啟動類里面,都加入了此啟動注解,此注解是個組合注解,包括了`@SpringBootConfiguration`、`@EnableAutoConfiguration`和`@ComponentScan`
    的頭像 發表于 04-07 14:27 ?969次閱讀
    Springboot常用<b class='flag-5'>注解</b>合集

    JAVA中注解是怎么做到的(上)

    注解想必大家在項目中經常使用,比如Spring框架中常用的一些注解:`@Controller`、`@Service`、`@RequestMapping`等等,它是JDK1.5及以后版本引入的一個特性
    的頭像 發表于 05-11 10:57 ?840次閱讀

    JAVA中注解是怎么做到的(下)

    注解想必大家在項目中經常使用,比如Spring框架中常用的一些注解:`@Controller`、`@Service`、`@RequestMapping`等等,它是JDK1.5及以后版本引入的一個特性
    的頭像 發表于 05-11 10:57 ?760次閱讀
    JAVA中<b class='flag-5'>注解</b>是怎么做到的(下)

    springmvc常用5種注解

    SpringMVC是一種基于Java的Web框架,使用注解可以更加方便靈活地開發和管理控制器,實現請求的映射和處理。在SpringMVC中,有許多常用的注解,本文將詳細介紹其中的五種注解,并且詳細
    的頭像 發表于 11-22 16:51 ?1296次閱讀

    springboot核心注解

    Spring Boot 是基于 Spring 框架的開源框架,它可以幫助開發者快速構建、部署和運行獨立的、生產級的 Spring 應用程序。Spring Boot 提供了一系列核心注解,這些注解可以
    的頭像 發表于 11-23 09:23 ?782次閱讀

    SpringBoot核心注解由幾個注解組成

    簡化應用程序開發的注解,其中核心注解包括 @SpringBootApplication、@RestController、@RequestMapping、@Autowired、@ComponentScan
    的頭像 發表于 12-03 15:09 ?1026次閱讀
    主站蜘蛛池模板: 欧美日韩一区视频 | 午夜视频www | 国产网站在线播放 | 成人午夜性视频欧美成人 | 在线观看免费av网站 | 天天寡妇色 | 亚洲人色大成年网站在线观看 | 国产精品久久久久久久久ktv | 我想看一级播放片一级的 | 精品一区二区三区免费爱 | 屁股趴过来欠打高h | 国产精品色片 | 久久综合九色婷婷97 | 黄色免费网站在线观看 | 黄色www网站 | 日韩免费高清一级毛片 | 国产色婷婷免费视频 | 色www视频永久免费软件 | 一级片一级片一级片 | 又黄又爽又猛大片录像 | 新激情五月 | 国产精品你懂的在线播放 | 永久毛片 | 国产精品午夜高清在线观看 | 三级免费黄色片 | 丁香六月五月婷婷 | 中国一级特黄剌激爽毛片 | 亚洲天天看 | 最新中文字幕在线资源 | 8888四色奇米在线观看不卡 | 国产三级在线观看免费 | 欧美.亚洲.日本一区二区三区 | 亚洲成人av | 第九色 | 被cao到合不拢腿腐男男 | 亚洲成人资源 | 色偷偷.com| 日韩特黄特色大片免费视频 | 国产精品7m凸凹视频分类大全 | 福利视频网址 | 久久观看视频 |