网站首页 > 技术文章 正文
软件项目实训及课程设计指导——Web表示层典型功能实现的应用实例
1、Web页面中的树形菜单的功能实现
利用树形菜单可以实现层次化的命令集,方便导航用户的操作。目前在 Web页面中可以采用许多不同的技术实现树形菜单的应用效果——如基于Ajax技术实现Web树状菜单、采用XML+JavaScript脚本创建树形菜单或者利用CSS(Cascading Style Sheets,层叠样式表)实现静态效果的树形菜单等。
DHTMLXTree是Web开发中运用较多的一个开源的树型菜单控件,允许开发人员快速开发Web界面中的树形菜单,它基于Ajax的JavaScript脚本库,允许在线编辑、拖拽、三种状态(全选、不选、半选)、复选框等模式。在加载大数据量的时候,仍然可以保持非常高效的速度。
DHTMLXTree本质上其实是一个在Web页面上实现树状显示效果的JavaScript控件,因此应用它不仅可以实现树型菜单,也可以实现树型目录等"树"状结构的数据显示效果。如下示图为应用DHTMLXTree控件实现的一个树形结构的数据显示效果的应用示例局部截图。
而如下示图为DHTMLXTree官方网站页面提供的有关技术文档局部截图,读者可以根据待开发的软件应用系统项目的需要下载相关的系统库文件和在线浏览技术参考文档资料。
在示例项目银行账户信息管理系统的后台页面的设计和实现中,也采用了DHTMLXTree树型控件实现应用系统中的后台管理功能的树形菜单,请见下图所示页面效果局部截图。
2、Web页面数据的分页显示功能实现
由于在软件应用系统中某个功能的页面需要显示大量的数据,为了方便应用系统的操作者对数据的快速浏览,应该要对待显示的目标数据进行分页显示。Web应用系统中数据分页显示技术也是Web表示层开发中比较通用的功能实现要求——所谓的数据分页显示功能要求,也就是将从软件应用系统后台数据库表中获得的各种结果数据人为地分成特定长度的数据块、并在Web页面中只显示其中某一块的数据,并为操作者提供继续浏览其它块数据的链接或者按钮(包括前、后页、第一和最后页、快速定位某页等方式)。
下图所示为示例项目银行账户信息管理系统中对用户账户信息进行数据分页显示的效果的局部截图,该分页实现技术是每次只向数据库系统请求页面大小的数据,大大地提高了每次前/后翻页时的查询速度。
当然,在具体实现时一定要达到将软件应用系统的表示层数据显示与数据的业务逻辑处理相互分离的设计和开发实现的基本目标。
3、解决Web表单重复提交的问题以保证数据的唯一性
由于各个Web浏览器都提供有【刷新】功能菜单——请见下图所示,为了防止操作者点击【刷新】功能菜单而造成对软件应用系统后台的多次重复请求,在软件应用系统的表示层开发中应该要避免产生表单重复提交的问题。
对于解决表单重复提交的技术问题,许多基于MVC体系架构的应用框架都提供了对应的技术支持和具体的实现方法。早期的Struts框架是通过提供Token(令牌)机制很好地解决了表单重复提交的问题——其基本的实现原理是:
Struts框架的服务器端程Action类程序在处理到达的请求之前,会将请求中包含的令牌值与保存在当前用户会话中的令牌值进行比较,看是否匹配;而在处理完该次请求后,并且在将响应发送给客户端浏览器之前,将会产生一个新的令牌(一个随机的字符串),该令牌除传给客户端浏览器以外,也会将用户Session会话中保存的旧的令牌进行替换。
此时如果用户回退到刚才的提交页面并再次重复地提交请求时,客户端Web浏览器再次传递过来的令牌字符串就和服务器端保存的令牌字符串内容也就不一致,从而有效地防止了Web表单重复提交的发生。
而在Struts2应用框架中利用系统内带的<s:token />标签产生一个GUID(Globally Unique Identifier,全局唯一标识符)字符串值的隐藏输入框,同时还将GUID字符串放到Session会话中;在执行某个Web请求之前,Struts2应用框架中的缺省的"token"拦截器将会话中的令牌字符串与此时的Web请求令牌字符串比较,如果两者相同,则将会话中的令牌字符串删除并继续往下执行,否则向actionErrors程序类加入相关的错误信息。
如此一来,如果用户通过某种手段提交了两次相同的请求,两个令牌字符串就会不同。从而也有效地防止了Web表单重复提交的发生。
在示例项目银行账户信息管理系统中为了不依赖于Struts2等MVC框架系统,没有简单地采用这些MVC应用框架系统对Web表单重复提交的功能实现的技术支持。而是采用Web页面表单中的图形验证码进行限制,同样也能够达到相同的应用效果。
由于图形验证码在每次不同的Web请求时都会产生不同的值,从而控制重复提交的行为产生。在示例项目中的"开户"功能成功后,用户如果再次点击Web浏览器中的"回退"按钮后,将回到原来的Web表单请求页面。但此时Web页面表单中的验证码已经不一致,请见下图所示的功能操作状态图示,此时提交后,软件应用系统后台的验证码验证程序将报告错误而终止重复的Web请求。
但如果用户在Web表单中输入正确的验证码后再发送本次请求,软件应用系统后台将通过业务数据中的逻辑性和数据的一致性加以限制,而避免在物理数据库系统的数据库表中出现完全一样的两条记录数据。
4、Web表单中的数据有效性验证
软件应用系统的操作者可能由于操作的失误或者恶意的攻击或者无意识的错误数据输入等行为,在Web页面表单中将产生错误的输入数据。为了保证在软件应用系统后台能够正确地获得所需要的目标数据,应该要对Web表单中的各种关键性的输入数据进行数据验证(数据有效性验证)。
对于Web表单中提交的数据不仅需要应用Web客户端的数据验证(一般是采用JavaScript脚本语言实现),更应该要应用Web服务器端数据验证技术以真正达到软件应用系统的数据安全性、正确性和有效性等应用的要求。
这主要是由于目前有许多浏览器能够禁止执行Web客户端页面中所内嵌的JavaScript脚本语言程序代码而导致Web客户端的数据验证功能失效、或者恶意的攻击者直接通过Web客户端应用程序请求访问软件应用系统中的后台Web服务器端相关程序。下图所示为FireFox浏览器对Web页面中的JavaScript脚本语言的控制项目的局部截图。
在示例项目银行账户信息管理系统中应用Apache Validator验证器框架实现Web服务器端的数据验证,由于Apache Validator验证器框架是Jakarta的公共项目的一部分,读者可以从Apache Validator验证器官方网站中下载Validator框架的系统包文件。如下示图为Apache Validator验证器官方网站中技术特性介绍、系统库文件下载等信息页面局部截图。
下图所示为在示例项目银行账户信息管理系统中的AccountInfoManageAction类的checkVerifyCodeOK方法中应用Validator框架的代码片段局部截图。
5、统计软件应用系统的在线人数
Web应用系统的在线人数实时反映软件应用系统的访问状态,如果能够显示当前软件应用系统的在线人数,一方面能够让软件应用系统的管理人员及时地了解软件应用系统的当前负载情况,另一方面也让访问者了解到本软件应用系统的热门程度。
但要想实时准确地统计Web应用系统的在线人数,其实也是一件不太现实的事情。这是因为HTTP协议本身是无状态的协议,当Web客户端程序(一般为Web浏览器程序)向Web服务器发出一个Web请求时,Web服务器会马上建立一个新的TCP/IP连接(也就是会话Session);在该Web页面完全载入后,这个会话连接也就关闭了;另外,正是由于HTTP协议是无状态的,所以也就无法知道某个Web请求访问是否已经离开或者Web请求者已经关闭了Web浏览器。
因此,Web应用中所谓的在线人数其实应该是指在"一定时间段内"同时访问Web站点的人数,而不是基于HTTP协议的并发连接数。但这个"一定时间段内"对于不同的Web服务器也是有差别的,如Tomcat服务器默认的Session会话超时为30分钟(但一般的Web网站都采用15分种的时间标准)。
在示例项目银行账户信息管理系统中也提供了该功能的具体实现,是利用实现HttpSessionListener接口的Web监听器统计在线Session个数、并将Tomcat服务器默认的Session会话超时时间改变为15分钟,最后在Web页面中显示输出本软件应用系统的在线人数。本示例项目最后实现的效果局部截图如图所示。
6、在软件应用系统中实现文件上传功能
文件上传或者下载也是Web应用系统中需要提供的功能,在示例项目银行账户信息管理系统中利用Apache Commons-FileUpload组件实现文件的上传功能,该FileUpload组件可以实现每次上传一个或多个文件,并可限制文件大小——比如在用户注册表单中允许注册者自行上传自己的图像文件,请见下图所示的局部截图。
7、在软件应用系统中实现文件下载功能
在Web应用系统的开发实现中,大部分的文件下载都是直接通过建立下载文件的URL文件链接方式直接进行下载。但是考虑到在Web应用中的文件下载具体实现时的盗链、跨服务器下载访问等方面的因素,直接文件流下载的方式也是必要的。因为,此时Web应用系统能够对下载的文件以及下载的操作者进行更多方面的安全及身份验证的检查和控制。
在Struts2应用框架中实现数据流下载时只需要改变Struts2应用框架中的result Type为Stream类型即可以实现本功能要求——请见下面的代码示例所示的某个实现文件下载功能的DownLoadFileAction的配置定义示例内容中的黑体标识的内容。如下为某个实现文件下载功能的DownLoadFileAction的配置定义示例
<action name="oneDownLoadGIFFile"
class="com.px1987.struts2.action.DownLoadFileAction">
<param name="inputPath">/downImages/logo.gif</param>
<result name="success" type="stream">
<param name="contentType">image/gif</param>
<param name="inputName">inputStream</param>
<param name="contentDisposition">filename="logo.gif"</param>
<param name="bufferSize">4096</param>
</result>
</action>
在示例项目银行账户信息管理系统中采用在Servlet程序中直接控制文件输出流的方式实现文件下载的控制。具体的功能实现代码请见如下所附的代码示例,该doDownLoadFile方法作为某个J2EE Servlet程序中一个功能方法被doGet方法所调用,并请注意其中的黑体部分的语句代码——实现文件下载功能的代码示例
public void doDownLoadFile(HttpServletRequest request, String downFileName,
HttpServletResponse response, String downFilePath)
throws ServletException, IOException{
ServletOutputStream servletOutputStream = null;
FileInputStream fileInputStream = null;
BufferedInputStream bufferedInputStream =null;
File downLoadTargetFile = new File(downFilePath+"/"+downFileName);
if(!downLoadTargetFile.exists()){
response.sendError(404,"没有找到要下载的目标文件!");
return;
}
try {
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition",
"attachment; filename=\"" + downFileName + "\"");
servletOutputStream = response.getOutputStream(); fileInputStream = new java.io.FileInputStream(downFilePath +
"\\"+ downFileName);
bufferedInputStream = new BufferedInputStream(fileInputStream);
byte[] oneBuffer = new byte[10240];
int byteNumber;
while ((byteNumber=bufferedInputStream.read(oneBuffer)) != -1){
servletOutputStream.write(oneBuffer,0,byteNumber);
}
}
catch (FileNotFoundException e) {
}
catch (IOException e) {
}
finally {
if(bufferedInputStream != null){
bufferedInputStream.close();
}
if(servletOutputStream != null){
servletOutputStream.close();
}
}
}
其中的response.setContentType("application/octet-stream");语句主要是设置Http响应头和要下载保存的文件名,Web浏览器将根据开发人员在Http数据流的Head部分的MIME(Multipurpose Internet Mail Extensions,多用途互联网邮件扩展类型)头的设置内容"application/octet-stream"直接产生出文件下载的对话框提示、并且按照设置的内容采用二进制数据格式传输文件流数据。
- 上一篇: 简单学量化——发送电子邮件 发电子邮件怎么操作
- 下一篇: 网络相关知识 网络相关知识抄写
猜你喜欢
- 2024-11-08 加班用了2天,结果同事30分钟就搞定了?你和别人的差距在哪里
- 2024-11-08 下载文件工具类 文件下载工具是什么
- 2024-11-08 SMTP发送邮件 smtp发送邮件过程
- 2024-11-08 NPM 使用介绍 npm .staging
- 2024-11-08 java servlet笔记:设置编码集、文件下载和两种服务器跳转
- 2024-11-08 还不懂 HTTP 协议的吗?一篇文章讲透
- 2024-11-08 JavaScript包管理工具pnpm介绍 js importpackage
- 2024-11-08 Ajax请求时,请求类型,常用的几种 Content-Type json form-data xml
- 2024-11-08 Python教程:报表和日志精讲 python自动生成日报
- 2024-11-08 安全RCE之未授权访问分析 未授权的访问路径
- 标签列表
-
- content-disposition (47)
- nth-child (56)
- math.pow (44)
- 原型和原型链 (63)
- canvas mdn (36)
- css @media (49)
- promise mdn (39)
- readasdataurl (52)
- if-modified-since (49)
- css ::after (50)
- border-image-slice (40)
- flex mdn (37)
- .join (41)
- function.apply (60)
- input type number (64)
- weakmap (62)
- js arguments (45)
- js delete方法 (61)
- blob type (44)
- math.max.apply (51)
- js (44)
- firefox 3 (47)
- cssbox-sizing (52)
- js删除 (49)
- js for continue (56)
- 最新留言
-