Struts2学习——登录效果

版权声明: 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,这样自然加载不到资源。

发现了问题所在。你要给图片、文件、等等资源的路径前加上${pageContext.request.contextPath }/  ,然后就不会出现资源无法加载的情况了,切记,动态网页开发,最好所有需要填写路径的地方前边都要加上这段代码(作用是获取项目名)

猜你喜欢

转载自blog.csdn.net/hu18315778112/article/details/84843503