一、struts2和hibernate整合
1.整合
StrutsPrepareAndExecuteFilter作用详解: https://blog.csdn.net/clk_esunny/article/details/80293978
过滤器和拦截器
- 拦截器是基于java的反射机制的,而过滤器是基于函数回调。
- 在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次;
- 拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用;
- 拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
- 配置struts2.xml
- 配置hibernate.cfg.xml 连接数据库的信息
2.创建实体类
3.生成实体类的对象关系映射文件
4.生成表结构
二、用户登录模块
1.
2.
package db;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
public class MyHibernateSessionFactory {
private static SessionFactory sessionFactory;//会话工厂属性
//构造方法私有化,保证单例模式
private MyHibernateSessionFactory()
{
}
//共有的静态方法,获得会话工厂对象
public static SessionFactory getSessionFactory()
{
if(sessionFactory==null)//未初始化
{
//创建配置对象
Configuration config = new Configuration().configure();
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();
sessionFactory = config.buildSessionFactory(serviceRegistry);
return sessionFactory;
}
else//已经初始化
{
return sessionFactory;
}
}
}
- 首先生成一个配置对象,调用configure()获得配置对象:
- 需要一个服务注册对象,其中config.getProperties()读取属性文档,利用buildServiceRegistry()返回一个服务注册对象:
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();
初始化sessionFactory
sessionFactory = config.buildSessionFactory(serviceRegistry);
- 之后可以调用这个会话工具类的getSessionFactory()来返回一个会话工厂实例
Session工作原理
- 1、客户首次访问服务器的一个页面时,服务器就会为该用户分配一个session对象,同时为这个session指定唯一的ID,并且将该ID发送到客户端并写入到cookie中,使得客户端与服务器的session建立一一对应的关系;
- 2、当客户端继续访问服务器端的其它资源时,服务器不再为该客户分配新的session对象,直到客户端浏览器关闭、超时或调用session的invalidate()方法使其失效,客户端与服务器的会话结束。
- 3、当客户重新打开浏览器访问网站时,服务器会重新为客户分配一个session对象,并重新分配sessionID。
session对象主要用于属性操作和会话管理,常用方法如下:
- 1、public void setAttribute(String name,String value)设定指定名字的属性的值,并将它添加到session会话范围内,如果这个属性是会话范围内存在,则更改该属性的值。 比如在登录的时候调用该方法,保存登录成功的用户名:session.setAttribute("loginUserName", user.getUsername());
- 2、public Object getAttribute(String name)在会话范围内获取指定名字的属性的值,返回值类型为object,如果该属性不存在,则返回null。
- 3、public void removeAttribute(String name),删除指定名字的session属性,若该属性不存在,则出现异常。注销登录时,采用此方法删除对应的用户信息:session.removeAttribute("loginUserName");
- 4、public void invalidate(),使session失效。可以立即使当前会话失效,原来会话中存储的所有对象都不能再被访问。
- 5、public String getId( ),获取当前的会话ID。每个会话在服务器端都存在一个唯一的标示sessionID,session对象发送到浏览器的唯一数据就是sessionID,它一般存储在cookie中。
- 6、public void setMaxInactiveInterval(int interval) 设置会话的最大持续时间,单位是秒,负数表明会话永不失效。
- 7、public int getMaxInActiveInterval(),获取会话的最大持续时间。
- 8、使用session对象的getCreationTime()和getLastAccessedTime()方法可以获取会话创建的时间和最后访问的时间,但其返回值是毫秒,一般需要使用下面的转换来获取具体日期和时间。
- Date creationTime = new Date(session.getCreationTime());
- Date accessedTime = new Date(session.getLastAccessedTime());
3.设计用户接口和实现类
package service.impl;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import db.MyHibernateSessionFactory;
import service.UsersDAO;
import staffentity.Users;
public class UsersDAOImpl implements UsersDAO{
@Override
public boolean usersLogin(Users u) {
// TODO Auto-generated method stub
//事务对象
Transaction tx = null;
String hql = "";
try
{
Session session = MyHibernateSessionFactory.getSessionFactory().getCurrentSession();
tx = session.beginTransaction();
hql = "from Users where username=:username and password=:password ";
Query query = session.createQuery(hql);
query.setParameter("username", u.getUsername());
query.setParameter("password", u.getPassword());
List list = query.list();
tx.commit();//提交事务
if(list.size()>0){
return true;
}else {
return false;
}
}
catch (Exception ex){
ex.printStackTrace();
return false;
}
finally {
if(tx!=null)
{
tx = null;
}
}
}
}
4.设计所有action的父类
Struts2中通常直接使用Action来封装HTTP请求参数,因此,Action类里还应该包含与请求参数对应的属性,并且为属性提供对应的getter和setter方法。
ActionSupport类是一个工具类,它已经实现了Action接口。除此之外,它还实现了Validateable接口,提供了数据校验功能。通过继承该ActionSupport类,可以简化Struts 2的Action开发。
在Validatable接口中定义了一个validate()方法,重写该方法,如果校验表单输入域出现错误,则将错误添加到ActionSupport类的fieldErrors域中,然后通过OGNL表达式负责输出。
为了让Struts 2增加输入数据校验的功能,改写程序中的LoginAction,增加重写validate方法。
(数据校验:应用中,即使浏览者输入任何用户名、密码,系统也会处理用户请求。在我们整个应用中,这种空用户名、空密码的情况不会引起太大的问题。但如果数据需要保存到数据库,或者需要根据用户输入的用户名、密码查询数据,这些空输入可能引起异常。
为了避免用户的输入引起底层异常,通常我们会在进行业务逻辑操作之前,先执行基本的数据校验。)
- 设计action父类
- 继承ActionSupport:内置很多拦截器,方便以后使用
- 为了获得常用的内置对象采用耦合IOC方式注入属性,比如request,respanse等,要实现以下接口,方便获得内置对象:
package action;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.util.ServletContextAware;
import com.opensymphony.xwork2.ActionSupport;
//所有Action动作的父类
public class SuperAction extends ActionSupport implements ServletRequestAware,ServletResponseAware,ServletContextAware{
/**
*
*/
private static final long serialVersionUID = 1L;
protected HttpServletRequest request;//请求对象
protected HttpServletResponse response;//响应对象
protected HttpSession session;//会话对象
protected ServletContext application;//全局对象
@Override
public void setServletContext(ServletContext application) {
// TODO Auto-generated method stub
this.application = application;
}
@Override
public void setServletResponse(HttpServletResponse response) {
// TODO Auto-generated method stub
this.response = response;
}
@Override
public void setServletRequest(HttpServletRequest request) {
// TODO Auto-generated method stub
this.request = request;
this.session = this.request.getSession();
}
}
5.
package action;
import org.apache.struts2.interceptor.validation.SkipValidation;
import com.opensymphony.xwork2.ModelDriven;
import service.UsersDAO;
import service.impl.UsersDAOImpl;
import staffentity.Users;
public class UsersAction extends SuperAction implements ModelDriven<Users>{
/**
*
*/
private static final long serialVersionUID = 1L;
private Users user = new Users();
//用户登录动作
public String login() {
UsersDAO udao = new UsersDAOImpl();
if(udao.usersLogin(user))
{
//在session中保存登录成功的用户名
session.setAttribute("loginUserName", user.getUsername());
return "login_success";
}
else
{
return "login_failure";
}
}
@SkipValidation
//用户注销方法
public String logout() {
if(session.getAttribute("loginUserName")!=null)
{
session.removeAttribute("loginUserName");
}
return "logout_success";
}
@Override
public void validate() {
// TODO Auto-generated method stub
super.validate();
//用户名不能为空
if("".equals(user.getUsername().trim()))
{
this.addFieldError("usernameError", "用户名不能为空!");
}
if(user.getPassword().length()<6)
{
this.addFieldError("passwordError", "密码长度不少于6位");
}
}
@Override
public Users getModel() {
// TODO Auto-generated method stub
return this.user;
}
}
显示表单验证信息,配置: