版权声明: https://blog.csdn.net/hu18315778112/article/details/84843503
- 首先说下今天发现的问题:教程中使用的是低版本的hibernate,所以HQL语句查询是,'?' 占位符仍然可以用,今天自己用高版本的发现报错query parameters (`?`) are no longer supported; use JPA-style ordinal parameters。意思就是不再支持 '?' 占位符了,所以我使用了 ':xxx' 的占位符形式。
登录功能按照架构分层可以分为:
-
web层:获取用户提交的登录数据,封装并传递到service层
-
service层:调用dao层,查询数据库,将查询结果与web层的数据比较,将比较结果返回给web层
-
dao层:根据service层提交数据,查询数据库
具体实现:
-
web层,学习struts2当然要用它来实现:
- Action:
/* 继承ActionSupport的方式创建Action类 * 实现ModalDriven接口的方式,获取参数(getModal方法) */ public class UserAction extends ActionSupport implements ModelDriven<User>{ // 创建service层对象 private UserService service = new UserserviceImpl(); // 创建对象,用于接收参数 private User u = new User(); public String login() throws Exception { // 调用service层登录方法 User user = service.login(u); // 将user存到session域 ActionContext.getContext().getSession().put("user", user); return "login"; } @Override public User getModel() { return u; } }
Service层:使用Hibernate框架封装的工具类实现的事务
- login方法
@Override public User login(User u) { // 开启事务 Transaction tst = HibernateUtils.getCurrentSession().beginTransaction(); // 执行操作(根据用户名) User user = dao.login(u.getUser_code()); // 提交事务(因为这里业务简单,也没有表修改操作,所以无需回滚,直接提交) tst.commit(); // 判断是否存在用户 if (user == null) { // 抛出错误,Struts2框架可以根据用户自定义错误在页面显示信息 throw new RuntimeException("用户名不存在"); } // 判断密码是否正确 if (!user.getUser_password().equals(u.getUser_password())) { throw new RuntimeException("密码错误"); } // 用户名密码都正确,返回该User对象 return user; }
- 这里直接进行了两次判断来确定用户名对错与密码对错:
- 1. 使用用户提交的用户名(user_code)去查询数据库(一般情况用户名不可重复),如果查到了用户信息,起码说明用户名正确的,可以向下执行,然后再判断密码。为空则直接抛出异常
- 2. 判断用户提交的密码,与从数据库获取的用户信息中的密码是否相同,相同则正确,可以继续向下执行。不同则直接抛出异常
这里可以发现我们使用抛出异常的方式来说明用户名或密码错误,既然使用这种方式,那么肯定有手段来处理,不可能给用户直接抛出一个代码异常(可以想象用户一脸蒙蔽),至于如何处理,在最后说明,这里先把dao层的代码贴出来。
dao层:使用Hibernate的基本操作Hql查询并封装对象
- login方法:
@Override public User login(String user_code) { // 获得session Session session = HibernateUtils.getCurrentSession(); // 创建hql查询语句 String hql = "from com.huhu.domain.User where user_code = :code "; // 创建查询对象 Query query = session.createQuery(hql); // 添加查询条件 query.setParameter("code", user_code); // 查询 User user=(User) query.uniqueResult(); return user; }
- 这里刚开始我使用的是 '?' 占位符,结果进行数据库查询时报错了,就是开头提到的 '?' 占位符不再支持了,所以改用了 ':xxx' 命名占位符的形式。
接下来详细说明一下,如何将异常信息处理并显示在页面上。
-
1. 首先需要在配置文件中,配置全局异常映射:
<!-- 我将之成为全局异常映射,应该是用于处理程序中抛出的可预见性的异常的配置 --> <global-exception-mappings > <!-- result属性:值为当抛出该异常时返回的值 (struts2的一大功能就是根据方法的返回值来执行对应操作) exception属性:填写可预见性异常的全包名 --> <exception-mapping result="error" exception="java.lang.RuntimeException"> <!-- 目前没整明白干啥用的 --> <param name=""></param> </exception-mapping> </global-exception-mappings> <action name="userAction_*" class="com.huhu.web.action.UserAction" method="{1}"> <!-- 既然抛出异常时,会有一个方法值,当然要对这个返回值做处理。 这是配置返回error这个值时跳转的页面 注意:这个result元素是配置在你觉得会抛出这个异常的action下 例如:我要做的是登录操作,登录方法在UserAction类中,所以我在UserAction对应的action配 置元素下,配置此result --> <result name="error" type="redirect">/login.jsp</result> <!-- 配置可动态调用的方法 --> <allowed-methods>login</allowed-methods> </action>
- 他的位置:在struts.xml配置文件中,在package元素下,在action元素之前。如图所示:
这完成了对异常的处理,但是如何在页面显示信息还没做。
-
2. 如何在页面中显示异常信息
<!-- 在jsp文件中引入标签库 -->
<%@ taglib uri="/struts-tags" prefix="s" %>
<!-- 在想要显示错误信息的位置可以通过该标签获取并显示异常信息 -->
<s:property value="exception.message" />
这样就打到了通过抛出异常的形式,并将错误信息显示给用户。
理论就是这样,教程中也达到了效果。但是我在这里出现了点问题,就是如果出现异常(用户名或密码错误),使用转发的方式转发到显示页面时,出现页面无法加载数据的情况(图片,文字,包含页面……)。现在我还没整明白,目前我用重定向的方式,如果出现异常(用户名或密码错误),重定向到登录页,但是这样又会丢掉异常信息,导致无法反馈给用户,不知道是不是struts2版本更新,哪些配置方式有变动。等我研究明白会在这里补充。
-
试了配置方式,最后发现是package元素的namespace的问题,将namespace设置为"/"就好了。。。。。。
-
貌似给了namespace一个值后,在这个元素下的转发,加载资源时都会默认加上该package元素的namespace名称空间来访问。
-
如:我设置的namespace="/user",想要转发到页面:http://localhost:8080/xxxx/login.jsp,页面是转到了;
-
但是加载图片时,比如图片路径原本是:/img/001.jpg,他会自动修改为/user/img/001.jpg,这样自然加载不到资源。