Request是一次客户端请求,由servlet容器进行处理。它包含了客户端所有请求信息,如头部信息和消息体。而根据匹配url找到对应的serlvte,如果是HttpServlet则把客户端的信息封装成HttpServletRequest,如果是GenericServlet则封装成ServletRequest。

       HttpServletRequest生成条件

        1。该请求是一个 HTTP HTTPS请求。
        2 HTTP 方法是 POST或者get
        3。内容类型是 application/x-www-form-urlencoded。(貌似默认值,区别于multipart/related,如果是application/x-www-form-urlencoded,则会在post的时候以

a=1&b=2放在body里面,get默认直接截取查询字符生成参数到HttpServletRequest
        4。该 servlet 已经对 request对象的任意getParameter方法进行了初始调用。(意思是servlet容器已经走到这步了)

        当满足参数可用条件的时候,那么便可以通过HttpServletRequest(本身是一个HttpServlet的Servlet)以下方法获得参数:

        ■ getParameter

        ■ getParameterNames

        ■ getParameterValues

        ■ getParameterMap

       getParameterValues方法返回一个String 对象的数组,包含了与参数名称相关的所有参数值。getParameter方法的返回值必须是getParameterValues方法返回的String

象数组中的第一个值。getParameterMap方法返回请求参数的一个java.util.Map对象,其中以参数名称作为map 键,参数值作为 map 值。

       查询字符串和POST请求的数据被汇总到请求参数集合中。查询字符串数据在POST数据之前发送。例如,如果请求由查询字符串a =helloPOST 数据a=goodbye&

a=world组成,得到的参数集合顺序将是=(hello,goodbye,world)

     文件上传

       当数据是post上传的时候

           1:Content-Type必须是multipart/related

            2:@MultipartConfig或者配置的时候multipart-config

            这样子就可以吧文件写入HttpServletRequest的Part,通过以下两个方法获取

            public Collection<Part> getParts()

            public Part getPart(String name)

            MultipartConfig

            location="E:\\see",(路径包含临时文件和保存目录)maxFileSize=1024*1024,(最大上传大小单位byte)fileSizeThreshold=1024(最大上传数) fileSizeThreshold 这个不知道
             Part 类 有一些对应的方法,如

                     write(filename)如果配置了location则可以直接写filename=文件名字+后缀就行了

                     getInputStream  直接得到文件流操作他


     无论是上传文件还是参数传递,如果没有设置对应的头部multipart/related或者application/x-www-form-urlencoded,就只能自己在HttpServletReuqest.getInputStream
中得到文件流进行处理了。

          获取头和路径
                 getHeader   获取单个头key的value值,如果多个value则返回第一个
                 getHeaders  获取单个头key的value的list
                 getHeaderNames  获取key的list

                getContextPath  web服务器的url
                 getServletPath   当前servlte的url
                 getPathInfo         当serlvte是ce/* 的时候 url是ce/abc 则getPathInfo  =   /  abc 

                总符合这个定律:     requestURI = contextPath + servletPath + pathInfo

         非阻塞io

       阻塞情况(write/send/msgsnd的行为)

            与阻塞读有多少读多少不同的是,阻塞写会一直阻塞,直到所有数据都完成,再返回。这是因为,读的时候不知道需要读多少,防止一直等不到足够的数据;而写的时候是知道要写多少数据的。不过也可能被中断,大多数情况是能够写完的。

      非阻塞情况(write/send/msgsnd的行为)

         非阻塞写,就是有多少写多少。能够写多少是根据本地网络拥塞情况为标准的,当网络拥塞严重的时候,网络层没有足够的内存来进行写操作,就会出现写不完的情况;这时候,阻塞写除非被中断,都会等到数据都写完;而非阻塞写,就是能写多少算多少。

      
        非阻塞 IO 仅对在 Servlet 和 Filter(2.3.3.3 节定义的,“异步处理”)中的异步请求处理和升级处理(2.3.3.5 节定义的,“升级处理”)有效。否则,当调用 ServletInputStream.setReadListener 或
ServletOutputStream.setWriteListener 方法时将抛出 IllegalStateException。

        ReadListener 为非阻塞 IO 提供了下面的回调方法:
      ReadListener
          onDataAvailable().

               当可以从传入的请求流中读取数据时 ReadListener 的 onDataAvailable 方法被调用。当数据可读时容器初次调用该方法。当且仅当下面描述的 ServletInputStream 的 isReady 方法返回 false,容器随后将调用 onDataAvailable 方法。 onAllDataRead().当读取完注册了此监听器的 ServletRequest 的所有数据时调用 onAllDataRead 方法。

         onError(Throwable t).

             处理请求时如果有任何错误或异常发生时调用 onError 方法。容器必须线程安全的访问 ReadListener 中的方法。

     除了上述 ReadListener 定义的方法外,下列方法已被添加到 ServletInputStream 类中:

     ServletInputStream

      boolean isFinished().

              与 ServletReader/ServletInputStream 相关的请求的所有数据已经读取完时 isFinished方法返回 true。否则返回 false。
      boolean isReady().

              如果可以无阻塞地读取数据 isReady 方法返回 true。如果没有数据可以无阻塞地读取该方法返回 false。 如果 isReady 方法返回 false,调用 read 方法是非法的,且必须抛出 IllegalStateException。 void setReadListener(ReadListener listener). 设置上述定义的 ReadListener,调用它以非阻塞的方式读取数据。一旦把监听器与给定的 ServletInputStream 关联起来,当数据可以读取,所有的数据都读取完或如果处理请求时发生错误,容器调用 ReadListener 的方法。注册一个 ReadListener 将启动非阻塞 IO。 在那时切换到传统的阻塞 IO 是非法的,且必须抛出 IllegalStateException。在当前请求范围内,随后调用 setReadListener是非法的且必须抛出 IllegalStateException。

           以上api是j2ee7的

    请求数据编码
      

          许多浏览器默认是不带字符编码限定符的,如果客户端没有指定默认请求的字符编码,容器解析请求的数据是编码方式是ISO-8859-1。

          如果客户端没有设置字符编码,并使用不同的编码来编码请求数据,而不是使用上面描述的默认的字符编码 , 那 么 可 能 会 发 生 破 坏 。 为 了 弥 补 这 种 情 况 , ServletRequest 接 口 添 加 了 一 个 新 的 方 法setCharacterEncoding(String enc)。开发人员可以通过调用此方法来覆盖由容器提供的字符编码。必须在解析任何 post 数据或从请求读取任何输入之前调用此方法。此方法一旦调用,将不会影响已经读取的数据的编码。
  

    Request 对象的生命周期
       

       每个 request 对象只在 servlet service 方法的作用域内,或过滤器的 doFilter 方法的作用域内有效,除非该组件启用了异步处理并且调用了 request 对象的 startAsync 方法。在发生异步处理的情况下, request 对象一直有效,直到调用 AsyncContext complete 方法。容器通常会重复利用 request 对象,以避免创建 request对象的性能开销。开发人员必须注意的是,不建议在上述范围之外保持 startAsync 方法还没有被调用的请求对象的引用,因为这样可能产生不确定的结果。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐