首页 > 代码库 > bos项目第二天(msyql操作、ssh配置集成、PowerDesinger、自定义登陆拦截器)
bos项目第二天(msyql操作、ssh配置集成、PowerDesinger、自定义登陆拦截器)
项目第二天(完整流程)
1. 第二天 重点内容
搭建SSH 完成框架
以用户管理为例
- 用户登录
- 用户退出
- 修改密码
2. 开发流程
2.1. 业务分析
2.2. 数据库设计
MySQL : 新建 DataBase 、 新建用户 User 、进行授权
Oracle : 新建用户 User 、 创建表空间 、 在表空间进行操作
MySQL 操作步骤 :
步骤: 新建数据库
查看字符集 show variables like ‘%char%’;
client、connection、results 这三个字符集 和 安装mysql命令窗口相关
database 、 server 、system 这三个字符集服务器 (设置 utf8 )
修改 my.ini 文件 [mysqld] 下面
character-set-server=utf8
创建数据库使用默认字符集
新建用户
create user 用户名@localhost (本机)/ 用户名@%(远程) identified by ‘密码’ ;
为账户授权
2.3. 完成项目SSH 配置集成
在Spring 的applicationContext.xml 连接数据库 (整合Hibernate )
步骤:
整合Hibernate ,配置SessionFactory
事务管理
引入外部属性文件,为了项目维护更加方便
config.properties
配置事务
建立项目包结构
cn.itcast.bos.domain 数据实体类
cn.itcast.bos.dao 数据层
cn.itcast.bos.service 业务逻辑层
cn.itcast.bos.web 表现层
2.4. 数据库建模工具 PD的使用
安装12.5版本,进行破解
PD 是最专业数据建模工具, 是 Sybase 公司一个 产品
PD 提供四种模型文件
PDM 物理数据模型,面向数据库表结构设计,直接生成SQL语句或者通过ODBC工具直接导入数据 (JDBC 类型 jdbc-odbc桥、 NativeAPI、 Middleware 、 纯java驱动)
CDM 概念数据模型,类似E-R图 主要数据模型分析
OOM 面向对象模型,将表关系,表示类之间关系
BPM 业务流程模型,业务流程图
CDM 、PDM、OOM 三者相互转换
PDM 直接生成数据库文件,完成数据库建表
课程: PDM设计使用
2.5. 建立 user数据表
/* 创建user数据表 */
create table user (
id varchar(32) primary key,
username varchar(20),
password varchar(32), /* md5加密密码 */
salary double ,
birthday date ,
gender varchar(10),
station varchar(40),
telephone varchar(11),
remark varchar(255)
);
/* 初始化一条记录 */
insert into user(id,username,password) values(‘abcdefghijklmn‘,‘admin‘,md5(‘admin‘));
作业: 使用PowerDesigner 绘制 user 数据模型
使用 Hibernate 开发
第一条: 创建数据表,根据数据表 编写PO类和 hbm映射
第二条: 面向对象设计 表关系,使用类动态 生成数据表
使用 MyEclipse 反转引擎,生成
步骤:
1、 新建 Database 连接
2、 新建web项目 temp
添加myeclipse hibernate 能力
3、 Hibernate 反转构建
将 User.java 类 复制 src/main/java , User.hbm.xml 复制 src/main/resources
3. 编程实现 用户登录操作
3.1. 设计 数据访问层 DAO
2 企业实际项目中,各层之间面向接口整合 ,好处将业务和实现解耦合,方便程序维护和扩展 ,程序中面向接口编程,在程序中看不到实现类,实现类都是通过Spring 配置
2 在企业开发各层内部,一定会存在重复可复用的代码 ,设计BaseXXX 类,是抽象类 ,将重复代码放入抽象类中, 自定义DAO 或者 Service 基础BaseDAO 或者 BaseService
设计通用 DAO 组件,只编写 一个DAO 工具类完成 所有表 CURD
需要依赖 反射和泛型 技术
在 cn.itcast.bos.dao.impl 提供 GenericDAO 实现
2 使用Session操作 Hibernate
2 使用HibernateTemplate 操作 Hibernate
public class GenericDAOImpl<T> extends HibernateDaoSupport implements GenericDAO<T> {
…
}
因为基础 HibernateDaoSupport 向DAO 注入SessionFactory 使用HibernateTemplate
配置具体DAO
applicationContext.xml 分离
<import resource="classpath:applicationContext-common.xml"/>
<import resource="classpath:applicationContext-dao.xml"/>
<import resource="classpath:applicationContext-service.xml"/>
<import resource="classpath:applicationContext-action.xml"/>
在 applicationContext-dao.xml 为每张表,配置一个DAO Bean
<!-- 配置DAO -->
<!-- 为每个表 配置一个DAO -->
<bean id="userDAO" class="cn.itcast.bos.dao.impl.GenericDAOImpl">
<!-- 构造器注入 ,传入 实体类 完整类名 -->
<constructor-arg index="0" type="java.lang.String" value=http://www.mamicode.com/"cn.itcast.bos.domain.user.User"></constructor-arg>
<!-- 注入SessionFactory -->
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
3.2. 完成用户登录功能
3.2.1. 修改登陆页面
将 login.jsp 中form 修改为 <s :form>
好处: 使用 <s :form> 进行数据回显
通常会将登陆功能,编写单独Action (与用户管理其他功能分离开 )
好处: 便于进行权限控制
账户: username
密码: password
验证码 : checkcode
点击 提交 链接,提交form表单
3.2.2. 编写服务器程序
Web层
public abstract class BaseAction extends ActionSupport {
}
public class LoginAction extends BaseAction implements ModelDriven<User> {}
将可以复用代码 抽取 BaseAction 中
Service层
public abstract class BaseService {
}
public interface UserService {
}
public class UserServiceImpl extends BaseService implements UserService {}
BaseService 实现代码复用, UserService 接口和Web层整合,UserServiceImpl 业务实现类
================ 整合
将 DAO 注入 BaseService
将 Service 注入 BaseAction
业务层实现登陆, 需要根据用户名和密码查询 (条件查询 )
<!-- 命名查询 -->
<query name="User.login">
<![CDATA[from User where username = ? and password = ?]]>
</query>
在业务层调用 名称查询时,别忘记对密码 md5 加密
统一配置
struts.xml
<!-- 登陆功能 -->
<action name="login" class="loginAction">
<result name="input">/login.jsp</result>
<result type="redirect">/index.jsp</result>
</action>
applicationContext-action.xml
<!-- 配置Action -->
<bean id="loginAction"
class="cn.itcast.bos.web.action.user.LoginAction" scope="prototype"/>
applicationContext-service.xml
<!-- 配置Service -->
<bean id="userService"
class="cn.itcast.bos.service.impl.user.UserServiceImpl" />
使用注解注入,在applicationContext-common.xml
<!-- 使用注解注入对象 -->
<context:annotation-config />
=====================================================================
4. 登陆功能主页完善和系统退出
4.1. 主页信息显示完善
4.1.1. 主页面 右上方,登陆用户显示
/page_common_index.action 对应 /WEB-INF/pages/common/index.jsp
[<strong>${user.username }</strong>],欢迎你!您使用[<strong>${pageContext.request.remoteAddr }</strong>]IP登录!
4.1.2. 主页面右下方,弹出窗口提示
使用 EasyUI 提供 messager控件,制作提示框架效果
$.messager.show 右下角提示框
$.messager.alert 弹出警告框
$.messager.confirm 确认框
// 1 alert
$.messager.alert("标题","内容","info");
// 2 confirm
$.messager.confirm(‘标题‘,‘确认删除吗?‘,function(isConfirm){
if(isConfirm){
alert("执行删除");
}else{
alert("取消...");
}
});
制作右下角提示窗口
// 3、show
$.messager.show({
title : ‘标题‘,
msg : ‘<a href="http://www.mamicode.com/#">传智播客</a>‘,
timeout : 5000 , // 5秒后自动消失
});
4.2. 系统退出
// 退出登录
function logoutFun() {
// 询问 用户是否确认退出
$.messager.confirm("确认窗口","你确定退出系统吗?", function(isConfirm){
if(isConfirm){
// 确认退出
location.href = "http://www.mamicode.com/${pageContext.request.contextPath}/invalidate.jsp";
}
});
}
用户确认退出,直接跳转 invalidate.jsp
invalidate.jsp 退出操作,销毁当前用户对应的Session
<%
// 清除用户Session
session.invalidate();
// 重定向 login.jsp
response.sendRedirect(request.getContextPath()+"/login.jsp");
%>
5. 编写自定义拦截器,控制页面访问
自定义拦截器 LoginInterceptor 实现,如果用户未登陆,阻止访问 WEB-INF 下所有页面和 除登陆之外其它 Action
步骤 :
1、 编写 拦截器类,实现 Interceptor 接口
public class LoginInterceptor extends AbstractInterceptor {
2、 实现intercept 方法,判断当前用户是否登陆
User user = (User) ServletActionContext.getRequest().getSession().getAttribute("user");
if (user == null) {
// 没有登陆
return "login"; // 登陆页面
} else {
// 已经登陆
return invocation.invoke();
}
3、 注册拦截器,配置结果页面
<!-- 注册拦截器 -->
<interceptors>
<interceptor name="login" class="cn.itcast.bos.web.interceptor.LoginInterceptor"></interceptor>
<!-- 定义新的拦截器栈 -->
<interceptor-stack name="loginStack">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="login"></interceptor-ref>
</interceptor-stack>
</interceptors>
将拦截器 设置package默认拦截器
<!-- 设置默认拦截器栈 -->
<default-interceptor-ref name="loginStack"></default-interceptor-ref>
配置全局结果集
<!-- 配置全局结果集 -->
<global-results>
<result name="login">/login.jsp</result>
</global-results>
4、 使用拦截器传递错误信息
ActionSupport action = (ActionSupport) invocation.getAction();
action.addActionError("你还未登陆或者长时间未使用,请重新登陆!");
问题: 使用iframe嵌套,主页嵌套主页 情况
可以,在未登陆,跳转提示信息页面,用户点击链接,跳到登陆 (整个浏览器跳转) 或者
在登陆form 添加 target=”_top”
6. 密码修改
6.1. 弹出遮罩窗口
使用 EasyUI 的 window 控件制作 (dialog 是对window扩展,提供 工具栏)
使用 class=”easyui-window” 将任意div 变为窗口 ,设置属性
collapsible |
boolean |
定义是否显示折叠按钮。 |
true |
minimizable |
boolean |
定义是否显示最小化按钮。 |
true |
maximizable |
boolean |
定义是否显示最大化按钮。 |
true |
closable |
boolean |
定义是否显示关闭按钮。 |
true |
控制window的 按钮,默认四个按钮都是显示
通过 modal 属性 设置窗口遮罩效果
打开和关闭窗口。
$(‘#win‘).window(‘open‘); // open a window
$(‘#win‘).window(‘close‘); // close a window
示例代码:
<!-- 通过 easyui的 class 将任意 div 变为 窗口 -->
<!-- 为窗口 设置标题属性 和 宽高 -->
<div id="mywindow" class="easyui-window" data-options="title:‘自定义窗口‘,maximizable:false,minimizable:false,modal:true,closed:true"
style="width:200px;height: 150px">传智播客</div>
<input type="button" value=http://www.mamicode.com/"打开窗口"
onclick="$(‘#mywindow‘).window(‘open‘);"/>
6.2. 修改密码窗口,进行form校验
点击修改密码 : $(‘#editPwdWindow‘).window(‘open‘); 弹出窗口
输入密码,点击确定 : 执行js函数 ,对密码进行校验
// 获得新密码和确认密码的输入内容
var newPass = $("#txtNewPass").val(); // document.getElementById("txtNewPass").value;
var rePass = $("#txtRePass").val();
// 进行校验
// 新密码是否为空
if($.trim(newPass)==""){ // 也可以写为 jQuery.trim
// 新密码输入为空
$.messager.alert(‘警告‘,‘新密码不能为空或者空白字符!‘,‘warning‘);
return ;
}
// 两次密码是否一致
if($.trim(newPass) != $.trim(rePass)){
$.messager.alert(‘警告‘,‘两次密码输入不一致!‘,‘warning‘);
return ;
}
6.3. Ajax实现密码修改功能
1、 发起Ajax请求
// 通过 Ajax 将新密码发送到服务器
$.post("${pageContext.request.contextPath}/user_editpassword.action", {password: newPass}, function(data){
});
2、 编写服务器,完成密码修改功能
UserAction
注入 UserService
public class UserAction extends BaseAction implements ModelDriven<User> {}
// 如果修改用户某个属性,先查询,再修改
User exist = userDAO.findById(user.getId()); // 持久态
exist.setPassword(MD5Utils.md5(user.getPassword()));
3、 返回json 格式
对象 {key:value, key:value}
数组 [{},{}]
结果数据转换为json 推荐
2 flexjson 框架
2 struts2 自带 json plugin
使用 struts2 自带json插件
提供一个新的package : json-default , 提供新 result-type : json
插件基于值栈返回的
// 调用业务层
try {
userService.editPassword(user);
// 修改成功
Map<String, Object> map = new HashMap<String, Object>();
map.put("result", "success");
map.put("msg", "修改密码成功");
ActionContext.getContext().put("map", map);
} catch (Exception e) {
// 修改失败
Map<String, Object> map = new HashMap<String, Object>();
map.put("result", "failure");
map.put("msg", "修改密码失败," + e.getMessage());
ActionContext.getContext().put("map", map);
}
配置 struts.xml
配置包 <package name="needlogin" extends="json-default">
配置result
<!-- 用户管理 -->
<action name="user_*" class="userAction" method="{1}">
<!-- 修改密码 -->
<result name="editpasswordSUCCESS" type="json">
<!-- 配置root参数,指定将值栈哪个数据返回 -->
<param name="root">map</param>
</result>
</action>
配置applicationContext-action.xml
<bean id="userAction"
class="cn.itcast.bos.web.action.user.UserAction" scope="prototype" />
4、使用 firebug调试
控制台、 网络、脚本 三个面板 启用
在 applicationContext-common.xml 配置事务管理
对editPassword 方法添加事务
<tx:method name="*" propagation="REQUIRED" isolation="DEFAULT"/>
5、 编写回调函数
if(data.result == "success"){
$.messager.alert("信息", data.msg, "info");
}else{
$.messager.alert("信息", data.msg, "info");
}
// 窗口关闭
$("#editPwdWindow").window(‘close‘);
=====================================================================
bos项目第二天(msyql操作、ssh配置集成、PowerDesinger、自定义登陆拦截器)