📅  最后修改于: 2023-12-03 14:47:44.342000             🧑  作者: Mango
在 Web 应用程序中,登录功能通常是必不可少的。本文将介绍一个基于 Struts 2 和 Spring 框架的登录示例,演示如何在 Web 应用程序中实现登录和访问控制。
本示例需要一个用户表来存储用户名和密码信息。以下是用户表的设计:
CREATE TABLE users (
id INT(11) NOT NULL AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
password VARCHAR(50) NOT NULL,
PRIMARY KEY (id)
);
首先,需要在 web.xml
文件中配置 Struts 2 的过滤器和监听器:
<!-- Struts 2 Filter -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Struts 2 Listener -->
<listener>
<listener-class>org.apache.struts2.dispatcher.ng.listener.StrutsListener</listener-class>
</listener>
其次,在 struts.xml
文件中配置登录和访问控制的相关信息:
<struts>
<package name="login" namespace="/" extends="struts-default">
<action name="login" class="com.example.LoginAction">
<result name="success">/welcome.jsp</result>
<result name="error">/login.jsp</result>
</action>
<action name="logout" class="com.example.LogoutAction">
<result name="success">/login.jsp</result>
</action>
</package>
<constant name="struts.custom.i18n.resources" value="global" />
<constant name="struts.devMode" value="false" />
<interceptors>
<interceptor name="authInterceptor" class="com.example.AuthInterceptor" />
<interceptor-stack name="authStack">
<interceptor-ref name="authInterceptor" />
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="authStack" />
<global-results>
<result name="logout">/login.jsp</result>
</global-results>
</struts>
Action
名称为 login
,其类为 com.example.LoginAction
,用于验证用户名和密码是否正确;/welcome.jsp
页面,登录失败则跳转回 /login.jsp
;Action
名称为 logout
,其类为 com.example.LogoutAction
,用于清除登录状态;authStack
的拦截器栈,包含一个名为 authInterceptor
的拦截器和 defaultStack
栈;authStack
拦截器栈设置为默认拦截器栈;logout
结果。为了将 Struts 2 和 Spring 集成起来,需要在 struts.xml
文件中引入 Spring 的配置文件:
<struts>
<!-- ... 略 ... -->
<constant name="struts.objectFactory" value="spring" />
<constant name="struts.objectFactory.spring.autoWire.alwaysRespect" value="true" />
<bean type="com.example.UserService" name="userService" class="com.example.UserServiceImpl">
<property name="userDao" ref="userDao" />
</bean>
<bean type="com.example.UserDao" name="userDao" class="com.example.UserDaoImpl">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mydb" />
<property name="username" value="root" />
<property name="password" value="passw0rd" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.example.entity" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
</struts>
其中,
dataSource
的 Spring Bean,作为 Hibernate 的数据源;sessionFactory
Spring Bean,注入 dataSource
和 hibernateProperties
,其中指定了 Hibernate 方言为 MySQL 5 和数据表自动更新。业务逻辑是这样的:在登录页面中输入用户名和密码,点击登录按钮,将用户名和密码发送给后台进行验证。在后台,通过 UserService 的方法调用查询数据库,根据查询结果判断登录是否成功。登录成功后,将用户信息保存在 Session 中,用于访问控制。注销操作将清除 Session 中的用户信息。
先看一下 UserService 接口和实现类:
public interface UserService {
User getUserByUsername(String username);
}
@Service
@Transactional(readOnly = true)
public class UserServiceImpl implements UserService {
private UserDao userDao;
@Autowired
public UserServiceImpl(UserDao userDao) {
this.userDao = userDao;
}
public User getUserByUsername(String username) {
return userDao.getUserByUsername(username);
}
}
其中,
接下来看一下 LoginAction:
public class LoginAction extends ActionSupport {
private String username;
private String password;
@Autowired
private UserService userService;
public String execute() {
if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
addActionError(getText("error.username.or.password.required"));
return ERROR;
}
User user = userService.getUserByUsername(username);
if (user == null || !password.equals(user.getPassword())) {
addActionError(getText("error.username.or.password.invalid"));
return ERROR;
}
HttpSession session = ServletActionContext.getRequest().getSession();
session.setAttribute("currentUser", user);
return SUCCESS;
}
// getters and setters
}
其中,
@Autowired
注解用于将 UserService 注入进来;execute()
方法中,首先判断用户名和密码是否为空,如果为空则返回一个错误信息;最后,看一下访问控制的拦截器:
public class AuthInterceptor extends AbstractInterceptor {
public String intercept(ActionInvocation invocation) throws Exception {
HttpSession session = ServletActionContext.getRequest().getSession();
if (session.getAttribute("currentUser") != null) {
return invocation.invoke();
} else {
return "logout";
}
}
}
其中,
intercept()
方法中,获取 Session 中保存的用户信息,如果存在则放行,否则返回一个名为 logout
的结果,跳转回登录页面。本文演示了在 Web 应用程序中如何实现登录和访问控制,同时介绍了 Struts 2 和 Spring 集成的方式。通过这个示例,你可以了解到 Struts 2 和 Spring 的基本使用方法,并学会了如何在 Web 应用程序中实现登录和访问控制。