先说结论:springboot 2.2 ,引用的tomcat9,Http11InputBuffer 类会将head中key转小写。
解决:在项目中新建Http11InputBuffer类,保持和jar包的包路径一致,注释转小写的代码。
@PostMapping("head/{id}.json")
public String head(@RequestHeader Map<String, String> head, @PathVariable int id, @RequestBody User user, HttpServletRequest request, HttpServletResponse response) {
response.setHeader("storeId","11002054");
if (head.containsKey("storeId")) {
return head.get("storeId");
}
return user.getUserName();
}
简单测试http头部信息。
调试代码,先查看了HttpServlet方法中req参数
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {...}
这里getHeaders(),发现key已经是小写了。往上一层级追踪,应该是在tomcat接收请求时,查看最早的连接参数。
Http11Processor 类
if (!inputBuffer.parseHeaders()) { // We've read part of the request, don't recycle it // instead associate it with the socket openSocket = true; readComplete = false; break; }
tomcat在此处解析了头信息
Http11InputBuffer类
boolean parseHeaders() throws IOException { if (!parsingHeader) { throw new IllegalStateException(sm.getString("iib.parseheaders.ise.error")); } HeaderParseStatus status = HeaderParseStatus.HAVE_MORE_HEADERS; do { status = parseHeader();//这里执行解析
....
}while (status == HeaderParseStatus.HAVE_MORE_HEADERS);
}
private HeaderParseStatus parseHeader() throws IOException {
// chr is next byte of header name. Convert to lowercase. if ((chr >= Constants.A) && (chr <= Constants.Z)) { byteBuffer.put(pos, (byte) (chr - Constants.LC_OFFSET)); }
}
这段代码在 Http11InputBuffer 829-831 行