一、Struts实现登录以及在线列表展示
项目源码下载,提取码:4xf6
1.该项目实现用户登录在线列表展示功能。
2.用户只能单点登录
1.1 创建数据库的SQL
CREATE TABLE `member` (
`id` varchar(200) NOT NULL,
`name` varchar(20) NOT NULL,
`password` varchar(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1.2 代码
1.2.1 dao层
BaseDao.java
public abstract class BaseDao<T> {
public Class<T> clazz;
public BaseDao() {
Type type = this.getClass().getGenericSuperclass();
ParameterizedType p=(ParameterizedType) type;
clazz=(Class<T>) p.getActualTypeArguments()[0];
}
public int update(String sql,String ... params) {
try {
QueryRunner qr = JdbcUtil.getQr();
int update = qr.update(sql,params);
return update;
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
}
public List<T> query(String sql,String ... params){
List<T> result=null;
try {
QueryRunner qr = JdbcUtil.getQr();
result = qr.query(sql, new BeanListHandler<T>(clazz),params);
} catch (SQLException e) {
e.printStackTrace();
}
return result;
}
}
MemberDao .java
public class MemberDao extends BaseDao<MemberEntity>{
private Log logger=LogFactory.getLog(MemberDao.class);
public MemberEntity findByUserName(String name ) {
logger.info("查询用户名:"+name);
String sql="select * from member where name = ?";
List<MemberEntity> result = super.query(sql, name);
if(result!=null&&result.size()==1) {
return result.get(0);
}
logger.info("没有查询到该用户:"+name);
return null;
}
public List<MemberEntity> selectAll() {
String sql="select * from member ";
return super.query(sql);
}
public static void main(String[] args) {
MemberDao dao=new MemberDao();
List<MemberEntity> selectAll = dao.selectAll();
System.out.println(selectAll);
}
}
1.2.2 实体层
MemberEntity .java
public class MemberEntity {
private String id;
private String name;
private String password;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "MemberEntity [id=" + id + ", name=" + name + ", password=" + password + "]";
}
public OnlineEntity convert() {
OnlineEntity item=new OnlineEntity();
item.setMemberId(id);
item.setMemberName(name);
return item;
}
}
OnlineEntity .java
public class OnlineEntity {
private String memberId;
private String memberName;
private String isOnline;
private String sessoionId;
private String activeTime;
public String getMemberId() {
return memberId;
}
public void setMemberId(String memberId) {
this.memberId = memberId;
}
public String getMemberName() {
return memberName;
}
public void setMemberName(String memberName) {
this.memberName = memberName;
}
public String getIsOnline() {
return isOnline;
}
public void setIsOnline(String isOnline) {
this.isOnline = isOnline;
}
public String getSessoionId() {
return sessoionId;
}
public void setSessoionId(String sessoionId) {
this.sessoionId = sessoionId;
}
public String getActiveTime() {
return activeTime;
}
public void setActiveTime(String activeTime) {
this.activeTime = activeTime;
}
}
1.2.3 interceptor
LoginInterceptor .java
public class LoginInterceptor implements Interceptor {
private Log logger=LogFactory.getLog(LoginInterceptor.class);
private MemberDao memberDao=new MemberDao();
@Override
public void destroy() {
}
@Override
public void init() {
}
@Override
public String intercept(ActionInvocation chain) throws Exception {
ActionContext actionContext = chain.getInvocationContext();
ActionProxy proxy = chain.getProxy();
String methodNmae = proxy.getMethod();
if(!"login".equals(methodNmae)) {
logger.info("执行会员拦截器");
Map<String, Object> sessionMap = actionContext.getSession();
if(sessionMap==null||sessionMap.get("memberName")==null) {
logger.info("没有登录");
return "login";
}
}
String flag = chain.invoke();
return flag;
}
}
1.2.3 listener
MyHttpSessionAttributeListener .java
public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener{
private Log logger=LogFactory.getLog(MyHttpSessionAttributeListener.class);
@Override
public void attributeAdded(HttpSessionBindingEvent arg0) {
logger.info("注册在线人员");
HttpSession session = arg0.getSession();
String key=arg0.getName();
logger.info("注册在线人员-- key:"+key);
if(!"memberName".equals(key)) {return;}
ServletContext sc = session.getServletContext();
List<String> online=(List<String>) sc.getAttribute("online");
online.add((String)arg0.getValue());
logger.info("注册在线人员:"+(String)arg0.getValue());
logger.info("在线列表:"+online);
}
@Override
public void attributeRemoved(HttpSessionBindingEvent arg0) {
}
@Override
public void attributeReplaced(HttpSessionBindingEvent arg0) {
}
}
MyHttpSessiontListener .java
public class MyHttpSessiontListener implements HttpSessionListener{
private Log logger=LogFactory.getLog(MyHttpSessiontListener.class);
@Override
public void sessionCreated(HttpSessionEvent arg0) {
}
@Override
public void sessionDestroyed(HttpSessionEvent arg0) {
logger.info("移除在线人员");
HttpSession session = arg0.getSession();
Object object = session.getAttribute("memberName");
if(object==null) {return;}
String str=(String) object;
ServletContext sc = session.getServletContext();
List<String> online=(List<String>) sc.getAttribute("online");
online.remove(str);
logger.info("移除在线人员:"+str);
logger.info("在线列表:"+online);
}
}
MyServletContextListener .java
public class MyServletContextListener implements ServletContextListener{
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext sc = sce.getServletContext();
sc.setAttribute("online", new ArrayList<String>());
}
}
1.2.6 util
JdbcUtil .java
public class JdbcUtil {
private static DataSource dataSource;
static {
try {
Properties p=new Properties();
p.load(JdbcUtil.class.getResourceAsStream("/db.properties"));
dataSource = BasicDataSourceFactory.createDataSource(p);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public static QueryRunner getQr() {
return new QueryRunner(dataSource);
}
}
src/db.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/day11
password=root
username=root
maxActive=20
minIdle=3
initialSize=20
1.2.6 controller
LoginAction.java
public class LoginAction extends ActionSupport {
private MemberDao memberDao=new MemberDao();
private Log logger=LogFactory.getLog(LoginAction.class);
private MemberEntity member;
public void setMember(MemberEntity member) {
this.member = member;
}
public MemberDao getMemberDao() {
return memberDao;
}
public void setMemberDao(MemberDao memberDao) {
this.memberDao = memberDao;
}
public MemberEntity getMember() {
return member;
}
public String login() {
logger.info(member);
ActionContext ac = ActionContext.getContext();
Map<String, Object> req = ac.getContextMap();
if(member==null||member.getName()==null||member.getPassword()==null) {
req.put("msg", "用户名为空/用户密码为空");
return "error";
}
MemberEntity memberEntity = memberDao.findByUserName(member.getName());
if(memberEntity==null) {
req.put("msg", "用户名不存在");
return "error";
}
if(!memberEntity.getPassword().equals(member.getPassword())) {
req.put("msg", "用户密码不正确");
return "error";
}
logger.info("登录成功");
HttpServletRequest req1 = ServletActionContext.getRequest();
HttpSession session = req1.getSession();
session.setAttribute("memberName", memberEntity.getName());
return SUCCESS;
}
public String loginOut() {
logger.info("用户注销");
HttpSession session = ServletActionContext.getRequest().getSession(false);
if(session!=null) {
session.invalidate();
}
return "loginOut";
}
}
MemberAction .java
public class MemberAction extends ActionSupport {
private MemberDao memberDao=new MemberDao();
private Log logger=LogFactory.getLog(MemberAction.class);
public String list() {
List<MemberEntity> memberList = memberDao.selectAll();
HttpServletRequest req = ServletActionContext.getRequest();
List<String> obline=(List<String>) req.getServletContext().getAttribute("online");
logger.info("在线人员列表:"+obline);
HttpSession session = req.getSession(false);
String memberName = (String) session.getAttribute("memberName");
long creationTime = session.getCreationTime();
long onlineTime=creationTime/60;
List<OnlineEntity> result=new ArrayList<OnlineEntity>();
logger.info("会员列表:"+memberList);
memberList.stream().forEach(e->{
OnlineEntity item = e.convert();
item.setActiveTime(onlineTime+"分钟");
item.setIsOnline(obline.contains(e.getName())?"在线":"不在线");
item.setSessoionId(session.getId());
result.add(item);
});
req.setAttribute("result", result);
return SUCCESS;
}
}
1.2.7 配置
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<listener>
<listener-class>org.jsoft.listener.MyHttpSessiontListener</listener-class>
</listener>
<listener>
<listener-class>org.jsoft.listener.MyServletContextListener</listener-class>
</listener>
<listener>
<listener-class>org.jsoft.listener.MyHttpSessionAttributeListener</listener-class>
</listener>
<!-- 引入struts核心过滤器 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>
src/struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="xxxx" extends="struts-default">
<interceptors>
<!-- 自定义拦截器 -->
<interceptor name="memberInterceptor" class="org.jsoft.interceptor.LoginInterceptor"></interceptor>
<!-- 自定义拦截器 -->
<interceptor name="testInterceptor" class="org.jsoft.interceptor.HelloInterceptor"></interceptor>
<!-- 自定义拦截器栈 -->
<interceptor-stack name="myStack">
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="memberInterceptor"/>
<interceptor-ref name="testInterceptor"/>
</interceptor-stack>
</interceptors>
<!-- 指定执行的拦截器 -->
<default-interceptor-ref name="myStack"/>
<global-results>
<result name="login" type="redirect">/login.jsp</result>
</global-results>
<action name="login" class="org.jsoft.action.LoginAction" method="login">
<result name="success" type="redirect">/list</result>
<result name="error" type="redirect">/login.jsp</result>
</action>
<action name="loginOut" class="org.jsoft.action.LoginAction" method="loginOut">
<result name="loginOut" type="redirect">/login.jsp</result>
</action>
<action name="list" class="org.jsoft.action.MemberAction" method="list">
<result name="success" type="dispatcher">/list.jsp</result>
</action>
</package>
</struts>
log4j.properties
#1.设置Logger组件
log4j.rootLogger=info, console,file,A1
###################################################################################################################
#2.设置Appender组件1---输出内容到控制台
log4j.appender.console=org.apache.log4j.ConsoleAppender
##### 设置布局类:org.apache.log4j.PatternLayout(可以灵活地指定布局模式)包含选项:
log4j.appender.console.layout=org.apache.log4j.PatternLayout
##### 设置布局类的输出格式:ConversionPattern=%m%n :指定怎样格式化指定的消息
#2009-09-29 07:30:43,265 INFO com.itcast.web.controller.SearchCdServlet.doGet() - e
log4j.appender.console.layout.ConversionPattern=%d %p %c.%M() - %m%n
###################################################################################################################
#3.设置Appender组件2---输出内容到文件
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.Threshold=WARN
log4j.appender.file.Append=false
## 在classpath路径下生成日志文件,即demo/web-inf/classes/
log4j.appender.file.File=weblog.txt
##### 设置布局类:org.apache.log4j.PatternLayout(可以灵活地指定布局模式)包含选项:
log4j.appender.file.layout=org.apache.log4j.PatternLayout
##### 设置布局类的输出格式:ConversionPattern=%m%n :指定怎样格式化指定的消息
#2009-09-29 07:30:43,265 INFO com.itcast.web.controller.SearchCdServlet.doGet() - e
log4j.appender.file.layout.ConversionPattern=%d %p %c.%M() - %m%n
1.2.8 前端
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
${msg}
<form action="./login" method="post">
用户名:<input type="text" name="member.name" /> <br/>
密码:<input type="text" name="member.password"/><br/>
<input type="submit" /><br/>
</form>
</body>
</html>
list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
尊敬的会员${sessionScope.memberName}您好:
<a href="./loginOut">注销</a>
<table border="1" style="margin:100px auto;" cellspacting="1" cellpadding="1" >
<tr>
<th>ID</th>
<th>会员名</th>
<th>在线时间(分钟)</th>
<th>sessionID</th>
<th>会否在线</th>
</tr>
<c:if test="${not empty result}">
<c:forEach items="${result}" var="item" varStatus="vs">
<tr>
<th>${item.memberId }</th>
<th>${item.memberName }</th>
<th>${item.activeTime }</th>
<th>${item.sessoionId }</th>
<th>${item.isOnline }</th>
</tr>
</c:forEach>
</c:if>
</table>
</body>
</html>
1.4 实现效果
登录界面
在线列表展示界面