Servlet第四篇【request对象常用方法、应用】

什么是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方法
  • getParameterValues(String name)方法
  • getParameterNames方法
  • getParameterMap方法

HttpServletRequest应用

防盗链

什么是防盗链呢?比如:我现在有海贼王最新的资源,想要看海贼王的要在我的网页上看。现在别的网站的人看到我有海贼王的资源,想要把我的资源粘贴在他自己的网站上。这样我独家的资源就被一个CTRL+C和CTRL+V抢走了?而反盗链就是不能被他们CRTL+C和CRTL+V

下面我模拟一下场景。现在我首页先有一个超链接,指向着海贼王最新资源
在这里插入图片描述
当我点进去,就能看到海贼王最新资源了
在这里插入图片描述
其他的人可以通过复制粘贴我的地址,放到它们的网页上
在这里插入图片描述
这样我就划不来啦【我的广告你来没看呢!】。想要看我的资源,就必须经过我的首页点进去看。

想要实现这样的效果,就要获取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;charset=UTF-8");response.getWriter().write("路飞做了XXXXxxxxxxxxxxxxxxxx");

首先按正常预想的,别人从首页点击我的资源,访问我海贼王最新的资源
在这里插入图片描述
能够成功访问到资源
在这里插入图片描述
如果我在浏览器直接输入地址【此时Referer是为null的】,我们来看看
在这里插入图片描述
跳回到首页上,不能访问到海贼王资源
在这里插入图片描述
再试试,如果别人粘贴了我的资源url,在它的网页上挂了一个网址呢。
在这里插入图片描述
在别人网页上点击的时候
在这里插入图片描述
又跳回到了我的首页了。
在这里插入图片描述

表单提交数据【通过post方式提交数据】


<form action="/zhongfucheng/Servlet111" method="post"><table><tr><td>用户名</td><td><input type="text" name="username"></td></tr><tr><td>密码</td><td><input type="password" name="password"></td></tr><tr><td>性别</td><td><input type="radio" name="gender" value="男"><input type="radio" name="gender" value="女"></td></tr><tr><td>爱好</td><td><input type="checkbox" name="hobbies" value="游泳">游泳<input type="checkbox" name="hobbies" value="跑步">跑步<input type="checkbox" name="hobbies" value="飞翔">飞翔</td></tr><input type="hidden" name="aaa" value="my name is zhongfucheng"><tr><td>你的来自于哪里</td><td><select name="address"><option value="广州">广州</option><option value="深圳">深圳</option><option value="北京">北京</option></select></td></tr><tr><td>详细说明:</td><td><textarea cols="30" rows="2" name="textarea"></textarea></td></tr><tr><td><input type="submit" value="提交"></td><td><input type="reset" 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?username=xxx">使用超链接将数据带给浏览器</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 port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="utf-8"/>

设置了编码后,没有做任何手工转换,成功拿到数据

在这里插入图片描述
当然也有另一种改服务器编码的方式。设置Tomcat的访问该端口时的编码为页面的编码,这种改法是随着页面的编码而变

    <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" useBodyEncodingForURI="true" />

设置编码为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对象可以传递各种类型的数据,包括对象
  • 重定向只能传递字符串

跳转的时间不同

  • 转发时:执行到跳转语句时就会立刻跳转
  • 重定向:整个页面执行完之后才执行跳转

转发和重定向使用哪一个?

根据上面说明了转发和重定向的区别也可以很容易概括出来。转发是带着转发前的请求的参数的。重定向是新的请求。

典型的应用场景:

  1. 转发: 访问 Servlet 处理业务逻辑,然后 forward 到 jsp 显示处理结果,浏览器里 URL 不变
  2. 重定向: 提交表单,处理成功后 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,成功把网头和网尾包含了
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/557179.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java 设置控制台标题_修改Tomcat控制台标题以及标题乱码处理

双击“startup.bat”启动Tomcat&#xff0c;控制台默认标题是Tomcat&#xff0c;如下图&#xff1a;修改标题很容易&#xff0c;编辑catalina.bat这个文件(跟startup.bat在同级目录下)&#xff0c;编辑的时候建议使用notepad、editplus之类的工具。然后找到如下代码片段(大约在…

Servlet第五篇【介绍会话技术、Cookie的API、详解、应用】

什么是会话技术 基本概念: 指用户开一个浏览器&#xff0c;访问一个网站,只要不关闭该浏览器&#xff0c;不管该用户点击多少个超链接&#xff0c;访问多少资源&#xff0c;直到用户关闭浏览器&#xff0c;整个这个过程我们称为一次会话. 为什么我们要使用会话技术&#xff1…

Servlet第六篇【Session介绍、API、生命周期、应用、与Cookie区别】

什么是Session Session 是另一种记录浏览器状态的机制。不同的是Cookie保存在浏览器中&#xff0c;Session保存在服务器中。用户使用浏览器访问服务器的时候&#xff0c;服务器把用户的信息以某种的形式记录在服务器&#xff0c;这就是Session 如果说Cookie是检查用户身上的”…

Tomcat+Servlet面试题都在这里

下面是我整理下来的Servlet知识点: 图上的知识点都可以在我其他的文章内找到相应内容。 Tomcat常见面试题 Tomcat的缺省端口是多少&#xff0c;怎么修改 找到Tomcat目录下的conf文件夹进入conf文件夹里面找到server.xml文件打开server.xml文件在server.xml文件里面找到下列…

java sdk下载_Java Sdk下载 | 保利威帮助中心

播放界面开发前准备1.小程序微信开发者后台设置-开发设置-服务器域名中配置 [request合法域名]开始开发1.获取频道直播播放地址index.wxmlindex.js选项说明uid类型&#xff1a;String说明&#xff1a;直播账户idvid类型&#xff1a;String说明&#xff1a;直播频道idvideoConte…

mysql union 与 union all 语法及用法

1.mysql union 语法 mysql union 用于把来自多个select 语句的结果组合到一个结果集合中。语法为&#xff1a; select column,......from table1union [all]select column,...... from table2...在多个select 语句中&#xff0c;对应的列应该具有相同的字段属性&#xff0c…

Golang基础知识入门详解

Go语言入门 Go语言入门教程 很多人将 Go 语言 称为 21 世纪的 C 语言&#xff0c;因为 Go 不仅拥有 C 语言的简洁和性能&#xff0c;而且还很好的提供了 21 世纪互联网环境下服务端开发的各种实用特性&#xff0c;让开发者在语言级别就可以方便的得到自己想要的东西。 在 Go…

udp模拟tcp java_Java简单实现UDP和TCP

TCP实现TCP协议需要在双方之间建立连接&#xff0c;通过输入输出流来进行数据的交换&#xff0c;建立需要通过三次握手&#xff0c;断开需要四次挥手&#xff0c;保证了数据的完整性&#xff0c;但传输效率也会相应的降低。简单的TCP实现//服务端public class TcpServer {publi…

ant java 返回_使用Ant自动化我们的java项目生成

现在我们已经了解如何定义属性、依赖关系以及如何运行ant&#xff0c;接下来我们将学习怎样使用ant编译java源代码并生成jar文件。编译源代码由于Ant的主要目标就是生成java应用程序&#xff0c;它内置了javac任务来调用java的编译器。此任务一般定义如下Ant会寻找src目录下所有…

Spring boot自定义启动字符画(banner)

其实很好改&#xff0c;只需要在resources下新建一个txt文件就可以&#xff0c;命名为banner.txt&#xff0c;那这种字符该怎么拼出来呢&#xff0c;下面推荐一个网址&#xff0c;有这种工具&#xff0c;链接传送门&#xff1a;打开传送门 直接输入要生成的字母&#xff0c;系…

模拟天天酷跑游戏java_cocos2d 简单高仿天天酷跑游戏

1.先直接上视频来看下这个游戏的样子(GIF已经不能满足这个游戏的展示了)跑酷游戏最纠结的是地图&#xff0c;碰撞倒是简单&#xff0c;可以自己写或者使用box2d等物理引擎。跑酷游戏地图的特点就是随机性。但是随机中又有策划特意安排的部分&#xff0c;这样让玩家有小小惊喜。…

spring源码阅读--aop实现原理分析

aop实现原理简介 首先我们都知道aop的基本原理就是动态代理思想&#xff0c;在设计模式之代理模式中有介绍过这两种动态代理的使用与基本原理&#xff0c;再次不再叙述。 这里分析的是&#xff0c;在spring中是如何基于动态代理的思想实现aop的。为了方便了解接下来的源码分析…

java muki_再次学习 java 类的编译

做JAVA开发的都知道myeclipse&#xff0c; 我们在myeclipse中新建一个类&#xff0c;然后保存&#xff0c; 如何正常的话&#xff0c;那么在项目指定的目录(也就是项目的output目录)就会生成同名的class文件&#xff0c;可是&#xff0c;我们都知道myeclipse中的类的编译的原理…

spring源码阅读--@Transactional实现原理

Transactional注解简介 Transactional是spring中声明式事务管理的注解配置方式&#xff0c;相信这个注解的作用大家都很清楚。Transactional注解可以帮助我们把事务开启、提交或者回滚的操作&#xff0c;通过aop的方式进行管理。通过Transactional注解就能让spring为我们管理事…

MySQL 普通索引和唯一索引的区别详解

1 概念区分 普通索引和唯一索引 普通索引可重复&#xff0c;唯一索引和主键一样不能重复。 唯一索引可作为数据的一个合法验证手段&#xff0c;例如学生表的身份证号码字段&#xff0c;我们人为规定该字段不得重复&#xff0c;那么就使用唯一索引。&#xff08;一般设置学号字…

win8.1已阻止java_win8系统下打开java程序时出现应用程序已被安全设置阻止的解决方法...

今天和大家分享一下win7系统下打开java程序时出现应用程序已被安全设置阻止问题的解决方法&#xff0c;在使用win7系统的过程中经常不知道如何去解决win7系统下打开java程序时出现应用程序已被安全设置阻止的问题&#xff0c;有什么好的办法去解决win7系统下打开java程序时出现…

MySql常用函数大全

MySql常用函数大全 MySQL数据库中提供了很丰富的函数。MySQL函数包括数学函数、字符串函数、日期和时间函数、条件判断函数、系统信息函数、加密函数、格式化函数等。通过这些函数&#xff0c;可以简化用户的操作。例如&#xff0c;字符串连接函数可以很方便的将多个字符串连接…

LINUX下用YUM安装nginx出现No package nginx available.的问题与解决方案

一、问题描述 运行命令 yum install nginx 之后出现如下图情况。 二、解决过程如下 根据问题描述可以看出&#xff0c;是yum源出了问题&#xff0c;因此我们需要捣鼓以下yum源配置。具体解决过程如下。 1.备份CentOS-Base.repo mv /etc/yum.repos.d/CentOS-Base.repo /et…

php7 cms,PHP7CMS 无条件前台GETSHELL

Version:2018-10-09//最新版中以修复此漏洞这个漏洞很简单&#xff0c;如果作者在写代码的时候考虑到一点点安全方面&#xff0c;其实都可以避免的。[PHP] 纯文本查看 复制代码// php7cms/Core/Controllers/Api/Api.php// 52~61 linepublic function save_form_data() {$rt \P…

php服务器怎么设置cookie,php服务器如何清除浏览器cookie

php服务器清除浏览器cookie的方法&#xff1a;1、设置cookie的过期时间&#xff1b;2、设置cookie的值为空&#xff0c;代码为【setcookie($cookiename, ) setcookie($cookiename, NULL);】。php服务器清除浏览器cookie的方法&#xff1a;一、设置cookie的过期时间//将过期时间…