request.getReader()的怪异事件

本文探讨了在Servlet中使用getParameterMap()与getReader()方法获取POST请求参数时出现的数据读取冲突问题。当先调用getParameterMap()后,再尝试通过getReader()获取请求体内容时会失败。解决方法是避免同时使用这两个方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Map<String, String[]> pmap = request.getParameterMap(); BufferedReader br = request.getReader(); String res = ""; while ((res = br.readLine()) != null) { System.out.println("request body:" + res); out.print("<BR/>request body:" + res); }

以上代码在servlet里可以打印出来post请求的参数吗?


答案是不可以!!

为什么呢?

这个十分怪异,找了朋友,让他们帮忙用request.getReader()获得post参数,却都告诉我可以拿到。。

我就纳闷了,我的代码哪里出了错?

于是把朋友的代码拷过来,试了一下,成了!

就是第一行的getParameterMap(),这句话把数据读了一遍之后,后面的request.getReader()拿不到了!

去掉第一行的getParameterMap()就可以了。。。。


getReader只能调用一次


原因参考API,及这个帖子http://topic.youkuaiyun.com/t/20030816/03/2152573.html



在SpringMVC中,如果需要重新设置请求体,可以使用HttpServletRequestWrapper来包装请求。首先,在自定义的Interceptor中,我们可以通过HttpServletRequest的getInputStream方法获取到请求体的内容。然而,一旦读取了请求体,后续的流程就无法再次读取了,导致请求处理失败。为了解决这个问题,我们可以使用HttpServletRequestWrapper类来对原始请求进行包装,以实现请求体的重复读取。 具体的代码如下所示: ```java public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper { private final String body; public MyHttpServletRequestWrapper(HttpServletRequest request) throws IOException { super(request); body = getRequestBody(request); } @Override public ServletInputStream getInputStream() throws IOException { final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes()); return new ServletInputStream() { @Override public int read() throws IOException { return byteArrayInputStream.read(); } }; } private String getRequestBody(HttpServletRequest request) throws IOException { // 从原始请求中获取请求体 BufferedReader reader = request.getReader(); StringBuilder sb = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { sb.append(line); } return sb.toString(); } } ``` 在Interceptor的preHandle方法中,我们可以将原始的HttpServletRequest替换为自定义的HttpServletRequestWrapper,以实现请求体的重新设置。具体代码如下所示: ```java @Component @Slf4j public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 获取请求体的内容 String body = StringUtils.EMPTY; if (request instanceof MyHttpServletRequestWrapper) { body = ((MyHttpServletRequestWrapper) request).getBody(); } // 在这里可以对请求体进行处理或重新设置 // ... return true; } } ``` 通过这种方式,我们就可以在Interceptor中重新设置请求体,并且不会影响到后续的请求处理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [在Springboot HandlerInterceptor中获取GET和POST请求参数](https://blog.csdn.net/xindoo/article/details/127464604)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [浅谈SpringMVC HandlerInterceptor诡异问题排查](https://download.csdn.net/download/weixin_38659248/12749173)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值