HttpServletRequest 对象

HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息。

其他的具体方法就不详细描述了,具体方法上的使用看API,或者网上查查,有很多的。这里就介绍一下 请求方式获取参数 的问题

请求方式

根据HTTP标准,HTTP请求可以使用多种请求方法。

HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。
HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法

其实真正有多少请求方式我具体也没有详细了解过。我在这里就详细介绍一下经常的能接触到的请求.

GET:从服务器取出资源

POST:在服务器新建一个资源

PUT:在服务器更新资源(客户端提供改变后的完整资源)

PACTH:在服务器更新资源(客户端提供改变的属性)

DELETE:从服务器删除资源

OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的

这些接口在遇到服务端是以RESTful风格命名参数的时候是很有用的。这点其实可以参考阮一峰大神的《RESTful API 设计指南》,老实说这里大部分东西也是从那里剽窃来的,有些也加入自己的思考理解,也不知道对不对,说回来,读书人的这种事情能叫做抄吗(原谅我的无耻)。

其他的接口请求都是很好理解的,这里介绍一下OPTIONS,平常好像真的没怎么遇到过这个请求,理解上“获取信息”的请求,有些不知所谓。
其实不是的,遇到最多的请求其实是跨域的情况,在跨域的情况下,浏览器在第一次发送请求之前,会发送一个OPTIONS的请求方式的请求。(当然这里指的是非简单请求)。我们称之为“预检请求”,好了我又想抄了《跨域资源共享 CORS 详解》,阮一峰大神出品(感觉我像死忠粉一样)。

虽然浏览器做了预检请求,但是这时候需要服务端的配合

public class SimpleCORSFilter implements Filter
{@Overridepublic void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)throws IOException, ServletException{HttpServletResponse response = (HttpServletResponse) res;  response.setHeader("Access-Control-Allow-Origin", "*");  response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");  response.setHeader("Access-Control-Max-Age", "3600");  response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Cache-Control, token");chain.doFilter(req, res);}@Overridepublic void destroy(){// TODO Auto-generated method stub}@Overridepublic void init(FilterConfig arg0) throws ServletException{// TODO Auto-generated method stub}}

需要追加一个这样的过滤器,具体xml配置自行解决吧。

参数解释:

Access-Control-Allow-Origin:

这个Header是用来告诉浏览器,我的这个URL的资源是允许任何来源的请求访问我,如果值是*则表示表示接受任意域名的请求。

Access-Control-Allow-Methods:

顾名思义,表明服务器支持的所有跨域请求的方法。

Access-Control-Max-Age:

用来指定本次预检请求的有效期,单位为秒。在上面的设置中,即允许缓存该条回应为3600秒,在此期间不用发出另一条预检请求。

Access-Control-Allow-Headers:

表明服务器支持的所有头信息字段,不限于浏览器在”预检”中请求的字段。原文:The Access-Control-Allow-Headers header is used in response to a preflight request to indicate which HTTP headers can be used when making the actual request.

这里是关于跨域请求的事情了,扯远了。

Request请求在body体中获取参数

在Request请求获取参数的方式多种多样
这里我就给几个链接吧《Spring Controller 获取请求参数的几种方法》,《springmvc请求参数获取的几种方法》

这里想要说明一下request.getParameter(),request.getInputStream(),request.getReader()中request.getInputStream(),request.getReader()这两种方式。

这两个方法都是将request当做一个流对象来获取数据,区别呢是getInputStream 字节流得到的对象是InputStream对象,如果里边有二进制的话只能用这个读,getReader 字符流得到的是Reader对象,会按照请求消息中指定的字符集编码转换成文本字符串。 对于对于流来说我们可以把他们理解成管道,既然是管道,那么只能读取一次,第一次读取的时候可以读取到数据,但是接下来的读取操作都读取不到数据。

原因:

1 . 一个InputStream对象在被读取完成后,将无法被再次读取,始终返回-1;
2 . InputStream并没有实现reset方法(可以重置首次读取的位置),无法实现重置操作;

解决方法

1.使用request、session等来缓存读取到的数据,这种方式很容易实现,只要setAttribute和getAttribute就行(但是这样写未免太不优雅了);

2.使用HttpServletRequestWrapper来包装HttpServletRequest,在MAPIHttpServletRequestWrapper中初始化读取request的InputStream数据,以byte[]形式缓存在其中,然后在Filter中将request转换为包装过的request(强烈推荐如下放大);代码如下:

重写request

public class MAPIHttpServletRequestWrapper extends HttpServletRequestWrapper {  private final byte[] body; // 报文  public MAPIHttpServletRequestWrapper(HttpServletRequest request) throws IOException {  super(request);  body = StreamUtil.readBytes(request.getInputStream());  }  @Override  public BufferedReader getReader() throws IOException {  return new BufferedReader(new InputStreamReader(getInputStream()));  }  @Override  public ServletInputStream getInputStream() throws IOException {  final ByteArrayInputStream bais = new ByteArrayInputStream(body);  return new ServletInputStream() {  @Override  public int read() throws IOException {  return bais.read();  }  };  }  }  

配置相应过滤器

public class HttpServletRequestReplacedFilter implements Filter {  @Override  public void destroy() {  }  @Override  public void doFilter(ServletRequest request, ServletResponse response,  FilterChain chain) throws IOException, ServletException {  ServletRequest requestWrapper = null;    if(request instanceof HttpServletRequest) {    requestWrapper = new MAPIHttpServletRequestWrapper((HttpServletRequest) request);    }    if(requestWrapper == null) {    chain.doFilter(request, response);    } else {    chain.doFilter(requestWrapper, response);    }    }  @Override  public void init(FilterConfig arg0) throws ServletException {  }  }  

最后注意 request.getParameter()、 request.getInputStream()、request.getReader()这三种方法是有冲突的,因为流只能被读一次。
比如:

当form表单内容采用 enctype=application/x-www-form-urlencoded编码时,先通过调用request.getParameter() 方法得到参数后,再调用 request.getInputStream()或request.getReader()已经得不到流中的内容,因为在调用 request.getParameter()时系统可能对表单中提交的数 据以流的形式读了一次,反之亦然。

当form表单内容采用 enctype=multipart/form-data编码时,即使先调用request.getParameter()也得不到数据,但是这时调用 request.getParameter()方法对 request.getInputStream()或request.getReader()没有冲突,即使已经调用了 request.getParameter()方法也 可以通过调用request.getInputStream()或request.getReader()得 到表单中的数据,而request.getInputStream()和request.getReader()在同 一个响应中是不能混合使用的,如果混合使用就会抛异常。
此处参考了

https://www.cnblogs.com/v5hanhan/p/5646054.html

https://www.cnblogs.com/fzng/p/7227787.html?utm_source=itdadao&utm_medium=referral

转载于:https://www.cnblogs.com/liyunq/p/9724605.html

HttpServletRequest 对象相关推荐

  1. javaweb学习总结(十)——HttpServletRequest对象(一)

    2019独角兽企业重金招聘Python工程师标准>>> 一.HttpServletRequest介绍 HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协 ...

  2. httpservletrequest_了解HttpServletRequest 对象 基本应用

    HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发⼈员通过这个对象的⽅法,可以获得客户这些信息.简单来说 ...

  3. spring几种获取 HttpServletRequest 对象的方式

    以下的 request 实例都编号了,一共 4 种 方式 1.@Autowired 方式 2.public void Test(HttpServletRequest request1, HttpSer ...

  4. javaweb学习总结(十):HttpServletRequest对象(一)

    一.HttpServletRequest介绍 HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象 ...

  5. javaweb学习总结(十)——HttpServletRequest对象(一)(转)

    (每天都会更新至少一篇以上,有兴趣的可以关注)转载自孤傲苍狼 一.HttpServletRequest介绍 HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器 ...

  6. java面试题8 牛客:在Web应用程序中,( )负责将HTTP请求转换为HttpServletRequest对象

    在Web应用程序中,(    )负责将HTTP请求转换为HttpServletRequest对象 A Servlet对象 B HTTP服务器 C Web容器 D JSP网页 首先我们来看看web程序的 ...

  7. Java Web学习总结(7)——HttpServletRequest对象

    一.HttpServletRequest介绍 HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象 ...

  8. HttpServletRequest对象

    一.HttpServletRequest介绍 HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象 ...

  9. HttpServletRequest对象,请求行、请求头、请求体

    HttpServletRequest 公共接口类HttpServletRequest继承自ServletRequest.客户端浏览器发出的请求被封装成为一个HttpServletRequest对象.对 ...

最新文章

  1. javascript中break和continue
  2. java重写6,java重写equals()方法和hashCode()方法
  3. jQuery框架学习第五天:事件与事件对象
  4. Keil5配置GCC编译器编译STM32工程
  5. 利用模态DIV结合UpdateProgress防止页面重复提交
  6. 几何求交(一):直线和直线的交点
  7. 8700k超频测试软件,双节+双核,i7 8700k +Z370 Extreme4超频测试
  8. qt 5.12.1 下载安装详细教程
  9. c语言学籍信息系统,c语言学籍信息管理系统设计
  10. 无法获得VMCI 驱动程序的版本: 句柄无效。解决方法
  11. 微信小程序扫描程序码携带参数
  12. 零和博弈思维模式:选择即博弈,无法逃脱的思想牢笼
  13. OSChina 周六乱弹 —— 给你看个小仙女
  14. 室外管线lisp_AutoLISP语言在化工工艺室外管线设计中的应用
  15. 论文解读| NeurIPS 2022:面向科学任务的图神经网络设计
  16. Win10 LTSB/LTSC 录音机、图片查看器、便签
  17. 开源项目SMSS开发指南(二)——基于libevent的线程池
  18. Web 安全恩仇录:漏洞原理
  19. mkdir -p的用法
  20. 使用jenkins去gitlab拉取代码并部署到服务器

热门文章

  1. MongoDB常用操作总结
  2. Go 语言开发第一天,我的学习之路从这里开始
  3. Java冒泡实现类Collections.sort()
  4. localStorage.setItem()前后端分离情况下使用
  5. vmware配置centos7网络
  6. ionic4集成高德地图踩坑(二)
  7. 使用bakefile编译C工程代码
  8. 设置函数环境——setfenv(转)
  9. 纯css3天气动画场景特效
  10. yum 安装报Header V3 DSA signature: NOKEY 的错