SSH登陆模块
来源:互联网 发布:霸王别姬 知乎 蒋雯丽 编辑:程序博客网 时间:2024/06/06 06:18
利用Maven搭建的SSH实现带有验证码和密码加密方式的登陆功能。
搭建SSH
首先搭建SSH,可以参考利用Maven搭建SSM项目
配置实体类
利用注解配置User实体类,然后利用Hibernate生成相应的数据表。注意要在Hibernate配置文件中配置实体类的位置和表的生成策略。
@Entity@Table(name = "user")public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long user_id; @Column private String user_code; @Column private String user_name; @Column private String user_password; @Column private Character user_state; public String getUser_code() { return user_code; } public void setUser_code(String user_code) { this.user_code = user_code; } public String getUser_name() { return user_name; } public void setUser_name(String user_name) { this.user_name = user_name; } public String getUser_password() { return user_password; } public Long getUser_id() { return user_id; } public void setUser_id(Long user_id) { this.user_id = user_id; } public void setUser_password(String user_password) { this.user_password = user_password; } public Character getUser_state() { return user_state; } public void setUser_state(Character user_state) { this.user_state = user_state; }}
前端展示页面
一个带有基本功能的展示页面,用Ajax的post方式提交表单数据,如果状态码等于200的话登陆成功,否则登陆失败,打印出登陆失败的信息并刷新验证码。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>登陆界面</title><script src="http://libs.baidu.com/jquery/2.0.0/jquery.js"></script></head><body> <h3>用户登陆</h3> <form action="LoginAction_login.do" id="form1" method="post"> <table> <tr> <td><label for="username">用户名:</label></td> <td><input type="text" name="userName" id="username" /></td> </tr> <tr> <td><label for="password">密码:</label></td> <td><input type="password" name="password" id="password" /></td> </tr> <tr> <td><label for="verify">验证码:</label></td> <td><input type="text" name="verify" id="verify" /></td> </tr> <tr> <td></td> <td><img src="getVerifyAction.do" id="imgCode" /></td> </tr> <tr> <td></td> <td><input type="submit" /></td> </tr> </form> </table></body><script type="text/javascript"> $(function() { $("#imgCode").click(function() { refreshCode(); }); $("#form1").submit( function() { $.post("LoginAction_login.do", $("#form1").serialize(), function(data) { if (data.state == 200) { //跳转界面 alert("success"); } else { alert(data.msg); refreshCode(); } }) return false; }) }) //刷新验证码 function refreshCode() { var url = "getVerifyAction.do?" + new Date().getTime(); //加时间戳防止缓存 $("#imgCode").attr("src", url); }</script></html>
后端逻辑
首先是dao层,同过service层传入的用户名判断是否存在该用户,没有则返回null
public User findUserByName(String name) { String sql = "from User where user_name = ?"; List<User> lists = (List<User>) getHibernateTemplate().find(sql, name); if (lists.isEmpty()) { return null; } return lists.get(0); }
然后是service层,通过controller层传入的User 用户,然后通过判断是否存在该用户,没有则直接抛出异常。有则继续判断密码加密后是否相同。
public void login(User u) { // TODO Auto-generated method stub User u1 = dao.findUserByName(u.getUser_name()); if (u1 == null) { throw new RuntimeException("用户民不存在"); } if (!u1.getUser_password().equals(MD5Utils.md5(u.getUser_password()))) { throw new RuntimeException("密码错误"); } }
生成随机的数字,然后把随机数让入session中,输出到页面。注意验证码是一个独立的Action,直接在img标签的src属性中写入验证码的Action,就会生成验证码图片。或者直接在浏览器输入验证码的Action,就会出现验证码的图片。
@Controller("getVerifyAction")@Scope("prototype")public class GetVerifyAction { /** * 设置验证码 * * @return * @throws IOException * @date 2017年10月15日 上午9:41:38 */ public String getVerifyImpage() throws IOException { HttpServletResponse response = ServletActionContext.getResponse(); HttpServletRequest request = ServletActionContext.getRequest(); response.setContentType("image/jpeg"); response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); HttpSession session = request.getSession(); session.removeAttribute("verifyCode"); int width = 70, height = 23; BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // 获取图形上下文 Graphics g = image.getGraphics(); // 生成随机类 Random random = new Random(); // 设定背景色 g.setColor(getRandColor(200, 250)); g.fillRect(0, 0, width, height); // 设定字体 g.setFont(new Font("Times New Roman", Font.PLAIN, 20)); // 画边框 g.setColor(getRandColor(160, 200)); g.drawRect(0, 0, width - 1, height - 1); // 随机产生100条干扰线 g.setColor(getRandColor(160, 200)); for (int i = 0; i < 100; i++) { int x = random.nextInt(width); int y = random.nextInt(height); int xl = random.nextInt(10); int yl = random.nextInt(10); g.drawLine(x, y, x + xl, y + yl); } // 取随机产生4位数字 String sRand = ""; for (int i = 0; i < 4; i++) { String rand = String.valueOf(random.nextInt(10)); sRand += rand; g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110))); g.drawString(rand, 13 * i + 14, 20); } // 将认证码存入SESSION session.setAttribute("verifyCode", sRand); System.out.println("verifyCode:" + session.getAttribute("verifyCode")); // 图象生效 g.dispose(); // 输出图象到页面 ImageIO.write(image, "JPEG", response.getOutputStream()); return null; } private Color getRandColor(int fc, int bc) {// 给定范围获得随机颜色 Random random = new Random(); if (fc > 255) fc = 255; if (bc > 255) bc = 255; int r = fc + random.nextInt(bc - fc); int g = fc + random.nextInt(bc - fc); int b = fc + random.nextInt(bc - fc); return new Color(r, g, b); }}
登陆的Action,首先判断前端传入的验证码是否和session中的验证相等。
相等则把前台传入的账号,密码封装到User实体中,传入到service中。当然也可以不封装,直接把用户名,密码传入service,前台参数少可以这么做。如果前台传入的参数很多的话,最好封装到相对应的实体类中,一方面是更能体现出相对对象的写法,另一方面是写出的代码更加利于维护和简洁。
调用完service层方法后,如果没有抛出异常,则说明用户名和密码匹配。如果不匹配,就会抛出相应的异常,并且捕捉到Map集合中。
public class LoginAction extends ActionSupport { @Autowired LoginService service; /** * 登陆 * * @return * @throws IOException * @date 2017年10月15日 下午5:42:47 */ public String login() throws IOException { Map m = new HashMap(); boolean falg = ResultUtils.checkVerifyCode(verify); if (falg) { User u = new User(); u.setUser_name(userName); u.setUser_password(password); try { service.login(u); m.put("state", Result.SUCCESS.getState()); } catch (Exception e) { // TODO: handle exception String message = e.getMessage(); m.put("state", Result.ERROR.getState()); m.put("msg", message); } } else { m.put("state", Result.ERROR.getState()); m.put("msg", "验证码错误"); } //把Map集合转化为Json数据 ResultUtils.toJson(ServletActionContext.getResponse(), m); return null; } private String userName; private String password; private Map<String, Object> jsonResult; private String verify; public String getVerify() { return verify; } public void setVerify(String verify) { this.verify = verify; } public Map<String, Object> getJsonResult() { return jsonResult; } public void setJsonResult(Map<String, Object> jsonResult) { this.jsonResult = jsonResult; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; }}
枚举类型的结果集,创建通过整形初始化和字符串和整形初始化的构造器。比如当调用Result.SUCCESS(200),可以初始化一个state为200的对象。然后Result.SUCCESS(200).getState()就可以获取该参数。
public enum Result { SUCCESS(200), ERROR(400), INFO("请求超时", 100); private String msg; private int state; private Result(int state) { this.state = state; } private Result(String msg, int state) { this.msg = msg; this.state = state; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public int getState() { return state; } public void setState(int state) { this.state = state; }}
MD5加密的工具类,传入相应的密码就会获取该密码的加密的字符串。
public class MD5Utils { /** * 使用md5的算法进行加密 */ public static String md5(String plainText) { byte[] secretBytes = null; try { secretBytes = MessageDigest.getInstance("md5").digest(plainText.getBytes()); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("没有md5这个算法!"); } String md5code = new BigInteger(1, secretBytes).toString(16);// 16进制数字 // 如果生成数字未满32位,需要前面补0 for (int i = 0; i < 32 - md5code.length(); i++) { md5code = "0" + md5code; } return md5code; } public static void main(String[] args) { System.out.println(md5("1234")); }}
由于把对象转化为Json数据和检查验证码是否相等,在许多地方都能够用到,因此把大量重复的代码提取出来,制作成工具类。更加使代码简洁,优雅,也更能体现面对对象的思想。
public class ResultUtils { /** * 转化json数据 * * @date 2017年10月15日 下午4:03:29 */ public static void toJson(HttpServletResponse response, Object data) throws IOException { Gson gson = new Gson(); String result = gson.toJson(data); response.setContentType("text/json; charset=utf-8"); response.setHeader("Cache-Control", "no-cache"); // 取消浏览器缓存 PrintWriter out = response.getWriter(); out.print(result); out.flush(); out.close(); } /** * 验证验证码是否相等 * * @param originVerifyCode * @return * @date 2017年10月15日 上午9:47:30 */ public static boolean checkVerifyCode(String originVerifyCode) { HttpServletRequest request = ServletActionContext.getRequest(); HttpSession session = request.getSession(); String verifyCode = (String) session.getAttribute("verifyCode"); if (originVerifyCode.equals(verifyCode)) { return true; } return false; }}
展示效果
成功
密码错误
用户名不存在
- SSH登陆模块
- 使用python的Paramiko模块登陆SSH
- SSH登陆
- ssh登陆
- ssh登陆
- 登陆模块
- 登陆模块
- 使用pexpect提供的SSH模块登陆linux,并执行命令
- ssh 登陆 cvsnt
- SSH登陆修改端口
- ssh登陆缓慢
- 整合SSH--登陆注册
- ssh无密码登陆
- SSH登陆免密码
- SSH登陆,用XShell
- SSH登陆超级慢!!!
- ssh免密码登陆
- ssh 免密码登陆
- C语言笔记(运算符及表达式)
- C++ 11 thread静态链接getlogicalprocessorinformation导致错误
- Jackson 框架,轻易转换JSON
- Sigmoid 函数
- SpringBoot学习(六)——事务的管理
- SSH登陆模块
- Java面试题Day4
- 欢迎使用CSDN-markdown编辑器
- 删除/全部删除/模糊查询/升降序
- 微信抢票应用-个人总结
- ctrip常见标签的实现方式和优化方案
- LiFS: Low Human-Effort, Device-Free Localization with Fine-Grained Subcarrier Information
- 腾讯X5浏览器 TBS 代替Android WebView展示H5字体大小适配
- CentOS7修改网卡名