Code Life

boris1993的个人博客

我,很不幸,于 2022-12-23 夜,新冠奥密克戎发作。不过,最近记录自己被感染的生活好像是个流量密码,那我干脆也蹭一波热点,记录一下我感染之后的感受。

阅读全文 »

上个月冲动消费,入手了一台 HPE ProLiant MicroServer Gen8。其实我早想搞一台正经的服务器来玩了,因为群晖的魔改 Linux 总是玩的不那么爽。现在心愿实现,开始折腾。

本篇为二手 MicroServer Gen8 折腾记的第一篇,记录拿到服务器之后做的一些初始化的工作。

阅读全文 »

Filter

  • FilterServlet 规范制定的,受 Servlet 容器支持,接口定义在 javax.servlet 包中。
  • Filter 是被 Web Server(如 Tomcat)调用。
  • Filter 需要在 web.xml 中定义之后才会起作用。
  • Filter 只在请求的前后起作用,Servlet 对于 Filter 来说是一个黑盒。
  • Filter 的执行顺序是:
    • void init(FilterConfig) - 容器在初始化 Filter 时调用,在 Filter 生命周期内仅会被调用一次。方法可以抛出 ServletException
    • doFilter(ServletRequest, ServletResponse, FilterChain) - Web 容器每一次请求都会调用该方法。该方法将容器的请求和响应作为参数传递进来, FilterChain 用来调用下一个 Filter
    • void destroy() - 当容器销毁 Filter 实例时调用该方法,可以在方法中销毁资源,该方法在 Filter 的生命周期只会被调用一次。

Interceptor

  • InterceptorSpring 容器内的,由 Spring 框架提供支持。接口 HandlerInterceptor 定义在 org.springframework.web.servlet 包中。
  • Interceptor 是被 Spring 调用。
  • Interceptor 可以深入到方法前后、异常抛出前后等,比起 Filter 有更大的弹性。
  • Interceptor 还允许用户介入请求的生命周期,可以在请求过程中获取信息,通常与请求更加耦合。
  • Interceptor 的执行顺序是:
    • 请求到达 DispatcherServlet
    • DispatcherServlet 将请求发送至 InterceptorInterceptor 执行 preHandle() 方法
    • 请求到达 Controller
    • 请求结束后,Interceptor 执行 postHandle() 方法
阅读全文 »

就在刚刚,我一个误操作,在没有本地备份的前提下,force push 了一个 GitHub 上的仓库。万幸最后恢复成功,数据拿回来了。惊魂未定之余,在此记录我的抢救过程以供参考。

阅读全文 »

前段时间瞎折腾,给自己的黑莓 Bold 9900 写了个通过 NTP 同步时间的小工具,顺便在这里记录一下我在实现一个 NTP 客户端时对这个协议的理解。

阅读全文 »

太长不看:关闭 IPv6 或许可以解决。如果你平时要用到 IPv6,那就在更新之前先禁用 IPv6,更新完了再打开;如果开不开 IPv6 对你来说没区别的话,那永久关闭也不是不可以。当然如果你愿意,下文提到的改注册表的方案也是可用的。


这两天在给微软模拟飞行下载更新的时候,就算挂着网易 UU,速度也一直很慢,时常在 0.5MB/s~5MB/s 之间波动,不论怎么换节点也不能跑出正常的速度。今天经过一顿上网冲浪,发现这个问题的根源,在 IPv6。

其实网上针对这个问题已经有一些解决方案了,但内容看下来都一样,不外乎教你怎么关掉 IPv6。但我一方面要用到 IPv6,另一方面也不想那么粗暴的解决问题,所以又稍微做了点研究,顺便写了个小工具方便其他有这个问题的玩家。 经过一段时间的试用后发现,临时 / 永久关闭 IPv6 实际上是最优雅的方案……

阅读全文 »

联动上一篇博文,在解决了 OpenResty 上那个 SNI 的问题之后,我们发现有一个 Java 应用也有类似的问题。而最后发现,这是因为我们当前版本的 Java 中有一个 bug……

简单来说,就是在 Java 1.8u141 之前,HttpsURLConnection#setDefaultHostnameVerifier() 方法会破坏 SNI,而正好我们的代码里有这么一行:

1
HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);

翻了下框架的代码,发现如果我不设定这个值,框架也调用这个方法来指定它默认的 hostname verifier;而如果我传个 null,那么它会抛个异常给我。所以,代码层面没有很方便的解决方案。

无奈,最后决定,先临时换了个没开启 SNI 的域名,暂时解决掉问题,然后升级 Java 到 1.8u181,一劳永逸。


终于,我也有机会理直气壮地喊出 “这是 Java 的 bug” 了!(笑

[^1]: Extended server_name (SNI Extension) not sent with jdk1.8.0 but send with jdk1.7.0
[^2]: Custom HostnameVerifier disables SNI support on client in Java 8

0%