首先,數據庫新建兩張表:loginlog 字段:id ,userID,logintime,success
第二張:t_table_id 字段table_name,value ;默認寫入數據loginlog;0
1、Loginlog.java
package com.marcellotest.basedata.domain; /** * 用戶登錄日志 * @author Administrator * */ public class Loginlog { public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getLogintime() { return logintime; } public void setLogintime(String logintime) { this.logintime = logintime; } public int getSuccess() { return success; } public void setSuccess(int success) { this.success = success; } public void setLoginLogID(String loginLogID) { LoginLogID = loginLogID; } public String getLoginLogID() { return LoginLogID; } //主鍵 private String LoginLogID; private String userId; private String logintime; private int success; }
2、LoginlogManager.java
package com.marcellotest.basedata.manager; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import com.marcellotest.basedata.domain.Loginlog; import com.marcellotest.util.DBUtil; import com.marcellotest.util.generator.IDGenerator; public class LoginlogManager { private static LoginlogManager instance = null; private LoginlogManager() {} public static synchronized LoginlogManager getInstance() { if (instance == null) { instance = new LoginlogManager(); } return instance; } /** * 根據userid查詢登錄日志 * @param userid * @return 如果存在返回返回最后三次登錄失敗信息,否則返回null */ public List<String> findUserLOGById(String userID) { StringBuffer sbSql = new StringBuffer(); sbSql.append("select * from loginlog " ) .append("where userId =?" ) .append("and success = 0 " ) .append("and loginTime like ? ") .append("order by logintime DESC ") .append("limit 3 "); Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; Date now = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); String today = dateFormat.format(now); List<String> list = new ArrayList<String>(); try { conn = DBUtil.getConnection(); pstmt = conn.prepareStatement(sbSql.toString()); pstmt.setString(1, userID); pstmt.setString(2,"%"+today+"%"); rs = pstmt.executeQuery(); while(rs.next()){ list.add(rs.getString("LoginLogID")); list.add(rs.getString("userid")); list.add(rs.getString("logintime")); list.add(rs.getString("success")); } }catch(SQLException e) { e.printStackTrace(); }finally { DBUtil.close(rs); DBUtil.close(pstmt); DBUtil.close(conn); } //System.out.println(list); return list; } /** * 添加log記錄到數據庫 * @param client */ public void addUserLOG(Loginlog Loginlog) { StringBuffer sbsql = new StringBuffer(); sbsql.append("insert into loginlog ( ") .append("LoginLogID, userID, loginTime, ") .append("success) ") .append("values (? ,? ,?, ?) "); Connection conn = null; PreparedStatement pstmt = null; Date now = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String createDate = dateFormat.format(now); try { conn = DBUtil.getConnection(); //開啟事務 DBUtil.setAutoCommit(conn, false); pstmt = conn.prepareStatement(sbsql.toString()); pstmt.setInt(1, (int)IDGenerator.getInstance().newID("loginlog")); pstmt.setString(2, Loginlog.getUserId()); pstmt.setString(3, createDate); pstmt.setInt(4, Loginlog.getSuccess()); pstmt.executeUpdate(); //提交事務 DBUtil.commit(conn); }catch(Exception e) { e.printStackTrace(); //回滾事務 DBUtil.rollback(conn); }finally { DBUtil.close(pstmt); DBUtil.close(conn); } } }
3、LoginlogUtil.java
package com.marcellotest.util; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import com.marcellotest.basedata.domain.Loginlog; import com.marcellotest.basedata.manager.LoginlogManager; public class LoginlogUtil { private static LoginlogUtil instance = null; private LoginlogUtil() {} public static synchronized LoginlogUtil getInstance() { if (instance == null) { instance = new LoginlogUtil(); } return instance; } static Loginlog Loginlog = new Loginlog(); /** * 添加日志信息 * @param userid * @return */ public void ADDloginlogItem(Loginlog loginlog) { Loginlog.setUserId(loginlog.getUserId()); Loginlog.setSuccess(loginlog.getSuccess()); LoginlogManager.getInstance().addUserLOG(Loginlog); } /** * 判斷該用戶名是否符合登錄要求 * 5分鍾內輸錯三次鎖住該用戶 */ public boolean SelectloginlogItem(Loginlog loginlog){ //把查詢出來的數據放入list中 List<String> list = new ArrayList<String>(); list= LoginlogManager.getInstance().findUserLOGById(loginlog.getUserId()); boolean flag = false; System.out.println("個數"+list.size()); //循環 //for(String str : list){ // System.out.println(str); // } //判斷是否含有3行數據,如果沒有直接返回true if(list.size()<12){ flag = true; } else{ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { //現狀的時間 Date now = new Date(); //最后一次輸錯時間 Date ErrorOne= df.parse(list.get(2)); //前三次輸錯時間 Date ErrorTree = df.parse(list.get(10)); //最后一次輸錯時間和目前嘗試登陸時間 long spaceTIME = now.getTime()-ErrorOne.getTime(); long spaceTIMEmin = spaceTIME/1000; //最后三次間隔時間 long DifferTime=ErrorOne.getTime()-ErrorTree.getTime(); //long day=l/(24*60*60*1000); //long hour=(l/(60*60*1000)-day*24); //long min=((l/(60*1000))-day*24*60-hour*60); // long s=(l/1000-day*24*60*60-hour*60*60-min*60); //轉換成秒進行比較 long s1=DifferTime/1000; //System.out.println(""+day+"天"+hour+"小時"+min+"分"+s+"秒"); System.out.println(s1); //判斷時間是否間隔一個小時 if(spaceTIMEmin>=3600) { flag=true; } else{ //判斷是否5分鍾內輸入三次錯誤; if(s1<=300){ flag = true; } else{ flag = false; } } } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } //String a = list.get(2); //System.out.println(a); //String b = list.get(10); //System.out.println(b); } return flag; } public static void main(String[] args) { } }
生成唯一ID:IDGenerator.java
package com.marcellotest.util.generator; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import com.marcellotest.util.DBUtil; /** * id生成器,采用單例模式 * @author Administrator * */ public class IDGenerator { private static IDGenerator instance = new IDGenerator(); private IDGenerator() {} public static IDGenerator getInstance() { return instance; } /** * 生成新id * @param tableName * @return */ //public synchronized long newID(String tableName) { //synchronized(this) { public long newID(String tableName) { String sql = "select value from t_table_id where table_name=? for update"; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; long value = 0L; try { conn = DBUtil.getConnection(); ////開啟事務 DBUtil.setAutoCommit(conn, false); pstmt = conn.prepareStatement(sql); pstmt.setString(1, tableName); rs = pstmt.executeQuery(); if (rs.next()) { value = rs.getLong("value"); }else { throw new RuntimeException("生成Id出錯!"); } value = value + 1; //更新value modifyValueField(conn, tableName, value); //提交事務 DBUtil.commit(conn); }catch(Exception e) { e.printStackTrace(); //回滾事務 DBUtil.rollback(conn); throw new RuntimeException("生成Id出錯!"); }finally { DBUtil.close(rs); DBUtil.close(pstmt); DBUtil.close(conn); } return value; } /** * 更新value * @param conn * @param tableName * @param value * @throws SQLException */ private void modifyValueField(Connection conn, String tableName, long value) throws SQLException { String sql = "update t_table_id set value=? where table_name=?"; PreparedStatement pstmt = null; try { pstmt = conn.prepareStatement(sql); pstmt.setLong(1, value); pstmt.setString(2, tableName); pstmt.executeUpdate(); }finally { DBUtil.close(pstmt); } } public static void main(String[] args) { long newId = IDGenerator.getInstance().newID("t_client"); System.out.println(newId); } }
登陸時調用
/** * * 登錄(采用非受控異常) * @param userId * @param password */ public User login(String userId, String password) { CipherUtil cipher = new CipherUtil(); Loginlog loginlog = new Loginlog(); loginlog.setUserId(userId); //throws UserNotFoundException, PasswordNotCorrectException{ //必須拋出 User user = findUserById(userId); if (user == null) { System.out.println(user); throw new UserNotFoundException("用戶代碼不能找到,代碼=【" + userId +"】"); } //采用加密方式 if (!user.getPassword().equals(cipher.generatePassword(password))) { //調用記錄日志函數 loginlog.setSuccess(0); LoginlogManager.getInstance().addUserLOG(loginlog); throw new PasswordNotCorrectException("密碼不正確"); } if(!LoginlogUtil.getInstance().SelectloginlogItem(loginlog)){ throw new PasswordNotCorrectException("一小時后再試試"); } System.out.println("user"); //調用記錄日志函數 loginlog.setSuccess(1); LoginlogManager.getInstance().addUserLOG(loginlog); return user; }
有些人會說寫入日志時在調用時:
loginlog.setUserId(userId);
loginlog.setSuccess(1);
業務邏輯層又一次,為什么不直接登陸時候直接調用;這邊是為了把這些都分開,如果大公司,業務層,邏輯層都是分開的,就是說你登陸只能調用邏輯層;
最后調用時候的拋出異常類我沒有繼續寫了,如果有需要根據實際情況寫拋出;