专栏名称: 码农小胖哥
技术公众号:码农小胖哥
目录
相关文章推荐
51好读  ›  专栏  ›  码农小胖哥

Java Web 中对 ServletRequest 的一些非常规操作解决方案

码农小胖哥  · 掘金  ·  · 2019-10-24 05:06

正文

阅读 76

Java Web 中对 ServletRequest 的一些非常规操作解决方案

servletrequest.png

1. 前言

ServletRequest 是我们搞 Java Web 经常接触的 Servlet Api 。有些时候我们要经常对其进行一些操作。这里列举一些经常的难点操作。

2. 提取 body 中的数据

前后端交互我们会在 body 中传递数据。我们如何从 body 中提取数据。通常我们会通过 IO 操作:

   /**
      * obtain request body
      *
      * @param request the ServletRequest
      * @return body string   it maybe is   null
      */
     public static String obtainBody(ServletRequest request) {
         
         BufferedReader br = null;
         StringBuilder sb = new StringBuilder();
 
         try {
             br = request.getReader();
             String str;
             while ((str = br.readLine()) != null) {
                 sb.append(str);
             }
             br.close();
         } catch (IOException e) {
             log.error(" requestBody read error");
         } finally {
             if (null != br) {
                 try {
                     br.close();
                 } catch (IOException e) {
                     log.error(" close io error");
                 }
             }
         }
         return sb.toString();
 
     }
复制代码

看起来比较凌乱,各种异常处理, IO 开关操作,很不优雅。 如果你使用了 Java 8 你可以这样简化这种操作:

         String body = request.getReader().lines().collect(Collectors.joining()); 
复制代码

BufferedReader 提供了获取 Java 8 Stream 流的方法 lines() ,我们可以通过以上方法非常方便的获取 ServletRequest 中的 body

3. ServletRequest 中的流是一次性的

不要以为上面的读取 body 操作是完美无瑕的,这里有一个坑。 如果按照上面的操作 ServletRequest 中的 body 只能读取一次 。 我们传输的数据都是通过流来传输的。 ServletRequest 中我们实际上都是通过:

  ServletInputStream inputStream = request.getInputStream()
复制代码

来获取输入流,然后通过 read 系列方法来读取。 Java 中的 InputStream read 方法内部有一个 postion , **它的作用是标志当前流读取到的位置,每读取一次,位置就会移动一次,如果读到最后, read 方法会返回 -1 ,标志已经读取完了,如果想再次读取,可以调用 reset 方法, position 就会移动到上次调用 mark 的位置, mark 默认是 0 ,所以就能从头再读了。 能否 reset 是有条件的,它取决于 markSupported() , markSupported() 方法返回是否可以进行 mark/reset







请到「今天看啥」查看全文