建设银行无锡分行网站,网页版游戏单机游戏,免备案空间推荐,河南seo推广平台什么是HttpServletRequest
HttpServletRequest对象代表客户端的请求#xff0c;当客户端通过HTTP协议访问服务器时#xff0c;HTTP请求头中的所有信息都封装在这个对象中#xff0c;开发人员通过这个对象的方法#xff0c;可以获得客户这些信息。
简单来说#xff0c;要…什么是HttpServletRequest
HttpServletRequest对象代表客户端的请求当客户端通过HTTP协议访问服务器时HTTP请求头中的所有信息都封装在这个对象中开发人员通过这个对象的方法可以获得客户这些信息。
简单来说要得到浏览器信息就找HttpServletRequest对象
HttpServletRequest常用方法
获得客户机【浏览器】信息
getRequestURL方法返回客户端发出请求时的完整URL。getRequestURI方法返回请求行中的资源名部分。getQueryString 方法返回请求行中的参数部分。getPathInfo方法返回请求URL中的额外路径信息。额外路径信息是请求URL中的位于Servlet的路径之后和查询参- 数之前的内容它以“/”开头。getRemoteAddr方法返回发出请求的客户机的IP地址getRemoteHost方法返回发出请求的客户机的完整主机名getRemotePort方法返回客户机所使用的网络端口号getLocalAddr方法返回WEB服务器的IP地址。getLocalName方法返回WEB服务器的主机名
获得客户机请求头
getHeader方法getHeaders方法getHeaderNames方法
获得客户机请求参数(客户端提交的数据)
getParameter方法getParameterValuesString name方法getParameterNames方法getParameterMap方法
HttpServletRequest应用
防盗链
什么是防盗链呢比如我现在有海贼王最新的资源想要看海贼王的要在我的网页上看。现在别的网站的人看到我有海贼王的资源想要把我的资源粘贴在他自己的网站上。这样我独家的资源就被一个CTRLC和CTRLV抢走了而反盗链就是不能被他们CRTLC和CRTLV
下面我模拟一下场景。现在我首页先有一个超链接指向着海贼王最新资源 当我点进去就能看到海贼王最新资源了 其他的人可以通过复制粘贴我的地址放到它们的网页上 这样我就划不来啦【我的广告你来没看呢】。想要看我的资源就必须经过我的首页点进去看。
想要实现这样的效果就要获取Referer这个消息头判断Referer是不是从我的首页来的。如果不是从我的首页来的跳转回我的首页。
//获取到网页是从哪里来的String referer request.getHeader(Referer);//如果不是从我的首页来或者从地址栏直接访问的if ( referer null || !referer.contains(localhost:8080/zhongfucheng/index.jsp) ) {//回到首页去response.sendRedirect(/zhongfucheng/index.jsp);return;}//能执行下面的语句说明是从我的首页点击进来的那没问题照常显示response.setContentType(text/html;charsetUTF-8);response.getWriter().write(路飞做了XXXXxxxxxxxxxxxxxxxx);
首先按正常预想的别人从首页点击我的资源访问我海贼王最新的资源 能够成功访问到资源 如果我在浏览器直接输入地址【此时Referer是为null的】我们来看看 跳回到首页上不能访问到海贼王资源 再试试如果别人粘贴了我的资源url在它的网页上挂了一个网址呢。 在别人网页上点击的时候 又跳回到了我的首页了。
表单提交数据【通过post方式提交数据】 form action/zhongfucheng/Servlet111 methodposttabletrtd用户名/tdtdinput typetext nameusername/td/trtrtd密码/tdtdinput typepassword namepassword/td/trtrtd性别/tdtdinput typeradio namegender value男男input typeradio namegender value女女/td/trtrtd爱好/tdtdinput typecheckbox namehobbies value游泳游泳input typecheckbox namehobbies value跑步跑步input typecheckbox namehobbies value飞翔飞翔/td/trinput typehidden nameaaa valuemy name is zhongfuchengtrtd你的来自于哪里/tdtdselect nameaddressoption value广州广州/optionoption value深圳深圳/optionoption value北京北京/option/select/td/trtrtd详细说明:/tdtdtextarea cols30 rows2 nametextarea/textarea/td/trtrtdinput typesubmit value提交/tdtdinput typereset value重置/td/tr/table
在Servlet111中获取到提交的数据代码如下
//设置request字符编码的格式request.setCharacterEncoding(UTF-8);//通过html的name属性获取到值String username request.getParameter(username);String password request.getParameter(password);String gender request.getParameter(gender);//复选框和下拉框有多个值获取到多个值String[] hobbies request.getParameterValues(hobbies);String[] address request.getParameterValues(address);//获取到文本域的值String description request.getParameter(textarea);//得到隐藏域的值String hiddenValue request.getParameter(aaa);....各种System.out.println().......
向表单输入数据 Servlet111得到表单带过来的数据最后的一个数据是隐藏域带过来的。
超链接方式提交数据
常见的get方式提交数据有使用超链接sendRedirect()
格式如下
sendRedirect(servlet的地址?参数名参数值 参数名参数值);
我们来使用一下通过超链接将数据带给浏览器
a href/zhongfucheng/Servlet111?usernamexxx使用超链接将数据带给浏览器/a
在Servlet111接收数据
//接收以username为参数名带过来的值String username request.getParameter(username);System.out.println(username);
注意看浏览器左下角 服务器成功接收到浏览器发送过来的数据 并且传输数据明文的出现在浏览器的地址栏上 sendRedirect()和超链接类似在这里就不赘述了
解决中文乱码问题
细心的朋友会发现我在获取表单数据的时候有这句代码request.setCharacterEncoding(“UTF-8”);如果没有这句代码会发生什么事呢我们看看。
再重新填写数据 在服务器查看提交过来的数据所有的中文数据都乱码了 来这里我们来分析一下乱码的原因在前面的博客中我已经介绍了Tomcat服务器默认编码是ISO 8859-1而浏览器使用的是UTF-8编码。浏览器的中文数据提交给服务器Tomcat以ISO 8859-1编码对中文编码当我在Servlet读取数据的时候拿到的当然是乱码。而我设置request的编码为UTF-8乱码就解决了。
接下来使用get方式传递中文数据把表单的方式改成get即可
当我们访问的时候又出现乱码了 于是我按照上面的方式把request对象设置编码为UTF-8试试
request.setCharacterEncoding(UTF-8);String name request.getParameter(name);
结果还是乱码。这是为什么呢我明明已经把编码设置成UTF-8了按照post方式乱码问题已经解决了。我们来看看get和post方式的区别在哪为什么post方式设置了request编码就可以解决乱码问题而get方式不能呢。
首先我们来看一下post方法是怎么进行参数传递的。当我们点击提交按钮的时候数据封装进了Form Data中http请求中把实体主体带过去了【传输的数据称之为实体主体】既然request对象封装了http请求所以request对象可以解析到发送过来的数据于是只要把编码设置成UTF-8就可以解决乱码问题了。 而get方式不同它的数据是从消息行带过去的没有封装到request对象里面所以使用request设置编码是无效的。 要解决get方式乱码问题也不难我们既然知道Tomcat默认的编码是ISO 8859-1那么get方式由消息体带过去给浏览器的时候肯定是用ISO 8859-1编码了。
//此时得到的数据已经是被ISO 8859-1编码后的字符串了这个是乱码String name request.getParameter(username);//乱码通过反向查ISO 8859-1得到原始的数据byte[] bytes name.getBytes(ISO8859-1);//通过原始的数据设置正确的码表构建字符串String value new String(bytes, UTF-8);
上面的代码有些难理解我画张图说明一下 经过我们手工转换再来访问一下 好的成功解决掉乱码问题了。
除了手工转换get方式还可以改Tomcat服务器的配置来解决乱码但是不推荐使用这样不灵活。“
我们都知道Tomcat默认的编码是ISO 8859-1,如果在Tomcat服务器的配置下改成是UTF-8的编码那么就解决服务器在解析数据的时候造成乱码问题了
在8080端口的Connector上加入URIEncoding“utf-8”设置Tomcat的访问该端口时的编码为utf-8从而解决乱码这种改法是固定使用UTF-8编码的
Connector port8080 protocolHTTP/1.1 connectionTimeout20000 redirectPort8443 URIEncodingutf-8/
设置了编码后没有做任何手工转换成功拿到数据 当然也有另一种改服务器编码的方式。设置Tomcat的访问该端口时的编码为页面的编码这种改法是随着页面的编码而变 Connector port8080 protocolHTTP/1.1 connectionTimeout20000 redirectPort8443 useBodyEncodingForURItrue /
设置编码为UTF-8
request.setCharacterEncoding(UTF-8);String name request.getParameter(name);
再次访问 手写超链接如果附带中文参数问题要URL重写在JSP博客中会讲到
总结
post方式直接改request对象的编码get方式需要手工转换编码get方式也可以修改Tomcat服务器的编码不推荐因为会太依赖服务器了提交数据能用post就用post
实现转发
之前讲过使用response的sendRedirect()可以实现重定向做到的功能是页面跳转使用request的getRequestDispatcher.forward(request,response)实现转发做到的功能也是页面跳转他们有什么区别呢现在我先来说下转发
代码如下所示
//获取到requestDispatcher对象跳转到index.jspRequestDispatcher requestDispatcher request.getRequestDispatcher(/index.jsp);//调用requestDispatcher对象的forward()实现转发,传入request和response方法requestDispatcher.forward(request, response);
访问Servlet111 上面已经说了可以通过sendRedirect()重定向可以在资源尾部添加参数提交数据给服务器。那么转发能不能提交数据给服务器呢
答案明显是可以的并且使用这种方法非常频繁
在讲ServletContext的时候曾经说过Servlet之间可以通过ServletContext实现通讯ServletContext也能称之为域对象。而request也可以称之为域对象只不过ServletContext的域是整个web应用而request的域仅仅代表一次http请求
下面我们来使用request实现Servlet之间的通讯Servlet111代码
//以username为关键字存zhongfucheng值request.setAttribute(username, zhongfucheng);//获取到requestDispatcher对象RequestDispatcher requestDispatcher request.getRequestDispatcher(/Servlet222);//调用requestDispatcher对象的forward()实现转发,传入request和response方法requestDispatcher.forward(request, response);
Servlet222代码
//获取到存进request对象的值String userName (String) request.getAttribute(username);//在浏览器输出该值response.getWriter().write(i am :userName);
访问Servlet111看下效果 如上图所示Servlet222成功拿到了request对象在Servlet111存进的数据。
现在问题又来了我们可以使用ServletContext和request实现Servlet之间的通讯那么我们用哪一种呢一般的原则可以使用request就尽可能使用request。因为ServletContext代表着整个web应用使用ServletContext会消耗大量的资源而request对象会随着请求的结束而结束资源会被回收。使用request域进行Servlet之间的通讯在开发中是非常频繁的。
转发的时序图 请求转发的细节
如果在调用forward方法之前在Servlet程序中写入的部分内容已经被真正地传送到了客户端forward方法将抛出IllegalStateException异常。 也就是说不要在转发之前写数据给浏览器
我们来试试是不是真的会出现异常。
OutputStream outputStream response.getOutputStream();outputStream.write(--------------------------------------------.getBytes());//关闭流确保让数据到浏览器中outputStream.close();//跳转request.getRequestDispatcher(/Foot).forward(request, response);
访问的时候看到浏览器可以输出数据Tomcat后台抛出了异常 如果在调用forward方法之前向Servlet引擎的缓冲区中写入了内容只要写入到缓冲区中的内容还没有被真正输出到客户端forward方法就可以被正常执行原来写入到输出缓冲区中的内容将被清空但是已写入到HttpServletResponse对象中的响应头字段信息保持有效。
转发和重定向的区别
实际发生位置不同地址栏不同
转发是发生在服务器的
转发是由服务器进行跳转的细心的朋友会发现在转发的时候浏览器的地址栏是没有发生变化的在我访问Servlet111的时候即使跳转到了Servlet222的页面浏览器的地址还是Servlet111的。也就是说浏览器是不知道该跳转的动作转发是对浏览器透明的。通过上面的转发时序图我们也可以发现实现转发只是一次的http请求一次转发中request和response对象都是同一个。这也解释了为什么可以使用request作为域对象进行Servlet之间的通讯。
重定向是发生在浏览器的
重定向是由浏览器进行跳转的进行重定向跳转的时候浏览器的地址会发生变化的。曾经介绍过实现重定向的原理是由response的状态码和Location头组合而实现的。这是由浏览器进行的页面跳转实现重定向会发出两个http请求request域对象是无效的因为它不是同一个request对象
用法不同
很多人都搞不清楚转发和重定向的时候资源地址究竟怎么写。有的时候要把应用名写上有的时候不用把应用名写上。很容易把人搞晕。记住一个原则给服务器用的直接从资源名开始写给浏览器用的要把应用名写上
request.getRequestDispatcher(/资源名 URI).forward(request,response) 转发时/代表的是本应用程序的根目录【zhongfucheng】response.send(/web应用/资源名 URI); 重定向时/代表的是webapps目录
能够去往的URL的范围不一样
转发是服务器跳转只能去往当前web应用的资源重定向是浏览器跳转可以去往任何的资源
传递数据的类型不同
转发的request对象可以传递各种类型的数据包括对象重定向只能传递字符串
跳转的时间不同
转发时执行到跳转语句时就会立刻跳转重定向整个页面执行完之后才执行跳转
转发和重定向使用哪一个
根据上面说明了转发和重定向的区别也可以很容易概括出来。转发是带着转发前的请求的参数的。重定向是新的请求。
典型的应用场景
转发: 访问 Servlet 处理业务逻辑然后 forward 到 jsp 显示处理结果浏览器里 URL 不变重定向: 提交表单处理成功后 redirect 到另一个 jsp防止表单重复提交浏览器里 URL 变了
RequestDispatcher再说明
RequestDispatcher对象调用forward()可以实现转发上面已经说过了。RequestDispatcher还有另外一个方法include()该方法可以实现包含有什么用呢
我们在写网页的时候一般网页的头部和尾部是不需要改变的。如果我们多个地方使用Servlet输出网头和网尾的话需要把代码重新写一遍。而使用RequestDispatcher的include()方法就可以实现包含网头和网尾的效果了。
我们来操作吧现在我有网头和网尾的Servlet 使用Servlet111将网头和网尾包含
request.getRequestDispatcher(/Head).include(request, response);response.getWriter().write(--------------------------------------------);request.getRequestDispatcher(/Foot).include(request, response);
访问一下Servlet111,成功把网头和网尾包含了