HttpServletRequest对象常用功能_动力节点Java学院整理
作者:fjdingsd 发布时间:2022-01-05 10:37:08
使用HttpServletRequest可以防止盗链行为,什么是盗链行为,比如说在一个别的网站上超链接,指向我们的网页中的某个数据,这样从他的网页上就可以直接进入到我的某个页面,无需从我的指定路口进入:
例如在一个简单的1.html文件中加入了我的【myservlet】web应用下的某个Servlet访问的超链接:
如果我的Servlet中代码仅仅为为访问输出数据,例如:
response.setContentType("text/html;charset=utf-8");
String data ="银魂真是一部好动漫";
response.getWriter().write(data);
那么点击这个超链接肯定会访问到这个Servlet:
那么我们如果不想被比人直接通过地址访问或者超链接访问怎么办呢:
记得学习HTTP协议中的“referer”请求头吗,这个请求头是告诉服务器该请求是从哪个URL发来的,那么我们就可以根据这个URL来判断是否是我们允许的请求地址来控制服务器是否将响应发送回去。
代码如下:
String reqUrl = request.getHeader("referer");
if(reqUrl==null || !reqUrl.startsWith("http://localhost:8080/myservlet/index.jsp")){
response.sendRedirect("/myservlet/index.jsp");
return ;
}
response.setContentType("text/html;charset=utf-8");
String data ="银魂真是一部好动漫";
response.getWriter().write(data);
在if判断中判断是否为空是防止直接将该web资源以输入URL地址直接访问,而另一个判断是防止访问该web资源不是从指定的地方来访问进来。
通过该代码,如果我们继续在1.html页面中点击超链接,则会自动跳转到我们设置好的index.jsp中:
而如果我们直接在浏览器中访问Servlet也是会跳到这个页面的。
只有在index.jsp中点击我们设置好的超链接,才能访问到:
接下来,我们来讨论的使用HttpServletRequest响应对象来获取表单数据,这是非常重要的知识点,表单提交的数据根据提交方式的不同会放置在不同位置,例如采用POST方式则会将这些数据放置在HTTP请求数据实体中,无论采用哪种方式,都是可以用响应对象的getParameter(String)等等方式获取,这点在《Servlet的学习(十)》中已经介绍。
现在,我们在需要新创建一个HTML页面编写我们的表单代码,和一个Servlet作为服务器端接收表单提交的数据,将Servlet命名为ServletRequest,而表单的传送服务器和选择HTTP方式如下:
<form action="/myservlet/servlet/ServletRequest" method="post">
先来看
<input type="text" name="user" />
<input type="password" name="password" />
这两种常见的输入字符情况。
当然还需要在表单中提供具有提交功能的标签才能提交,我们选择
<input type="submit" value="提交" >
这样的提交方式,效果如下:
在表单中这两个都可以直接通过getParameter(String)方法获取用户输入的数据,代码如下:
String username = request.getParameter("user");
String password = request.getParameter("password");
只要我们在用户名和密码中输入数据,再点击提交,就可以将用户名和密码中的数据传递给服务器:
同时,由原来的表单的HTML页面会自动跳转到该Servlet的页面上。
对于text和password两种表单方式的健壮性判断:
依据:
1、如果表单中用户名和密码不填,那么直接提交后会是传递给服务器空字符串。
2、如果不是在表单,而是知道了平常表单提交后会跳转的Servlet页面,那么直接输入该Servlet地址则是传递Null给服务器
因此必须加入健壮性语句:
String username = request.getParameter("user");
if(username!=null && !username.trim().equals("")) {
System.out.println("user:"+username);
}
password部分代码同理。
接下来是单选按钮,比如性别选择:
性别 <input type="radio" name="gender" value="male"/>男
<input type="radio" name="gender" value="female"/>女
只有<input type=”radio”>标签中的”name”属性一样,才能具有单选的功能,同时”name”属性也是在Servlet中获取用户单选数据的重要参数,代码:
String gender = request.getParameter("gender");
如果单选没有选择任何选项,则提交会返回null,所以需加入健壮性语句:
String gender = request.getParameter("gender");
if(gender != null) {
System.out.println(gender);
}
接下来是下拉列表,下拉列表可以是作为选择城市,如:
城市<select name="city">
<option value="none">--选择城市--</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="hangzhou">杭州</option>
<option value="amoy">厦门</option>
</select>
由<select>标签中的”name”属性作为Servlet中服务器获取客户端发来的下来列表数据的重要参数,代码如下:
String city = request.getParameter("city");
System.out.println(city);
由于下拉列表会默认选择其第一个<option>标签的内容,所有即使我们没有进行任何选择,也是会传递值得,这里可以无需健壮性判断。
接下来是复选框,复选框可以是一些所学技能,或者兴趣爱好,如:
<input type="checkbox" name="hobby" value="sing">唱歌
<input type="checkbox" name="hobby" value="surf">冲浪
<input type="checkbox" name="hobby" value="swim">游泳
由<input type=”checkbox”>标签中的name属性决定了这些复选框是否属于同一个复选框组,也是同时也是作为Servlet中获取表单复选框的数据的重要参数,由于多个参数使用同一个参数名,所以必须使用getParameterValues(String)方法来获取所有的被勾选的复选框,代码如下(包含健壮性):
String[] hobbies = request.getParameterValues("hobby");
for(int i=0;hobbies!=null&&i<hobbies.length;i++) {
System.out.println(hobbies[i]);
}
如果没有勾选任何一个复选框,则不会向服务器Servlet传送任何数据。所以如果直接接收可能会发生空指针异常,必须判断是否接收到的字符串数组有数据(hobbies!=null)。
重要:
现在,我们再重新回到<input type="text" name="user" /> 上,如果我们输入的是中文数据,点击提交之后会是怎样?
在控制台看到的结果:
结果就是出现了中文乱码问题。这是浏览器在发送时通常要看当时的编码,如:
或者:
但是!!
在Servlet收到request请求对象发来的数据时,通过getParameter方法是默认查询“ISO-8859-1”码表的,所以造成了编码不一致!
解决方式也很简单,只要在Servlet中将获取的request对象选择正确的解码方式即可,只要在代码前添加一句:
request.setCharacterEncoding("UTF-8");
就可以获取表单中正确的中文数据了:
注意,对于响应对象的setCharacterEncoding方法只对HTTP协议的POST方式有效,对GET方式无效。
如果我们将表单提交方式改为GET,那么提交表单中有中文数据的话依然在Servlet中会出现乱码。
如果想使GET方式也不会出现中文乱码,并没有好的捷径方法。先要通过getParameter获取请求数据(这时在Servlet中以ISO8859码表进行解码),然后再通过ISO8859进行编码成字节数组,最后通过创建字符串对象的方式选择UTF-8解码表解出最开始客户端编码的数据。
代码如下:
String userTemp = request.getParameter("user");
String username = new String(userTemp.getBytes("ISO8859-1"),"utf-8");
即可。
当然这种方式对POST方式也是有效的。
另外一种对GET方式是修改Tomcat中的配置文件(这种方式只适合GET方式,用POST方式还是会乱码)。通过Tomcat服务器的首页,选择“Configuration”查看配置文档,选择“Connector”下的“HTTP”:
在这个文档中有一个URIEncoding属性,是指可以在server.xml文件中配置这个属性,如果没有这个属性,则Tomcat默认采用ISO8859-1编码:
通过在server.xml文件中的<connector>标签中添加设置即可:
由于是在Tomcat中修改server.xml文件,所以服务器需要重启。
经过这种方式,就无需在代码中再设置任何编码表,所有在服务器端都会采用“URIEncoding”属性设置的码表。但这个方式不建议使用。
同样在“Configuration”的配置文档中的“Connector”下的“HTTP”说明文档中,有useBodyEncodingForURI这么个属性:
当在server.xml文件中的<connector>标签中添加设置了这个属性,还未完成:
还必须在Servlet中同时调用了响应对象的setCharacterEncoding方法,就能再次使GET方式不会出现乱码:
request.setCharacterEncoding("utf-8");
String username = request.getParameter("user");
同样,这种配置server.xml文件的方式依然不建议采用。
最后说明一点,在HTML编程中,我们也可以使用超链接来提交数据,当然这样的方式属于HTTP中的GET方式,原理类似于在浏览器地址URL后手动添加参数,比如如下代码:
<a href="/myservlet/servlet/ServletRequest?user=银魂" >用户名为中文</a>
跟随的参数为中文!!
两种解决方式:
1、在这个超链接上必须将这个中文进行URL编码,必须在JSP中进行编写(在后面的篇章中会介绍如何使用);
2、或者使用上述GET处理中文乱码的第一种方式,进行双次编码:
String userTemp = request.getParameter("user");
String username = new String(userTemp.getBytes("ISO8859-1"),"utf-8");
也是可以的。


猜你喜欢
- 一、抽象类1.抽象类1.1抽象类的定义在Java面向对象当中,所有的对象都是用过类进行描绘的,但是并不是所有的类都是用来描绘对象的,如果一个
- 函数名称 说明ActiveKeyboardLayout 激活一个不同的键盘布局,该布局必须先由 LoadKeyBoardLayout函数装载
- 一、Tomcat集成使用的成本越低,内部封装越复杂;1、依赖层级在SpringBoot框架的web依赖包中,引入的是内嵌Tomcat组件,基
- 1.准备工作1、JDK安装2、Maven安装3、Git安装4、jenkins安装以上软件安装成功后进入jenkins进行相关配置。如果需要通
- 前言我们之前介绍了不少有关动画的篇章。前面介绍的动画都是只有一个动画效果,那如果我们想对某个组件实现一组动效,比如下面的效果,该怎么办?st
- 本文实例为大家介绍了Android自定义视图属性的方法,供大家参考,具体内容如下1. 自定义一个自己的视图类继承自Viewpublic cl
- 软件生存周期中,涉及代码运行的环节有编码、测试和维护阶段,而一套成熟的代码,在此三个阶段,数据库、日志路径、日志级别、线程池大小等配置一般会
- 1.数据类型的分类Java的数据类型主要分为两类:基本数据类型、引用数据类型Java中的字符串String属于引用数据类型。因为String
- Spring Boot 2.7.6整合redis与低版本的区别最近在写程序的时候参考了之前写过的一篇文章spring boot整合redis
- delphi dll 源码:library dllres; type char1
- 最近因为赶项目进度,因此将本来要用原生控件实现的界面,自己做了H5并嵌入webview中。发现点击H5中 input type="
- Java语言是简单的:Java语言的语法与C语言和C++语言很接近,使得大多数程序员很容易学习和使用。另一方面,Java丢弃了C++中很少使
- LongAdder实现原理图高并发下N多线程同时去操作一个变量会造成大量线程CAS失败,然后处于自旋状态,导致严重浪费CPU资源,降低了并发
- 一、new 对象的几种说法初学 Java 面向对象的时候,实例化对象的说法有很多种,我老是被这些说法给弄晕。public class Tes
- 我们已经写了一些Java程序。之前的每个Java程序都被保存为一个文件,比如Test.java。随后,该程序被编译为Test.class。我
- 目录前言asyncawait从以往知识推导创建异步任务创建异步任务并返回Task异步改同步说说 await Task说说 async Tas
- PowerPoint幻灯片中可插入公式,用于在幻灯片放映时演示相关内容的论证、推算的依据,能有效地为演讲者提供论述的数据支撑。通过后端程序代
- 背景以springboot为tomcat启动的框架,以angular2为前端页面的框架,最后需要将angular2的代码运行在springb
- 前言我们在日常的开发过程中针对一些字段采用整型的方式去代替某些具体的含义,比如性别0代表男,1代表女。如果只是一些不会变更的转译我们可以采用
- 末日这天写篇博客吧,既然没来,那就纪念一下。这次谈谈自制控件,也就是自定义控件,先上图,再说1.扩展OpenFileDialog,在Open