Servlet的学习之Request请求对象(2)

  在上一篇《Servlet的学习(十)》中介绍了HttpServletRequest请求对象的一些常用方法,而从这篇起开始介绍和学习HttpServletRequest的常用功能。

 

  使用HttpServletRequest可以防止盗链行为,什么是盗链行为,比如说在一个别的网站上超链接,指向我们的网页中的某个数据,这样从他的网页上就可以直接进入到我的某个页面,无需从我的指定路口进入:

例如在一个简单的1.html文件中加入了我的【myservlet】web应用下的某个Servlet访问的超链接:

  

如果我的Servlet中代码仅仅为为访问输出数据,例如:

1     response.setContentType("text/html;charset=utf-8");
2     String data ="银魂真是一部好动漫";
3     response.getWriter().write(data);

那么点击这个超链接肯定会访问到这个Servlet:

  

那么我们如果不想被比人直接通过地址访问或者超链接访问怎么办呢:

  记得学习HTTP协议中的“referer”请求头吗,这个请求头是告诉服务器该请求是从哪个URL发来的,那么我们就可以根据这个URL来判断是否是我们允许的请求地址来控制服务器是否将响应发送回去。

代码如下:

1     String reqUrl = request.getHeader("referer");
2     if(reqUrl==null || !reqUrl.startsWith("http://localhost:8080/myservlet/index.jsp")){
3         response.sendRedirect("/myservlet/index.jsp");
4         return ;
5     }
6         
7     response.setContentType("text/html;charset=utf-8");
8     String data ="银魂真是一部好动漫";
9     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方式如下:

1     <form action="/myservlet/servlet/ServletRequest" method="post">

先来看

1     <input type="text" name="user" /> 
2     <input type="password" name="password" /> 

这两种常见的输入字符情况。

当然还需要在表单中提供具有提交功能的标签才能提交,我们选择

1     <input type="submit" value="提交" >

这样的提交方式,效果如下:

  

在表单中这两个都可以直接通过getParameter(String)方法获取用户输入的数据,代码如下:

1     String username = request.getParameter("user");
2     String password = request.getParameter("password");

只要我们在用户名和密码中输入数据,再点击提交,就可以将用户名和密码中的数据传递给服务器:

  

同时,由原来的表单的HTML页面会自动跳转到该Servlet的页面上。

  对于text和password两种表单方式的健壮性判断:

依据:

1,如果表单中用户名和密码不填,那么直接提交后会是传递给服务器空字符串。

2,如果不是在表单,而是知道了平常表单提交后会跳转的Servlet页面,那么直接输入该Servlet地址则是传递Null给服务器

因此必须加入健壮性语句:

1     String username = request.getParameter("user");
2     if(username!=null && !username.trim().equals("")) {
3         System.out.println("user:"+username);
4     }

password部分代码同理。

 

  接下来是单选按钮,比如性别选择:

1 性别   <input type="radio" name="gender" value="male"/>2       <input type="radio" name="gender" value="female"/>   

只有<input type=”radio”>标签中的”name”属性一样,才能具有单选的功能,同时”name”属性也是在Servlet中获取用户单选数据的重要参数,代码:

1     String gender = request.getParameter("gender");

如果单选没有选择任何选项,则提交会返回null,所以需加入健壮性语句:

1     String gender = request.getParameter("gender");
2     if(gender != null) {
3         System.out.println(gender);
4     }

 

  接下来是下拉列表,下拉列表可以是作为选择城市,如:

1 城市<select name="city">
2     <option value="none">--选择城市--</option>
3     <option value="beijing">北京</option>
4     <option value="shanghai">上海</option>
5     <option value="hangzhou">杭州</option>
6     <option value="amoy">厦门</option>
7 </select>

由<select>标签中的”name”属性作为Servlet中服务器获取客户端发来的下来列表数据的重要参数,代码如下:

1     String city = request.getParameter("city");
2     System.out.println(city);

由于下拉列表会默认选择其第一个<option>标签的内容,所有即使我们没有进行任何选择,也是会传递值得,这里可以无需健壮性判断。

 

  接下来是复选框,复选框可以是一些所学技能,或者兴趣爱好,如:

1   爱好    <input type="checkbox" name="hobby" value="sing">唱歌
2         <input type="checkbox" name="hobby" value="surf">冲浪
3         <input type="checkbox" name="hobby" value="swim">游泳

由<input type=”checkbox”>标签中的name属性决定了这些复选框是否属于同一个复选框组,也是同时也是作为Servlet中获取表单复选框的数据的重要参数,由于多个参数使用同一个参数名,所以必须使用getParameterValues(String)方法来获取所有的被勾选的复选框,代码如下(包含健壮性):

1     String[] hobbies = request.getParameterValues("hobby");
2     for(int i=0;hobbies!=null&&i<hobbies.length;i++) {
3         System.out.println(hobbies[i]);
4     }

如果没有勾选任何一个复选框,则不会向服务器Servlet传送任何数据。所以如果直接接收可能会发生空指针异常,必须判断是否接收到的字符串数组有数据(hobbies!=null)。

 

重要:

  现在,我们再重新回到<input type="text" name="user" /> 上,如果我们输入的是中文数据,点击提交之后会是怎样?

  

在控制台看到的结果:

  

结果就是出现了中文乱码问题。这是浏览器在发送时通常要看当时的编码,如:

  

或者:

  

但是!!

在Servlet收到request请求对象发来的数据时,通过getParameter方法是默认查询“ISO-8859-1”码表的,所以造成了编码不一致!

解决方式也很简单,只要在Servlet中将获取的request对象选择正确的解码方式即可,只要在代码前添加一句:

1     request.setCharacterEncoding("UTF-8");

就可以获取表单中正确的中文数据了:

  

注意,对于响应对象的setCharacterEncoding方法只对HTTP协议的POST方式有效,对GET方式无效。

 

  如果我们将表单提交方式改为GET,那么提交表单中有中文数据的话依然在Servlet中会出现乱码。

如果想使GET方式也不会出现中文乱码,并没有好的捷径方法。先要通过getParameter获取请求数据(这时在Servlet中以ISO8859码表进行解码),然后再通过ISO8859进行编码成字节数组,最后通过创建字符串对象的方式选择UTF-8解码表解出最开始客户端编码的数据。

代码如下:

1     String userTemp = request.getParameter("user");
2     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方式不会出现乱码:

1     request.setCharacterEncoding("utf-8");
2     String username = request.getParameter("user");

同样,这种配置server.xml文件的方式依然不建议采用

 

  最后说明一点,在HTML编程中,我们也可以使用超链接来提交数据,当然这样的方式属于HTTP中的GET方式,原理类似于在浏览器地址URL后手动添加参数,比如如下代码:

1     <a href="/myservlet/servlet/ServletRequest?user=银魂" >用户名为中文</a>

跟随的参数为中文!!

两种解决方式:

1,在这个超链接上必须将这个中文进行URL编码,必须在JSP中进行编写(在后面的篇章中会介绍如何使用);

2,或者使用上述GET处理中文乱码的第一种方式,进行双次编码:

1     String userTemp = request.getParameter("user");
2     String username = new String(userTemp.getBytes("ISO8859-1"),"utf-8");

也是可以的。

  

转载于:https://www.cnblogs.com/fjdingsd/p/4854919.html

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

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

相关文章

如何提高linux的时钟精度,Linux时钟精度提高有什么办法?

2 动态高精度时钟设计和实现动态高精度时钟设计方案借鉴了KURT-Linux思想&#xff0c;但与其不同的是提供一个与标准Linux核心时钟并行的具有精密刻度的实时时钟&#xff0c;并与原核心时钟区别开。采用X86体系CPU提供的TSC作为高精度的时间标度&#xff0c;权衡一定时间段(如一…

c语言循环程序怎么编程,c语言程序(5):循环结构程序设计

#include #include #include /*循环结构:1.基本循环语句while循环do_while循环for循环1.1 所有的的循环&#xff0c;都是满足条件循环1.2 while循环while(条件){循环体;}1.3 kbhit() :监测键盘是否按键&#xff0c;1.4do{循环体;}while(count<3);1.5 for循环for(表达式1;表达…

Java基础知识强化之网络编程笔记05:UDP之多线程实现聊天室案例

1. 通过多线程改进刚才的聊天程序&#xff0c;这样我就可以实现在一个窗口发送和接收数据了 2. 代码示例&#xff1a; &#xff08;1&#xff09;SendThread.java&#xff0c;如下&#xff1a; 1 package com.himi.udpDemo2;2 3 import java.io.BufferedReader;4 import java.…

c语言宿舍管理设计报告,C语言课程设计—学生宿舍管理系统设计报告.doc

word格式精心整理版范文范例 学习指导课 程 设 计 报 告课程名称 C语言程序设计课题名称 学生宿舍管理系统专 业班 级学 号姓 名指导教师2012年6月19日湖南工程学院课 程 设 计 任 务 书课程名称 C语言程序设计课 题 学生宿舍管理系统专业班级学生姓名学 号指导老师审 批任务书…

EF编辑

//修改推荐的信息 var productRe db.Shop_ProductRecommends.Single(item > item.Id model.Id); productRe.seat model.seat; db.Set<Shop_ProductRecommends>().Attach(productRe); db.Entry(productRe).State EntityState.Modified;转载于:https://www.cnblogs.…

考勤管理系统c语言,C语言课程设计学生考勤系统最终版(范文1)

《C语言课程设计学生考勤系统.doc》由会员分享&#xff0c;可免费在线阅读全文&#xff0c;更多与《C语言课程设计学生考勤系统(最终版)》相关文档资源请在帮帮文库(www.woc88.com)数亿文档库存里搜索。1、&#xff1b;return(head)&#xff1b;}voidenter()*录入函数*{structS…

关于类和接口的一些小笔记

如果一个类实现了多个接口&#xff0c;如果将这个类实例化&#xff0c;那么这些接口之间可以互相调用的。转载于:https://www.cnblogs.com/pilihaotian/p/4868609.html

汇编语言调用c语言ads,ADS1.2 在汇编代码中调用C函数

EDA365欢迎您登录&#xff01;您需要 登录 才可以下载或查看&#xff0c;没有帐号&#xff1f;注册x, U) b) } U8 \" d/ v( \$ ~ T对于ARM体系来说&#xff0c;不同语言撰写的函数之间相互调用(mix calls)遵循的是 ATPCS(ARM-Thumb Procedure Call Standard)&#xff0c;…

c语言选择法排序案例,谁能给我一个c语言选择排序法的简单例子

满意答案evil83752014.02.27采纳率&#xff1a;51% 等级&#xff1a;11已帮助&#xff1a;7590人#include int main(){int array[100], n, c, d, position, swap;printf("Enter number of elements\n");scanf("%d", &n);printf("Enter %d inte…

huffman算法c语言实验报告,huffman二叉树实验报告--数据结构(c语言).doc

江海强 PAGE 7数 据 结 构 作 业 报 告——Huffman二叉树实验报告姓名&#xff1a;江海强班级&#xff1a;070921班学号上机时间&#xff1a;2010-报告时间&#xff1a;2010-10-26摘要1.实验目的本实验是为了让我们深入了解Huffman二叉树&#xff0c;学会使用Huffman编码…

《炉石传说》建筑设计欣赏(7):采用Google.ProtocolBuffers处理网络消息

这一次&#xff0c;琢磨了一下Unity3D网络游戏发展的网络信息处理。服务器的网络游戏一般都是自主研发&#xff0c;因此&#xff0c;相应的网络消息处理应该培养自己。client/现在使用的邮件服务器之间的价差JSON和Google.ProtocolBuffers有两种常见的方法。平炉码看其处理。代…

tarjan算法c语言,tarjan算法板子 - osc_e45irv7l的个人空间 - OSCHINA - 中文开源技术交流社区...

无向图概念时间戳\(dfn[x]\),在深度优先遍历中&#xff0c;按照每个节点第一次被访问的顺序&#xff0c;依次做整数标记追溯值\(low[x]\),通过非搜索边能到达的最小时间戳割边判定法则无向边\((x,y)\)是割边/桥&#xff0c;当且仅当存在x的一个子节点满足\(dfn[x] < low[y]\…

流和文件

流&#xff1a;流是数据的传输方式&#xff1b;C程序处理一个流而不是直接处理文件。你声明一个FILE *fp &#xff0c;并把fopen(某个文件)返回的值赋予fp这两个动作就相当于建立了一个水龙头&#xff0c;当你用getc(fp)之类的输入函数读取文件字符时就相当于拧开了水龙头&…

小球进盒子C语言,N个小球放进M个盒子算法-Go语言中文社区

N个小球放入M个盒子共有多少种方法&#xff0c;并输出的算法设计&#xff1a;算法思路1 &#xff1a;暴力填充盒子每个小球都可能放入M个盒子的任意一个&#xff0c;所以直接根据小球个数做递归即可,然后将存储放入hash中排重//TODO算法思路2 &#xff1a;递归填充盒子即&#…

r语言c5.0要求因子输出,R语言中因子的创建与使用

原标题&#xff1a;R语言中因子的创建与使用因子在R语言中可以用来表示名义型变量或有序变量。名义变量一般表示类别&#xff0c;如性别&#xff0c;种族等等。有序变量是有一定排序顺序的变量&#xff0c;如职称&#xff0c;年级等等。在R语言中&#xff0c;名义变量和有序变量…

WinForm中使用AnyCAD三维控件 の 初始化

在WinForm中可以方便的集成AnyCAD.Net三维控件&#xff0c;只需要以下几部即可完成。 一、添加DLL程序集 AnyCAD.Foundation.Net.dll AnyCAD.Presentation.Net.dll AnyCAD.Exchange.Net.dll 二、初始化控件 1.首先创建一个窗体 2.在窗体上放置一个Panel用来放置三维控件 3.初始…

linux中nodejs后台运行工具forever

forever让nodejs应用后台执行 命令如下&#xff1a; forever start ./bin/www nodejs一般是当成一条用户命令执行的&#xff0c;当用户断开客户连接&#xff0c;运用也就停了&#xff0c;很烦人。如何让nodejs应用当成服务&#xff0c;在后台执行呢&#xff1f; 最简单的办法(不…

android启动其他app的服务器,Android中通过外部程序启动App的三种方法

这篇文章主要介绍了Android中通过外部程序启动App的三种方法,本文讲解了直接通过包名、通过自定义的Action、通过Scheme三种方法,并分别给出操作代码,需要的朋友可以参考下第一种&#xff1a;直接通过包名&#xff1a;复制代码 代码如下:Intent LaunchIntent getPackageManage…

linux date 天之前,linux date命令前后几天的推导

linux date使用(前后几天时间推导)在Linux系统 中&#xff0c;可以采用如下方法&#xff1a;1) 取之前的时间&#xff1a;date -d "a day ago" %Y%m%d 取出前1天的系统时间date -d "2 days ago" %Y%m%d 取出前2天的系统时间2) 取之后的时间&#xff1a;dat…

各种封装——封装getClass

因为用Class获取元素时&#xff0c;有兼容性问题&#xff0c;需要分情况获取 显示判断是否可以用getElementsByClassName&#xff0c;若是不介意用就要先获取全部的元素&#xff0c;在用正则判断 function getClass(oParent,sClass){if(oParent.getElementsByClassName){return…