HttpServletRequest 重复读取及设置自定义header
2020/3/1 17:44:42
本文主要是介绍HttpServletRequest 重复读取及设置自定义header,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
前言
最近在开发中遇到了一个需求,需要重复读取HttpServletRequest
请求内容及设置自定义header向下传递,但是会出现Required request body is missing
,原因是ServletInputStream
的流只能读取一次,那么我们只需要让请求内容可以重复读取即可,可以通过HttpServletRequestWrapper
来实现。
实现步骤
1.自定义MutableHttpServletRequest
public class MutableHttpServletRequest extends HttpServletRequestWrapper { private final String body; private byte[] bytes; private final Map<String, String> customHeaders; public MutableHttpServletRequest(HttpServletRequest request) throws IOException { super(request); this.customHeaders = new HashMap<String, String>(); this.bytes = StreamUtils.copyToByteArray(request.getInputStream()); this.body = new String(this.bytes, StandardCharsets.UTF_8); } public void putHeader(String name, String value) { this.customHeaders.put(name, value); } @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(getInputStream(), StandardCharsets.UTF_8)); } @Override public ServletInputStream getInputStream() throws IOException { if (bytes == null) { bytes = new byte[0]; } final ByteArrayInputStream bais = new ByteArrayInputStream(bytes); return new ServletInputStream() { @Override public boolean isFinished() { return false; } @Override public boolean isReady() { return false; } @Override public void setReadListener(ReadListener readListener) { } @Override public int read() throws IOException { return bais.read(); } }; } @Override public String getHeader(String name) { String headerValue = customHeaders.get(name); if (headerValue != null) { return headerValue; } return ((HttpServletRequest) getRequest()).getHeader(name); } @Override public Enumeration<String> getHeaderNames() { Set<String> set = new HashSet<String>(customHeaders.keySet()); @SuppressWarnings("unchecked") Enumeration<String> e = ((HttpServletRequest) getRequest()).getHeaderNames(); while (e.hasMoreElements()) { String n = e.nextElement(); set.add(n); } return Collections.enumeration(set); } } 复制代码
2. MutableHttpServletRequest
使用
-
创建
filter
public class ReadRequestBodyFilter implements Filter { @Override public void init(FilterConfig filterConfiguration) throws ServletException { // do nothing } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException { request = new MutableHttpServletRequest((HttpServletRequest) request); // do nothing chain.doFilter(request, response); } @Override public void destroy() { // do nothing } } 复制代码
-
注册
filtel
@Bean public FilterRegistrationBean<BodyReaderFilter> Filters() { FilterRegistrationBean<ReadRequestBodyFilter> registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new ReadRequestBodyFilter()); registrationBean.addUrlPatterns("/*"); registrationBean.setName("readRequestBody-filter"); registrationBean.setOrder(1); return registrationBean; } 复制代码
总结
http
请求内容只能被读取一次,如果您在过滤器中读取body
,则目标servlet
将无法重新读取它,这也会导致IllegalStateException
。 使用上面给定的HttpServletRequestWrapper
,就可以读取HTTP请求正文,然后Servlet以后仍可以读取它。 本质上,请求主体内容被缓存在包装对象中,因此在整个请求生命周期中,它可以是N次。
参考文章
httpServletRequest中的流只能读取一次的原因
这篇关于HttpServletRequest 重复读取及设置自定义header的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-10-01基于Python+Vue开发的医院门诊预约挂号系统
- 2024-10-01基于Python+Vue开发的旅游景区管理系统
- 2024-10-01RestfulAPI入门指南:打造简单易懂的API接口
- 2024-10-01初学者指南:了解和使用Server Action
- 2024-10-01Server Component入门指南:搭建与配置详解
- 2024-10-01React 中使用 useRequest 实现数据请求
- 2024-10-01使用 golang 将ETH账户的资产平均分散到其他账户
- 2024-10-01JWT用户校验课程:从入门到实践
- 2024-10-01Server Component课程入门指南
- 2024-09-30Dnd-Kit学习:新手快速入门指南