SSH 案例学习总结(一)

最近通过视频,看了开发一个 SSH web程序的基本过程,也跟着把代码都敲下来了,感觉收获挺多的,而且了解了很多以前不知道的知识与技术,虽然自己才刚刚接触,了解不深,但是希望将自己的学习心得记录下来。

这是一个在线调查系统,功能涵盖了用户注册、用户登录、文件上传、权限管理、日志管理等几大方面。用户注册过后,可以进行新建调查、参与调查、查看调查,新建调查时可以进行调查的设计,设计调查的页面、调查的问题、问题的题型、问题的答案,参与调查时能进行问题的回答,进行各种问题的答案的统计,然后可以将统计结果以图表方式展示出来。查看调查时可以看到自己的调查列表,并且可以为自己的调查上传logo等。

在注册的功能中( RegAction ),主要运用md5加密方法对用户密码进行加密入库,重写了 ActionSupport 父类中的 validate 方法对用户的输入进行校验,将不合法的输入信息添加到 addFieldError 方法中,在 jsp 页面进行展示。

在登录的功能中( LoginAction ),重写了 ActionSupport 父类的 validate 方法,将用户登录时的错误信息添加到 addActionError 方法中,在 jsp 页面进行展示。并且实现了 SessionAware 接口,注入了 sessionMap,将用户登录信息保存进 sessionMap 中。

------ 很多功能都需要用户登录后才能进行,如SurveyAction...,为了不在每个需要登录的Action中都去从 session中
获取User对象,所以新建一个 UserAware 接口,里面写上 setUser(User user) 方法,然后哪个 Action 需要
登录,就去实现这个接口,在 登录拦截器中,当检测到实现了 UserAware 接口的 Action 时,就取执行 setUser() 
方法,为这个 Action 注入 user。

------ 在所有 Action 的父类 BaseAction<T> 中,继承了 ModelDriven<T> 接口,利用反射,得到了子类的泛型类型,并初始化了 model 对象,从而在所有 Action 子类中不需要再去覆写getModel 方法

public BaseAction() {
ParameterizedType type = 
(ParameterizedType) this.getClass().getGenericSuperclass();
Class clazz = (Class) type.getActualTypeArguments()[0];
try {
model = (T) clazz.newInstance();
} catch(Exception e) {
e.printStackTrace();
}
}

在调查功能中( SurveyAction ),新建调查时,因为用户与调查、调查与页面之间均存在一对多的关联关系,并且由多的一方维护关联关系,因此有:survey.setUser(user);page.setSurvey(survey);

在设计调查中,因为要将已存在的调查的页面和答案显示出来,而 hibernate 又有懒加载机制,在查询调查时只是拿到调查的代理对象,因此,调查所关联的页面和答案并没有被查出来,所以需要强行加载调查所关联的页面和答案,即 //强行初始化 pages 集合和 question 集合
for(Page page : survey.getPages()){
page.getQuestions().size();
}

在更新调查中,由于页面上调查的 id 属性是隐藏域,不能手动修改,因此要保持更新后的调查的关联关系,设置id及调查属于的 user。

在增加 Logo 功能中( 文件的上传 ),利用 struts2 的上传机制,先定义了File类型要上传的文件和string类型的并且以FileName结尾的文件名,并增加了 setter/getter 方法,并让SurveyAction实现了ServletContextAware 接口,拿到了ServletContext 对象,通过 ServletContext 对象得到文件在服务器上的真实路径,根据文件名得到文件的后缀,并以系统的纳秒时间作为文件的新名称,根据文件路径及名称和后缀,将文件保存到服务器上。如下:

//得到 uplode 文件夹在服务器上的真实路径
String dir = servletContext.getRealPath("/uplode");
//文件扩展名
String ext = 
logoPhotoFileName.substring(logoPhotoFileName.lastIndexOf("."));
//纳秒时间作为文件名(防止重名)
long l = System.nanoTime();
//新文件路径
File newFile = new File(dir,l+ext);
//文件另存为
logoPhoto.renameTo(newFile);
//2.更新路径
surveyService.updateLogoPhotoPath(sid,"/uplode/"+l+ext);

由于参与调查( EngageAction )的功能比较多,所以单独做一个action,为了在答题时进行上一步、下一步等操作时能将答案保存并回显,故将当前调查和答案分别保存到session中进行缓存,保存答案的 map 是 HashMap<Integer, Map<String, String[]>> 类型,原因如下:( 参与调查的页面中,有 上一步 ,下一步,完成,退出 等导航,只有点 完成 后,表单才会被提交到服务器,在此之前,如果
  要进行 上一步, 下一步 等操作时,应该将当前页面已经做好的答案存放到 session 中,如果 用  Map<String,String[]> 来存放 <控件名称,答案> ,在进行 上一步 修改时,有的答案可能无法覆盖掉比如: 之前前一页有个题是可选可不选的,前一次操作中选中了,然后在另一页中点击 上一步 导航时,要把那一页中那个选项 给去掉,这时 session 中那题对应的键值对就无法被覆盖掉,导致问题。所以将存放答案的 session 设计为 Map<Integer,Map<String,String[]>> 来存放 <页面id,<控件名称,答案>>,这样在修改时,整个页面都会被覆盖,可以避免问题)

在处理参与调查功能中,为了能与页面数据进行交互,让 EngageAction 实现了 ParameterAware 接口,这个接口的拦截器将页面上所有参数都放到 Map<String, String[]> paramsMap 中,因此在其中可以直接根据用户点击的按钮判断是上一步、下一步或者完成、退出等,从而进行不同功能的实现。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值