Servlet之保存用户偏好设置简单功能的实现
写在前面:
先来陈述一下为什么会有这样一个需求和这篇博文。
这是公司的一个项目,我们负责前端,后台服务由其他公司负责。该系统有一个系统偏好设置模块,用户可以设置系统的背景图片等系统样式,因为这是一个比较简单的功能,所以当时没有让后台公司来实现,由自己公司的一个领导编写了一个Servlet。但是由于服务器故障被格式化之后,这个Servlet就丢失了。本来打算跟领导汇报的,但是又怕挨批评,而且这个功能也并不复杂,所以决定自己实现一下吧。但是作为一个对Java一点都不懂的我来说,还是废了不少功夫的,所以有必要将这个过程记录一下。
具体需求:
每一个用户都可以针对该Web系统设置自己的背景图片,可以从系统预设的图片中选择,也可以自己上传新的图片。而我们需要做的就是将用户的配置信息、上传的图片保存下来,当用户下次登录时,通过配置信息加载对应的背景图片即可。
实现方案:
方案一:
如果将所有的用户配置信息都存放到一个文件中,那么不管在获取还是保存时,都需要解析这个文件的内容,太麻烦,而且不利于扩展。假设以后这个系统偏好设置模块,不仅可以设置背景图片,还可以设置系统的常用功能模块,那对应保存每个用户的配置信息的数据格式就变了,那么解析这个文件内容的方法也就得跟着变了。举个例子吧,假设之前文件中保存用户配置信息的数据是这样的,{"用户Id1":"url1", "用户Id2":"url2", "用户Id3":"url3", ...}。那么在扩展了功能之后,数据格式就会变成了这个样子,{"用户Id1":{"bgImage":"url1", "常用功能":"功能1, 功能2, ..."}, "用户Id2":{"bgImage":"url2", "常用功能":"功能2, 功能3, ..."}, ...},或者说变成了其他格式,不管变成了哪种格式,总之一句话,之前的那种格式已经满足不了需求了,所以解析这个文件内容的方法势必要进行改造。这就是不利于扩展的一个方面。
方案二:
其实我们可以根据用户Id将每一个用户的配置信息单独放到一个目录下,而每一个功能的配置信息,单独放到一个文件中。什么意思呢?其实就是这样:

每一个用户的背景图片的配置信息都在对应用户Id文件夹下的bgImageConfig.txt文件中。这样只要给出用户Id和文件名,我们就将对应的文件内容读取直接返回给前端,无需解析文件内容。因为文件内容本身就是前端保存进来的,保存时我们也不会去关注具体保存了什么信息,只需要将内容写入文件即可。这样做还有一个好处,假设甲方增加了一个设置系统常用功能的需求,那么我们的目录就会变成这样:

而我们的代码逻辑却不需要改变。与上面同样的道理,只要给出用户Id和文件名,我们就将文件内容直接返回给前端。我们甚至都不会去关注用户Id和文件名具体是什么,我们只需要将用户Id和文件名拼接起来,获取时,如果存在则直接读取返回;如果不存在,则返回为空或者作出提示。保存时,如果存在则直接覆盖;如果不存在,则创建然后写入内容。文件名完全可以由前端自己确定,前端保存配置信息时传递的文件名是什么,我们就保存该文件名对应的文件。获取时,只要给出对应的文件名,我们就将对应的文件内容返回即可。
对于用户自己上传的图片,是统一放到一个目录中,还是分别放到用户Id对应的文件夹下,其实也是有讲究的。假设统一放到一个目录中,那假如两个用户上传的图片是不一样的,但是恰好文件名是一样的,那之前的图片岂不是会被覆盖了?所以还是分别放到用户Id对应的文件夹下比较好。
技术点:
1、Servlet
虽然是Java小白,但是基本的Servlet还是了解的,但是也仅仅停留在创建一个Servlet,测试一下GET、POST请求而已。
2、Java上传文件
这里是通过commons-fileupload-1.3.1.jar和commons-io-2.5.jar来实现的,代码是从网上找的,具体原理还是不太明白,这里就不贴代码了,等到最后记录一下项目的地址。
还有一点需要注意的是,上传文件时的参数获取和普通的GET、POST请求的参数获取,还是不一样的。我们需要获取文件流,判断文件流是不是非文件域fileItem.isFormField(),如果是非文件域,则通过fileItem.getFieldName()获取参数名,通过new String[]{Streams.asString(fileItem.getInputStream())}获取参数值。
另外需要注意的一点是,我们需要获取文件的上传路径,这里我们是通过request.getSession().getServletContext().getRealPath("")得到工程目录所对应的路径的,然后执行创建文件夹、写文件等操作。我们还需要返回前端一个可访问的Web路径,当然不能是功能目录所对应的绝对路径,这样前端是访问不到的。这里我们是通过request.getRequestURL()获取前端的请求路径,然后和前面保存的上传路径拼接起来的,这部分功能参考了这里。
关于获取文件的上传路径和返回前端一个可访问的Web路径,总感觉自己的做法太麻烦,抽空需要请教一下有没有简便的做法。
3、Java的文件操作
通过实现这么一个功能,对File类有了一个基本的认识。该类的对象可以代表一个具体的文件或文件夹。通过该类,可以实现创建文件夹mkdir()、mkdirs(),创建文件createNewFile(),判断文件或文件夹是否存在exists()等。这里参考的是火之光和Java写入文件的几种方法。
总结:
虽然这个功能是做通了,但是还是有好多不明白的地方,还是应该再接着研究的,否则下次还是不知道怎么用。
项目地址:https://github.com/Youwanwu/CloudServer.git
Servlet之保存用户偏好设置简单功能的实现的更多相关文章
- Android 保存用户偏好设置
很多情况下都允许用户根据自己的习惯和爱好去设置软件,而我们需要保存这些设置,可以用一个专业保存用户偏好的类:SharedPreferences. 这个类是实现方法其实也就是创建和修改 XML 文件, ...
- 16_采用SharedPreferences保存用户偏好设置参数
按钮事件 <Button android:id="@+id/button" android:layout_width="wrap_content" and ...
- 黎活明8天快速掌握android视频教程--16_采用SharedPreferences保存用户偏好设置参数
SharedPreferences保存的数据是xml格式,也是存在数据保存的下面四种权限: 我们来看看 我们来看看具体的业务操作类: /** * 文件名:SharedPrecences.java * ...
- 【Qt官方例程学习笔记】Application Example(构成界面/QAction/退出时询问保存/用户偏好载入和保存/文本文件的载入和保存/QCommandLineParser解析运行参数)
The Application example shows how to implement a standard GUI application with menus, toolbars, and ...
- Android之使用SharedPreferences保存用户偏好参数
在Android应用中,我们常需要记录用户设置的一些偏好参数,,此时我们就需要用SharedPreferences和Editor将这些信息保存下来,在下次登录时读取. SharedPreference ...
- SharedPreferences保存用户偏好参数
package com.example.administrator.myapplication; import android.content.Context; import android.cont ...
- iOS开发--应用设置及用户默认设置【2、读取应用中的设置】
在上一节中,我们通过探讨应用的系统设置的基本功能,了解运用bundle捆绑包以及plist文件的基本开发.用户能够使用设置应用来声明他们的偏好设置,那么我们怎样去调用用户所设置的参数呢 ...
- iOS开发--应用设置及用户默认设置——转载
[链接]iOS开发--应用设置及用户默认设置[1.bundlehttp://www.jianshu.com/p/6f2913f6b218 在iphone里面,应用都会在“设置”里面有个专属的应用设置, ...
- iOS: 偏好设置的详解和使用
偏好设置的详解: 用途:主要用来存储用户系统的设备信息,但有的时候也可以在程序的任何地方用来存储数据,作为全局数据来访问,例如视图切换需要进行登录时. 偏好设置的写入: •很多iOS应用都支持偏好设置 ...
随机推荐
- Linux下SSH+Firefox
Linux下SSH+Firefox 简明FQ攻略 FQ的软件有很多,楼主原来在Windows下用过Tor(洋葱头).Puff.freegate等,一般只需要打开FQ软件,简单的设置后就可以FQ浏览了. ...
- [置顶] C语言中各种数据类型的长度 sizeof char, short, int, long, long long
这些数据类型的sizeof具体长度依赖于编译器和操作系统(32-bit or 64-bit) 1: 首先,参见c99标准 标准中没有定义这些数据类型的长度,而是定义了这些数据类型能表达的大小范围的最小 ...
- centos 6.4 x64安装bugfree
第一步:下载xampp-linux-1.8.1.tar.gz [root@SVNMANAGER ~]# tar -zxvf xampp-linux-1.8.1.tar.gz -C /opt [root ...
- Android 关于ListView中按钮监听的优化问题(方法一)
在Android应用开发过程中经常会用到ListView,并且每次在item中都要对点击事件进行监听.在给按钮添加OnClickListener时,一般会下意识的在getView()中找到每一个But ...
- Linux中的task,process, thread 简介
本文的主要目的是介绍在Linux内核中,task,process, thread这3个名字之间的区别和联系.并且和WINDOWS中的相应观念进行比较.如果你已经很清楚了,那么就不用往下看了. LINU ...
- MVC源码解析 - Http Pipeline 解析(上)
IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(context); 上一篇说到了创建 ...
- [转载]关于shell脚本的基本语法
关于shell脚本的基本语法 整理于:2014-03-31,何俭飞,mymladdr@sina.com 一.执行 1.shell脚本如果要被执行,一般地必须要有执行权限"x"(除了 ...
- 项目上传svn出问题
我在自己的笔记本上(win8),安装了tortoise 1.9.4和visualSVN server 3.5.3.我现在想让eclipse的自带的svn插件连接到本地服务器的资源库上.但是我写http ...
- To the end
身为一名初二狗的我也走过了半年.不管怎么说人生中也没有几个半年嘛.从九月到现在快四个月了,我也离中考越来越近了/郁闷/.但是还是要好好过唔.不过我想起这半学期还是挺充实的,至少没有浪费太多的时间.有些 ...
- TypeScript 学习三 类
1,类: 类是TypeScript的核心,大部分代码都是写在类里面: 声明:class 类名{ 属性: 方法(){}:} 注意:类名首字母同样大写,但是方法不需要表明类型,直接写方法名加()即可:属 ...