HttpServletRequest 对象
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 对象相关推荐
- javaweb学习总结(十)——HttpServletRequest对象(一)
2019独角兽企业重金招聘Python工程师标准>>> 一.HttpServletRequest介绍 HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协 ...
- httpservletrequest_了解HttpServletRequest 对象 基本应用
HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发⼈员通过这个对象的⽅法,可以获得客户这些信息.简单来说 ...
- spring几种获取 HttpServletRequest 对象的方式
以下的 request 实例都编号了,一共 4 种 方式 1.@Autowired 方式 2.public void Test(HttpServletRequest request1, HttpSer ...
- javaweb学习总结(十):HttpServletRequest对象(一)
一.HttpServletRequest介绍 HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象 ...
- javaweb学习总结(十)——HttpServletRequest对象(一)(转)
(每天都会更新至少一篇以上,有兴趣的可以关注)转载自孤傲苍狼 一.HttpServletRequest介绍 HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器 ...
- java面试题8 牛客:在Web应用程序中,( )负责将HTTP请求转换为HttpServletRequest对象
在Web应用程序中,( )负责将HTTP请求转换为HttpServletRequest对象 A Servlet对象 B HTTP服务器 C Web容器 D JSP网页 首先我们来看看web程序的 ...
- Java Web学习总结(7)——HttpServletRequest对象
一.HttpServletRequest介绍 HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象 ...
- HttpServletRequest对象
一.HttpServletRequest介绍 HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象 ...
- HttpServletRequest对象,请求行、请求头、请求体
HttpServletRequest 公共接口类HttpServletRequest继承自ServletRequest.客户端浏览器发出的请求被封装成为一个HttpServletRequest对象.对 ...
最新文章
- javascript中break和continue
- java重写6,java重写equals()方法和hashCode()方法
- jQuery框架学习第五天:事件与事件对象
- Keil5配置GCC编译器编译STM32工程
- 利用模态DIV结合UpdateProgress防止页面重复提交
- 几何求交(一):直线和直线的交点
- 8700k超频测试软件,双节+双核,i7 8700k +Z370 Extreme4超频测试
- qt 5.12.1 下载安装详细教程
- c语言学籍信息系统,c语言学籍信息管理系统设计
- 无法获得VMCI 驱动程序的版本: 句柄无效。解决方法
- 微信小程序扫描程序码携带参数
- 零和博弈思维模式:选择即博弈,无法逃脱的思想牢笼
- OSChina 周六乱弹 —— 给你看个小仙女
- 室外管线lisp_AutoLISP语言在化工工艺室外管线设计中的应用
- 论文解读| NeurIPS 2022:面向科学任务的图神经网络设计
- Win10 LTSB/LTSC 录音机、图片查看器、便签
- 开源项目SMSS开发指南(二)——基于libevent的线程池
- Web 安全恩仇录:漏洞原理
- mkdir -p的用法
- 使用jenkins去gitlab拉取代码并部署到服务器