java-WEB模块物流项目二.docx
BOS物流管理系统 第2天 内容安排:1、 Spring data 完成数据访问层2、 封装dao 项目使用 STS 3、 登陆业务 1. 登陆业务1.1. 使用PD 根据大纲绘制用户表PowerDesigner点击 菜单 Database ->genreate Database ->点击预览 注意: PD 生成表 ,默认脚本自带顺引号 设置 一定去掉双引号 否则逆向生成实体类 失败! 一般习惯脚本采用大写! Oracle 数据库生成脚本!去掉双引号设置步骤:->Edit current Database 选项点击生成脚本 预览 .引号就没有了!预览用户的脚本使用plsql 工具 完成脚本执行!开发中 一般新建一个用户 授予 resouce + connect 角色即可 ! plsql/develepor 工具使用管理员创建用户并且授权ITCAST29开发bos 采用oracle ITCAST29用户!1.2. 创建实体类 Spring data jpa 注解 : Entity Table Id GenerateValue 实体类的注册 需要编写 ApplicationContext.xml 1.3. 配置ApplicationContext 连接池和Bean注册1: 数据库配置文件2:配置连接池 以及 sessionFactory 测试: 启动tomcat <context:property-placeholder location="classpath:jdbc.properties"/> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><!- 配置 连接数据库参数 c3p0 连接池 -> <property name="driverClass" value="$jdbc.driverClass"></property> <property name="jdbcUrl" value="$jdbc.url"></property> <property name="user" value="$jdbc.username"></property> <property name="password" value="$jdbc.password"></property> </bean> <!- 连接池 给 sessionFactory 注解版本 -> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <!- 配置其他hibernate 信息 -> <property name="hibernateProperties"> <props> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">validate</prop><!- <prop key="hibernate.hbm2ddl.auto">update</prop> -> <prop key="hibernate.dialect">$jdbc.dialect</prop> </props> </property> <property name="packagesToScan"> <list> <value>cn.itcast.mavenbos.domain</value> </list> </property> </bean>oracle validate 校验报错: 数据库表字段类型 numeric(10,2)->实体类 BigDecimal 类型.需要导入: hibernate-entity.jar spring-data. jpa 依赖的jar <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>$hibernate.version</version> </dependency>1.4. 配置 Spring data 学习 1:引入spring-data.jar + 依赖包 参阅文档 45页2:spring主配置文件(以前:学习hibernate 需要连接池 ->SessionFactory) 现在spring data 不用sessionFactory + 注解支持 需要配置spring data名称空间缺少jpa 名称空间 参照 background 章节 找到 quick start applicationContext.xml 引入名称空间<beans xmlns="http:/www.springframework.org/schema/beans"xmlns:xsi="http:/www.w3.org/2001/XMLSchema-instance"xmlns:context="http:/www.springframework.org/schema/context"xmlns:aop="http:/www.springframework.org/schema/aop"xmlns:jpa="http:/www.springframework.org/schema/data/jpa"xmlns:tx="http:/www.springframework.org/schema/tx"xsi:schemaLocation="http:/www.springframework.org/schema/beans http:/www.springframework.org/schema/beans/spring-beans.xsdhttp:/www.springframework.org/schema/contexthttp:/www.springframework.org/schema/context/spring-context.xsdhttp:/www.springframework.org/schema/aophttp:/www.springframework.org/schema/aop/spring-aop.xsdhttp:/www.springframework.org/schema/tx http:/www.springframework.org/schema/tx/spring-tx.xsdhttp:/www.springframework.org/schema/data/jpa http:/www.springframework.org/schema/data/jpa/spring-jpa.xsd"> </bean>配置连接池 <!- 使用 Spring data -> <context:property-placeholder location="classpath:jdbc.properties"/> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><!- 配置 连接数据库参数 c3p0 连接池 -> <property name="driverClass" value="$jdbc.driverClass"></property> <property name="jdbcUrl" value="$jdbc.url"></property> <property name="user" value="$jdbc.username"></property> <property name="password" value="$jdbc.password"></property> </bean>配置EntityManagerFactory 参照 文档 = sessionFactory<bean id="entityManagerFactory"class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"><property name="dataSource" ref="dataSource" /><property name="packagesToScan" value="cn.itcast.bos.domain" /><property name="jpaVendorAdapter"><bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"><property name="database" value="ORACLE" /><!- 自动建表 -><property name="generateDdl" value="true" /><!- 方言 -><property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect"></property><!- 显示sql -><property name="showSql" value="true"></property></bean></property></bean>配置:注解包扫描 是pring注解扫描 以及 spring data 支持dao 扫描<!- 依赖注入 扫描spring 注解 -><context:componen-scan base-package="cn.itcast.bos.service,cn.itcast.bos.web"/><!- 扫描 spring data 继承dao 接口 -><jpa:repositories base-package="cn.itcast.bos.dao"></jpa:repositories>配置事务<!- 注解事务管理器 -><bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"><property name="entityManagerFactory" ref="entityManagerFactory" /></bean><tx:annotation-driven transaction-manager="transactionManager"/>测试: 配置完成 启动tomcat 导入jar1.5. UserDao 设计Reposistory 接口 最大接口! 根据目录继承树结构->F4开发中 XxxxDao extends JpaRepostory<User/Staff,String/Integer> 即可 spring data 提供一套接口 以及 实现类 编写 UserDao 继承 指定接口即可 完成 crud userDao 完成! 专门针对dao 测试!1.6. UserService 设计 设计简单业务方法注解完成业务层实现测试业务层 :UserDao 扫描需要配置事务管理器 采用spring data 提供事务管理器开启 spring 注解扫描测试:1.7. JPQL 查询说明1: 根据方法名称 自动生成 jpql 语句 参照文档案例1测试 业务层+junit业务层调用userDao :userDao 业务方法 必须符合命名规范 测试:s2: 命名查询 推荐注解 name 查询 要求: 类名.方法名 spring data 自动扫描 实体类 找寻 注解NamedQuery(name="xxx")案例2 : 要求使用NamedQuery 注解 在目标查询实体类上声明实体类添加注解 spring data 自动搜索 类名.方法 名称 找寻对应HQL 语句 junit 3:Query 注解的查询 dao 方法名称可以自定义 注解中编写 JPQL 语句 = HQL 案例三演示4: Query 注解 完成 本地 sql 查询 需要添加 nativeQuery=true 告知spring data 书写语句 本地sql 5:参数注入查询 Param注解 指定参数 类似HQL 占位符 Param("lastname') 自动将参数值 赋予 :lastnamespring data jpa 查询结束!web action 抽取1.8. 通用Action模板封装通用性代码 BaseActionpackage cn.itcast.mavenbos.web.action.base;import java.lang.reflect.ParameterizedType;import java.lang.reflect.Type;import org.apache.struts2.ServletActionContext;import org.springframework.beans.factory.annotation.Autowired;import cn.itcast.mavenbos.service.user.UserService;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.ActionSupport;import com.opensymphony.xwork2.ModelDriven;import com.opensymphony.xwork2.util.ValueStack;/ 复用 Action 代码public abstract class BaseAction<T> extends ActionSupport implements ModelDriven<T> / 各种业务层对象Autowiredprivate UserService userService;/ Autowired/ private UserService userService;/ Autowired/ private UserService userService;/ Autowired/ private UserService userService;/ Autowired/ private UserService userService;/ Autowired/ private UserService userService;/ Autowired/ private UserService userService;/ Autowired/ private UserService userService;/ Autowired/ private UserService userService;/ Autowired/ private UserService userService;protected T model;/ 各个action 封装对象modelpublic T getModel() return model;/ 后续子类XxxxAction 请求参数 封装model 里面public BaseAction() / 对model进行实例化, 通过子类 类声明的泛型Type superclass = this.getClass().getGenericSuperclass();/ 转化为参数化类型ParameterizedType parameterizedType = (ParameterizedType) superclass;/ 获取一个泛型参数Class<T> modelClass = (Class<T>) parameterizedType.getActualTypeArguments()0;try model = modelClass.newInstance(); catch (InstantiationException e) e.printStackTrace(); catch (IllegalAccessException e) e.printStackTrace();/ 获取请求参数public String getParameter(String name) return ServletActionContext.getRequest().getParameter(name);/ 获取Session Attributepublic Object getSessionAttribute(String name) return ServletActionContext.getRequest().getSession().getAttribute(name);/ 向session保存属性public void setSessionAttribute(String name, Object value) ServletActionContext.getRequest().getSession().setAttribute(name, value);/ 值栈对象的获取public ValueStack getStack() return ActionContext.getContext().getValueStack();/ 压入数据到值栈public void push(Object obj) getStack().push(obj);/ 压入数据到值栈public void set(String key, Object value) getStack().set(key, value);/ 分页请求属性驱动protected int page; / 页码protected int rows; / 每页 记录数public void setPage(int page) this.page = page;public void setRows(int rows) this.rows = rows;注入各种业务层接口 1.9. login.jsp页面设计登陆按钮-><a> 同步请求 不能 提交表单 将<a> 标签超链接 变成js 点击事件 -> 函数方法->提交表单编写js go 方法实现 提交表单form 表单的设计1.10. 验证码ajax校验js 完成 !<script type="text/javascript"> var checkcode_flag = false; / 页面加载 完成 进行验证码校验 .离焦事件 $(function() $("inputname='checkcode'").blur(function() / 发送ajax 请求 $.post("$pageContext.request.contextPath/user/userAction_validCheckCode","checkcode":this.value,function(data) if(data) / true 验证码正确 可以提交表单 用户提示 $("#checkcode_sp").html("<font color='green'></font>"); checkcode_flag = true; else / false 验证码错误 不可以提交表单 用户提示 $("#checkcode_sp").html("<font color='red'>×</font>"); checkcode_flag = false; ); ); );/ 表单的提交 function go()/ 提交表单 if(checkcode_flag)$("#loginform").submit(); </script>2: action 校验方法 从session 获取验证码 json返回 true/false测试:ok login.jsp 表单 action地址 1.11. login 业务方法编写1: login.jsp action 2: login 业务方法/ 登陆业务方法/ 登陆业务Action(value = "userAction_login", results = Result(name = "login_ok", type = "redirect", location = "/index.jsp"), Result(name = "login_error", location = "/login.jsp") )public String login() String session_code = (String) getSessionAttribute("key");String input_code = getParameter("checkcode");if (StringUtils.isNotBlank(input_code) if (input_code.equalsIgnoreCase(session_code) User existUser = userService.findUserByNameAndPassword(model.getUsername(), model.getPassword();if (existUser = null) this.addActionError(this.getText("login.usernameorpassword.error");return "login_error" else / 用户存放Session 验证码移除removeSessionAttribute("key");setSessionAttribute("existUser", existUser);return "login_ok" else / 验证码 错误 .绕过 ajax 校验/ throw new RuntimeException("数据非法.");this.addActionError(this.getText("login.illegal.error");return "login_error" else this.addActionError(this.getText("login.illegal.error");return "login_error"/ 用户没有输入验证码/ throw new RuntimeException("数据非法.");2: 配置国际化相关信息 3: login.jsp 回显错误信息1.12. 登陆请求表单参数校验(登陆参数校验)UserAction 同包下 新建 局部xml校验文件编写校验器规则<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE validators PUBLIC "-/Apache Struts/XWork Validator 1.0.3/EN" "http:/struts.apache.org/dtds/xwork-validator-1.0.3.dtd"> <validators> <!- field name 值 表示 form 表单Input name属性值 -> <field name="username"> <!- 选择对应校验器 type="校验器的名称" -> <field-validator type="requiredstring"> <!- message 书写错误信息 -> <message key="login.params.loginName.requiredstring.error"></message> </field-validator> <!- 同一个字段 添加多个校验器 -> <field-validator type="stringlength"> <!- message 书写错误信息 -> <param name="minLength">1</param> <param name="maxLength">10</param> <message key="login.params.loginName.stringlength.error"></message> </field-validator> </field> <!- 密码校验 -> <field name="password"> <!- 选择对应校验器 type="校验器的名称" -> <field-validator type="requiredstring"> <!- message 书写错误信息 -> <message key="login.params.loginPwd.requiredstring.error"></message> </field-validator> <!- 同一个字段 添加多个校验器 -> <field-validator type="stringlength"> <!- message 书写错误信息 -> <param name="minLength">1</param> <param name="maxLength">10</param> <message key="login.params.loginPwd.stringlength.error"></message> </field-validator> </field> </validators>国际化信息添加错误信息提示 UserAction_login 方法上 添加参数非法结果集视图配置以及结果集跳转/ 登陆Action(value = "userAction_login", results = Result(name = "login_param_error", location = "/login.jsp"), Result(name = "login_error", location = "/login.jsp"), Result(name = "login_ok", type = "redirect", location = "/index.jsp"),Result(name = "login_exception", location = "/login.jsp") )InputConfig(resultName = "login_param_error")/ 如果表单参数格式错误 跳转 login_param_error 结果集视图public String login() String input_code = getParameter("checkcode");if (StringUtils.isNotBlank(input_code) String session_code = (String) getSessionAttribute("key");if (input_code.equals(session_code) / 验证码正确 才会判断 用户名或者密码 是否正确User existUser = userService.findUserByusernameAndPassword(model.getUsername(), model.getPassword();if (existUser = null) / 数据库不存在this.addActionError(this.getText("login.usernameOrpassword.error");return "login_error" else / 数据库存在 一次性验证码 session移除removeSessionAttribute("key");/ 一次性验证码移除/ 登陆认证setSessionAttribute("existUser", existUser);return "login_ok" else / 非法数据this.addActionError(this.getText("login_exception.error");return "login_exception" else / 非法数据this.addActionError(this.getText("login_exception.error");return "login_exception"login.jsp 页面回显参数非法错误信息1.13. applicationContext.xml 注册扫描包测试: ok !1.14. 添加自定义拦截器完成登陆认证MethodFilterIntecetper 类 提供对action 指定业务方法排除功能!1: 编写拦截器类2: 注册拦截器(拦截器对象 Struts2 创建的!)3: 应用当前包下4: 结果集配置 struts.xml 配置结果集自定义拦截器 完成!扩展 拦截器对象 由spring 管理 struts.xml 配置伪类名测试ok 2