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应用都支持偏好设置 ...
随机推荐
- Emacs折腾经验谈
Emacs折腾经验谈 这几天都没有动力写mongodb的东西,我果然还是太懒了么~ 主要是没有一个系统的东西整理出来,加上我令人拙计的语言表达能力,这个坑只能慢慢再补了. 最近在折腾emacs这个东西 ...
- MP4视频编码器
用 HTML5 播放视频,最流行的视频格式非 MP4莫属, 所有最新浏览器都支持; MP4 带有 H.264 视频编码和 AAC 音频编码的 MPEG 4 文件: 以前做过一个把其它编码格式的视频转成 ...
- C语言之带有返回值的函数
带有返回值的函数 语法: 类型 函数名(参数列表){ 函数体; return 数据; } 例: int getSum(int num1,int num2){ int sum = num1 + num2 ...
- Java Web学习笔记--JSP for循环
JSP for循环 <%@ page language="java" contentType="text/html; charset=UTF-8" %&g ...
- javascript:;”是什么意思
就是 执行一段 空白JAVASCRIPT语句 并且返回的也是空或者false值..把 javascript:; 加在超级链接上 就可以防止 链接跳转..从而 可以给 链接的 onclick 方法上 写 ...
- 认识div在排版中的作用
在网页制作过程过中,可以把一些独立的逻辑部分划分出来,放在一个<div>标签中,这个<div>标签的作用就相当于一个容器. 语法: <div>-</div&g ...
- openui5的资料比较少
openui5的资料比较少,稳定优秀的开源框架,国内了解的人了了,都在追AngularJS.ExtJS.React. React比较新,非死不可出品而且裹挟Native的噱头.Mobile Nativ ...
- action中list传到JSP中取不到值的问题
今天遇到了这个问题 action中list传到JSP中取不到值 搞了半天是因为我在JSP中取值的的时候 <s:iterator value="shlist" var=&qu ...
- 采用rest接口对接而非webservice
代码示例 public static String queryForCTI(String url){ String targetURL = getCTIurl()+"/"+url; ...
- 基于Unity的Profiler性能分析
A. WaitForTargetFPS: Vsync(垂直同步)功能所,即显示当前帧的CPU等待时间 B. Overhead: Profiler总体时间-所有单项的记录时 ...