从此

Java Web/Servlet、Java Network

综合/最新

Java编程专题Nginx Jetty HTTP C/SJakarta EEAndroid应用开发JDK源码Gradle构建
原则 - 首选内存用量小的Quarkus(GraalVM),次选嵌入式Jetty、Open Liberty InstantOn、Open Liberty非快速启动版。

通用

死记:
  网址编解码:
    // URI遇空格报错,故可清除左侧空格,将其他空格编码为 %2B 传至后端;若不转为URI则无需替换。
    var r = URLEncoder.encode(" https://x/path?qs=a  b ".replaceFirst("^\\s+", "").replaceAll("\\s", "+"));
    URI.create(URLDecoder.decode(r)); // 后端会自动 decode 至 "https://x/path?qs=a++b+"

注意 - HttpServletRequest.getInputStream()首次读取正常,再次读取会报 IllegalStateException ,可通过中间变量暂存。
  解决中文乱码(Java18起默认已是UTF-8/Open Liberty InstantOn需设置) - response.setContentType("text/plain; charset=utf-8");

Servlet:
  [可选配置文件]web.xml - web-app_6_1.xsd 版本列表(不存在或写高了均取最高支持版本)
  Servlet支持版本 - quarkus-undertow为4.0,Open Liberty和Jetty则为6.0。


OpenLiberty:
  OpenLiberty 官方称Ubuntu没有计划升级到JDK21 - https://github.com/OpenLiberty/ci.docker/issues/582#issuecomment-2432514946
  OpenLiberty 基于 CRIU 的快速启动容器镜像 - https://openliberty.io/docs/latest/instanton.html
  Open Liberty - App.class.getResource("/x.wasm"); // wsjar:file:/opt/ol/wlp/usr/servers/defaultServer/apps/x.war!/WEB-INF/classes/x.wasm
  path支持file和folder路径 - 

常用:
  request.getParameter("url") 会自动解码 URLEncoder.encode(request.getRequestURL().toString() + "?" + request.getQueryString(), Charset.defaultCharset());

  //  首个空参数 ?& 便于后续只处理&符号。
  var p1="k=v"; "https://example.com/path/?&" + p1 + "&" + p2;

  JAX-RS中必须调用flush()来刷新缓存区,否则响应HTTP 204: response.getWriter().print(jsScript); response.getWriter().flush();

  Cookie - response.addCookie(cv); // 无法被本请求的 request.getCookies() 感知到。
  Session - request.getSession(false) 过期设置 web.xml :
    <web-app ...>
      <session-config><session-timeout>-1</session-timeout><cookie-config><max-age>[默认]浏览器关闭JSESSIONID即失效</max-age></cookie-config></session-config>
    </web-app>
    或 session.setMaxInactiveInterval(30 * 60); // 仅生效在当前请求上下文,单位秒。
JAX-RS解决JSON Binding (JSON-B)报错 - Could not find MessageBodyWriter for response object of type: pkg.JavaRecord$OrPOJO of media type: application/json
  引入库 yasson ;若为 OpenLiberty 则添加 jsonb-3.0

JAX-RS SSE(Server-Sent Events): jakarta.ws.rs.sse.SseEventSink,也能用 Servlet 流式响应 asyncSupported=true 模拟。
  1分20秒重连问题解决 - 开长连接、关闭缓存:(尽量不要在VPN网络下测试)
location = /apis/add-video-watermark { proxy_http_version 1.1; # 默认的1.0不支持Keep-Alive,而1.1则默认处于长连接。 proxy_buffering off; # 关闭响应缓存,关闭后会连带proxy_cache也处于off,类似no-cache。 proxy_set_header Connection ''; proxy_read_timeout 500; proxy_pass http://ip:9080; # SSE不能用在try_files指令 }
必须的响应头: Content-Type: text/event-stream Cache-Control: no-cache Connection: keep-alive

其他

request网址取值:
 getServletPath():获取能够与“url-pattern”中匹配的路径,注意是完全匹配的部分,*的部分不包括。
 getPageInfo():与getServletPath()获取的路径互补,能够得到的是“url-pattern”中*d的路径部分
 getContextPath():获取项目的根路径
 getRequestURI:获取根路径到地址结尾
 getRequestURL:获取请求的地址链接(浏览器中输入的地址)
 getServletContext().getRealPath(“/”):获取“/”在机器中的实际地址
 getScheme():获取的是使用的协议(http 或https)
 getProtocol():获取的是协议的名称(HTTP/1.11)
 getServerName():获取的是域名(xxx.com)
 getLocalName:获取到的是IP