← 回到首頁

每日新聞摘要

2026年01月14日

選擇語言 / Select Language

中文 English 简体中文
今日收集到 6 篇文章摘要

How to Set Content-Length Header in ResponseEntity in Spring MVC

How to Set Content-Length Header in ResponseEntity in Spring MVC
Set Content-Length explicitly when you know the response size to ensure correct transfers and client compatibility.

重點摘要

Content-Length specifies the exact byte size of the response body; omit it and the server may use chunked transfer encoding.
For text calculate byte length with the correct charset (e.g., UTF-8); for binary or file downloads set contentLength(...) or HttpHeaders.setContentLength(...).
Avoid setting Content-Length for streaming, SSE, or incrementally generated responses; let Spring manage it unless the size is known and required.
Spring MVC's ResponseEntity normally sets HTTP headers automatically, but you should explicitly set the Content-Length header when the response size is known in advance to ensure correct transfers and client compatibility. Content-Length conveys the exact byte count of the response body; omitting it can cause the server to use Transfer-Encoding: chunked, which is appropriate for streaming or dynamically generated content but not for file downloads or clients that track progress. For text responses calculate bytes using the correct character encoding (for example UTF-8). For binary data and file downloads determine the byte size from the byte array or file and set it via contentLength(...) or HttpHeaders.setContentLength(...). Verify resource existence and sizes to avoid client-side errors, and avoid declaring Content-Length for streaming/SSE endpoints. In most REST cases letting Spring manage the header is safest; set it explicitly only when the exact byte count is known and required.
在 Spring MVC 的 ResponseEntity 中设置 Content-Length 标头
当响应大小已知时,显式设置 Content-Length 可确保传输正确并提高客户端兼容性。

重點摘要

Content-Length 指定响应主体的精确字节大小;未设置时服务器可能使用 chunked 传输编码。
文本响应需使用正确编码(如 UTF-8)计算字节长度;二进制或文件下载可通过 contentLength(...) 或 HttpHeaders.setContentLength(...) 设置。
避免在流式传输、SSE 或逐步生成内容时设置 Content-Length;如果大小不确定,应让 Spring 自动管理。
在 Spring MVC 中,ResponseEntity 通常会自动管理 HTTP 标头,但当响应大小已知时,应显式设置 Content-Length,以确保传输准确并与客户端兼容。Content-Length 表示响应主体的精确字节数;省略它可能导致服务器使用 Transfer-Encoding: chunked,这适用于流式或动态生成的内容,但不适用于文件下载或需要显示下载进度的客户端。对于文本响应,应使用正确的字符编码(例如 UTF-8)计算字节长度;对于二进制数据和文件下载,应从字节数组或文件获取大小,并通过 contentLength(...) 或 HttpHeaders.setContentLength(...) 设置。确认资源存在且大小准确以避免客户端错误,通常只有在确知精确字节数且必要时才显式设置,该场景下显式设置可提升兼容性和用户体验。
在 Spring MVC 的 ResponseEntity 設定 Content-Length 標頭
當回應大小已知時,明確設定 Content-Length 可確保傳輸正確並提升客戶端相容性。

重點摘要

Content-Length 指定回應主體的精確位元組大小;未設定時伺服器可能改用 chunked 傳輸。
文字回應需以正確編碼(如 UTF-8)計算位元組長度;二進位或檔案下載可使用 contentLength(...) 或 HttpHeaders.setContentLength(...)。
避免在串流、SSE 或逐步產生內容時設定 Content-Length;若不確定大小,應由 Spring 自動管理。
在 Spring MVC 中,ResponseEntity 通常會自動處理 HTTP 標頭,但當回應大小已知時,應明確設定 Content-Length,以確保傳輸正確與客戶端相容。Content-Length 指定回應主體的精確位元組大小;未設定時伺服器可能改用 chunked 傳輸,適合串流或動態內容但不適用於檔案下載或需顯示進度的客戶端。對文字回應須以正確編碼(例如 UTF-8)計算位元組長度;二進位資料或檔案下載則從陣列或檔案取得大小並使用 contentLength(...) 或 HttpHeaders.setContentLength(...) 設定。請確認資源存在且大小正確,並避免在 StreamingResponseBody、SSE 或逐步產生內容時手動設定;大多數 REST 情況下讓 Spring 自動管理最安全,僅在確知精確位元組數且必要時才顯式設定。

Fix the Java-MySQL Connection Exception: Public Key Retrieval is not allowed

Fix the Java-MySQL Connection Exception: Public Key Retrieval is not allowed
The error is a security safeguard when the JDBC driver cannot safely retrieve the MySQL server's RSA public key during authentication.

重點摘要

Occurs when caching_sha2_password is used without SSL and public key retrieval is disabled
Quick development workaround: add allowPublicKeyRetrieval=true to the JDBC URL
Recommended fix: enable SSL with CA verification; alternative is changing the user plugin to mysql_native_password
This article explains the "Public Key Retrieval is not allowed" exception seen when a Java client connects to MySQL 8. The error arises because MySQL 8 uses caching_sha2_password and, when SSL is unavailable, requires an RSA public key to encrypt the password; Connector/J blocks automatic retrieval by default for security. The author reproduces the problem using a two-machine test (MySQL server and Java client), showing a JDBC URL with useSSL=false and allowPublicKeyRetrieval=false triggers the exception. Fixes include a development-only workaround (allowPublicKeyRetrieval=true), the recommended production solution of enabling SSL with a CA-signed server certificate and a Java truststore (sslMode=VERIFY_CA), and as a last resort switching the user to mysql_native_password. The guide details certificate generation, MySQL SSL configuration, and client truststore setup so the secure SSL option removes the error.
修复 Java 与 MySQL 连接异常:Public Key Retrieval is not allowed
当 JDBC 驱动无法安全地检索 MySQL 服务器的 RSA 公钥以完成认证时,会触发此安全提示。

重點摘要

通常发生在使用 caching_sha2_password 且未启用 SSL 或未允许公钥检索时
开发临时方案:在 JDBC URL 加上 allowPublicKeyRetrieval=true(仅限测试)
生产环境推荐启用 SSL 并使用 CA 验证;可作为最后手段将认证插件改为 mysql_native_password
本文介绍了在 Java 客户端连接 MySQL 8 时出现“Public Key Retrieval is not allowed”异常的成因与解决方案。问题来自 MySQL 8 的默认认证插件 caching_sha2_password:如果未启用 SSL,密码交换需要用服务器的 RSA 公钥加密,而 Connector/J 为安全起见默认禁止自动检索该公钥。作者以两台机器的测试环境重现该错误,并给出三种处理方式:开发环境可临时在连接字符串中开启 allowPublicKeyRetrieval=true;推荐的生产方案是为 MySQL 配置 SSL(生成 CA 与服务器证书、设置 ssl-ca、ssl-cert、ssl-key)、在 Java 客户端导入 CA 到 truststore 并使用 sslMode=VERIFY_CA;最后还可将用户认证改为 mysql_native_password,但安全性较低。
修正 Java 與 MySQL 連線例外:Public Key Retrieval is not allowed
當 JDBC 驅動無法安全地取得 MySQL 伺服器的 RSA 公鑰以進行驗證時,會以此安全機制拋出錯誤。

重點摘要

錯誤常見於使用 caching_sha2_password 且未啟用 SSL 或未允許公鑰擷取時
開發快速解法:在連線字串加入 allowPublicKeyRetrieval=true(僅測試用)
正式環境建議啟用 SSL 與 CA 驗證;必要時可改用 mysql_native_password
本文說明在 Java 客戶端連接 MySQL 8 時出現「Public Key Retrieval is not allowed」的原因與解法。此錯誤源自 MySQL 8 預設的 caching_sha2_password 機制:若沒有 SSL,密碼交換需以伺服器 RSA 公鑰加密;為安全起見,Connector/J 預設拒絕自動擷取公鑰。文章以兩台機器的測試環境重現問題,並提供三種解決路徑:一是開發環境短期作法,在 JDBC URL 設定 allowPublicKeyRetrieval=true;二是推薦做法,於伺服器產生 CA 與伺服器憑證、設定 MySQL 的 SSL,並在 Java 端匯入 CA 至 truststore 並使用 sslMode=VERIFY_CA;三是最後手段,將使用者認證改為 mysql_native_password(安全性較低)。

Obtain Index of a Given LinkedHashSet Element Without Iteration

Obtain Index of a Given LinkedHashSet Element Without Iteration
Iterating or converting a LinkedHashSet yields linear index lookups, while a custom index-aware structure can provide constant-time access.

重點摘要

Iterating a LinkedHashSet for indexOf is O(n)
Converting to List/array duplicates data and remains linear
Custom two-map approach gives O(1) add/get/indexOf, removal requires O(n) reindexing
This tutorial compares strategies for obtaining an element's index when using a LinkedHashSet. It shows that straightforward iteration or converting the set to a List/array performs linear searches and may double memory usage. Using separate List and Set structures preserves order and uniqueness but still yields O(n) index lookups and complicates removals. A custom index-aware implementation that maintains two maps (element→index and index→element) can achieve constant-time add, get and indexOf operations, at the cost of O(n) work when removing elements due to index shifting. The article also presents a complexity table, discusses trade-offs for different operation mixes, and highlights concurrency concerns: compound operations across multiple containers must be performed atomically (e.g., via synchronization) to remain correct. Wrapping behavior in a dedicated class offers the most flexible path for future optimizations.
在 LinkedHashSet 中获取元素索引(避免直接迭代)
直接迭代或转换 LinkedHashSet 会导致线性索引查找,自定义的索引感知结构可实现常数时间访问。

重點摘要

遍历 LinkedHashSet 获取索引为 O(n)
转换为 List/数组会复制数据且仍是线性搜索
双映射自定义实现可实现 O(1) 添加/获取/indexOf,删除需 O(n) 重新索引
本文比较了在 LinkedHashSet 中获取元素索引的几种策略。作者指出,直接遍历或转换为 List/数组都会执行线性搜索,并可能导致额外的内存开销;使用 List 与 Set 分别维护顺序与唯一性虽能保留各自优点,但索引查找仍为 O(n),且删除需额外处理。文中建议使用双映射(元素→索引、索引→元素)的自定义实现,将添加、按索引获取和 indexOf 操作降为常数时间,但删除元素时需移动索引,成本为 O(n)。文章还提供复杂度概览并讨论多线程访问时的一致性和同步问题,最后建议将逻辑封装到专用类中以便未来优化。
在 LinkedHashSet 中取得元素索引(避免直接遍歷)
直接遍歷或轉換 LinkedHashSet 會導致線性時間的索引查找,而自訂的索引感知結構能提供常數時間存取。

重點摘要

遍歷 LinkedHashSet 取得索引為 O(n)
轉換為 List/陣列會複製資料且仍為線性搜尋
雙映射自訂實作可達成 O(1) 新增/取得/indexOf,刪除需 O(n) 重整
本文比較多種在 LinkedHashSet 中取得元素索引的做法。說明直接遍歷或在需要時轉換為 List/陣列都會進行線性搜尋,且可能增加記憶體使用。採用 List 與 Set 分別維護順序與唯一性可以保留兩者優點,但索引查找仍為 O(n),且刪除需額外同步處理。作者提出使用兩個映射(元素→索引、索引→元素)的自訂類別,可將新增、依索引取得與 indexOf 降為常數時間,但刪除時須重整索引為 O(n)。文章亦列出各方法的時間空間折衷並討論多執行緒存取的同步需求,建議以封裝在專用類別的方式實作以利未來優化。

How to Print JUnit Assertion Results

How to Print JUnit Assertion Results
The article reviews several ways to print assertion results into logs, including assertion messages with post-assertion logging, wrapping assertions to catch and log failures, and using JUnit 5 extensions for centralized test-level logging.

重點摘要

Use clear assertion messages and post-assertion logging
Wrap assertions to log pass/fail and rethrow failures
Use JUnit 5 TestWatcher extension for centralized test-level logs
This article examines techniques for printing JUnit assertion results to logs to aid debugging, CI/CD monitoring, and reporting. It starts with the simplest approach: include descriptive assertion messages and explicit info logs before and after assertions so successful and failed checks appear in logs. It then demonstrates wrapping assertions in a custom Assertion/AssertionWithMessage API and a LoggingAssertions.assertAll method that logs each assertion's outcome, records errors, and rethrows an AssertionError if any assertion failed to preserve test failure semantics. Finally, it shows implementing a JUnit 5 TestWatcher/BeforeEachCallback extension to log test lifecycle events (before each test, on success, and on failure), which centralizes logging when tests are designed with one assertion per test. The article recommends clear messages as a baseline and building utilities or extensions for more complex needs.
如何打印 JUnit 断言结果
文章介绍多种将断言结果写入日志的方法:使用明晰的断言消息并在断言前后记录、封装断言以捕获并记录失败,或使用 JUnit 5 的扩展在测试生命周期集中记录日志。

重點摘要

以清晰的断言消息与事后日志为首选
封装断言以记录通过/失败并在失败时重新抛出
通过 JUnit 5 TestWatcher 扩展实现集中化测试日志
本文概述了在 JUnit 中将断言结果打印到日志的几种方法,以便调试、CI/CD 监控和生成基于日志的报告。首先建议在断言中使用明确的提示信息,并在断言前后添加日志以标示执行流程;然后展示通过自定义 Assertion 与 AssertionWithMessage,以及 LoggingAssertions.assertAll 对断言逐一执行、记录通过或失败并在存在失败时重新抛出 AssertionError 的方案;最后介绍实现 TestWatcher 与 BeforeEachCallback 的 JUnit 5 扩展,用于在测试开始、成功或失败时集中记录日志。文章建议以清晰的断言消息为基础,并在需要时构建工具或扩展以处理更复杂的断言逻辑。
如何列印 JUnit 斷言結果
文章示範多種將斷言結果寫入日誌的方法:使用清楚的斷言訊息與事後記錄、包裝斷言以捕捉例外並紀錄細節,以及透過 JUnit 5 的 TestWatcher 延伸集中處理測試日誌。

重點摘要

以清楚的斷言訊息與事後日誌為基礎
包裝並捕捉 AssertionError,記錄通過與失敗並重新拋出
利用 JUnit 5 TestWatcher 延伸集中記錄測試結果
本文介紹在 JUnit 測試中將斷言結果列印到日誌的幾種做法。首先建議在斷言中加入具描述性的訊息,並在斷言前後加入 info 日誌以顯示流程;接著示範建立 Assertion 與 AssertionWithMessage 的包裝,透過 LoggingAssertions.assertAll 逐一執行斷言、記錄通過或失敗資訊,並在發生失敗時重新拋出 AssertionError,以確保測試框架能正確識別失敗;最後說明使用 JUnit 5 的 TestWatcher 與 BeforeEachCallback 來在測試週期層級集中記錄成功或失敗,適合把每個案例設為單一斷言的情境。建議以清楚的斷言訊息為基礎,必要時再擴充工具或延伸以滿足複雜需求。

What does ‘throw return’ do in Kotlin?

What does ‘throw return’ do in Kotlin?
"The Vacuous Boomerang!" — a brief Kotlin brain teaser (Puzzle 16 of 23) that asks what 'throw return' does.

重點摘要

A Medium post by Sam Cooper asking about 'throw return' in Kotlin.
Part of the Kotlin Brain Teasers series — Puzzle 16 of 23 titled 'The Vacuous Boomerang!'.
Excerpt invites readers to continue on Medium for the full puzzle and discussion.
This short Medium post by Sam Cooper, titled "What does ‘throw return’ do in Kotlin?", is presented as Puzzle 16 of 23 in a Kotlin Brain Teasers series and carries the label "The Vacuous Boomerang!". The excerpt functions as a compact brain teaser prompt that raises the question of how the 'throw return' construct behaves in Kotlin. Rather than providing a full explanation in the snippet, the entry directs readers to continue reading on Medium to view the complete puzzle statement and any accompanying discussion or answers. The piece is positioned as one of a sequence of bite-sized challenges intended to prompt thought about Kotlin language behavior, with the full content available via the linked Medium article.
在 Kotlin 中“throw return” 是做什么的?
“虛無回力镖(The Vacuous Boomerang)!”——Kotlin 脑筋急转弯第 16 题(共 23 题),探讨 'throw return' 的行为。

重點摘要

Sam Cooper 在 Medium 发布,题为“在 Kotlin 中‘throw return’ 是做什么的?”。
属于 Kotlin Brain Teasers 系列,第 16 题(共 23 题),标题为“The Vacuous Boomerang!”。
摘录为谜题提示,读者需到 Medium 阅读完整题目与讨论。
这篇由 Sam Cooper 在 Medium 发布的短文,题为“在 Kotlin 中‘throw return’ 是做什么的?”,为 Kotlin Brain Teasers 系列的第 16 题(共 23 题),并以“The Vacuous Boomerang!”为题。摘录以简短的脑筋急转弯形式提出问题,指向 Kotlin 中 'throw return' 的行为,但片段本身没有给出完整解释或答案,而是引导读者继续在 Medium 上查看完整的题目内容和相关讨论。该文章作为一系列简短题目之一,旨在激发对 Kotlin 语言行为的思考。
在 Kotlin 中「throw return」是做什麼的?
「虛無回力鏢(The Vacuous Boomerang)!」——Kotlin 腦筋急轉彎第 16 題(共 23 題)詢問 'throw return' 的行為。

重點摘要

由 Sam Cooper 在 Medium 發表,題為「在 Kotlin 中『throw return』是做什麼的?」
屬於 Kotlin Brain Teasers 系列,第 16 題(共 23 題),標題為「The Vacuous Boomerang!」。
摘錄為謎題提示,並引導讀者到 Medium 閱讀完整內容與討論。
這篇由 Sam Cooper 在 Medium 發表的短文,標題為「在 Kotlin 中『throw return』是做什麼的?」,為 Kotlin Brain Teasers 系列中的第 16 題(共有 23 題),並以「The Vacuous Boomerang!」為題。摘錄本身以簡短的腦筋急轉彎形式提出問題,詢問 Kotlin 中 'throw return' 的行為細節,但節錄並未在原文片段內提供完整解說或解答,而是引導讀者點選連結至 Medium 查看完整題目與後續討論。此篇作為一系列短題目之一,旨在激發對 Kotlin 語言行為的思考。

Stop Lying to Yourself: Why “I’ll Fix It Later” is a Myth (And How to Kill It)

Stop Lying to Yourself: Why “I’ll Fix It Later” is a Myth (And How to Kill It)
It’s 11 PM, the feature must ship tomorrow, so you compromise and start writing code you’ll ‘fix later.’

重點摘要

Postponing fixes with “I’ll fix it later” enables rushed compromises.
Deferring work accumulates technical debt and lowers quality.
The article offers ways to break the habit and prevent recurring last‑minute trade‑offs.
In this article the author challenges the common developer rationalization “I’ll fix it later,” opening with a familiar scene: it’s late, a feature must ship tomorrow, and you hastily code a compromise. The piece argues that treating future time as a guarantee is a myth that allows recurring shortcuts, creates technical debt, and degrades product quality. Rather than accepting the pattern as inevitable, the author highlights the real costs of deferral and emphasizes accountability for addressing issues promptly. The title’s parenthetical promise—“And How to Kill It”—signals that the article moves beyond diagnosis to present practical approaches for eliminating the reflex to postpone fixes, helping practitioners avoid repeated last‑minute compromises and ship more sustainable, higher‑quality code.
别再自欺:为什么“我以后再修”是个迷思(以及如何根除)
晚上11点,功能明天要上线,你妥协开始写明知道以后会再修的代码。

重點摘要

“以后再修”的想法助长了仓促的妥协。
推迟修正会累积技术债并降低质量。
文章提出方法,帮助打破这一拖延惯性。
作者以常见情境切入:为赶明天上线的功能,深夜妥协写出需要“以后再修”的代码,指出这种自我安慰是个误区。文章论述将问题留给未来只会导致反复的权衡、累积技术债并影响产品质量,而所谓的“以后”并不能自动修补当前的妥协。除了说明拖延带来的代价外,作者也在标题暗示下提供了可行的做法,旨在帮助开发者摆脱“以后再修”的惯性,减少临时折衷,以更可持续、更高质量的方式交付代码。
別再自欺:為何「以後再修」是迷思(以及如何根除)
深夜十一點,功能明天要上線,你妥協開始寫明知道以後會再修的程式碼。

重點摘要

以後再修的心態促成倉促妥協。
拖延修正會累積技術負債並降低品質。
作者提出實際做法,幫助擺脫這種習慣。
作者以熟悉的場景開場:深夜為了趕明天上線的功能而妥協寫出需要「以後再修」的程式碼,指出這種自我安慰其實是一種迷思。文章說明把問題留給未來只會造成重複性的折衷、累積技術負債並降低產品品質,而未來並不會自動補救當下的妥協。除了解剖這個行為模式帶來的代價外,標題所承諾的「如何根除」也表明作者提供可行的方法,目的在幫助開發者改變習慣、減少臨時讓步,進而以更可持續且高品質的方式交付功能。

Generated by Kotlin News Summarizer with AI Summaries