Java项目:UMS 用户管理系统(四)

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: Java项目:UMS 用户管理系统(四)

8、UMS-验证码校验【阶段2】


8.1、需求说明


8.2、点击切换验证码


8.2.1、需求分析


8.2.2、代码实现


/login/login.jsp


<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-1.11.3.min.js"></script>
<script type="text/javascript">
   var m1Src;//图片验证码src
   $(function(){
      //为验证码图片绑定点击切换图片功能
      $("#m1").click(function(){
         var m1 = $(this);
         if(m1Src==undefined){
            m1Src = m1.prop("src");
         }
         m1.prop("src",m1Src+"&t="+new Date().getTime());
      });
   });
</script>
<tr>
   <td height="30" nowrap>
      <strong><font color="000F60">验证码: </font> </strong>
   </td>
   <td>
      <input type="text" name="verifyCode" class="text" style="width: 50px;"/>
      <img id="m1" src="<%=pageContext.getServletContext().getContextPath()%>/vc?method=vc" style="height:30px;width:100px;"/>
   </td>
</tr>

VerifyCodeServlet


/**
 * 生成验证码,正确答案保存session
 */
public void vc() throws IOException {
    String vci = createVerifyCodeImage();
    System.out.println(vci);
    getRequest().getSession().setAttribute("vci",vci);
}

8.3、验证码校验


8.3.1、需求分析


8.3.2、代码实现


/login/login.jsp
<tr>
   <td height="30" nowrap>
      <strong><font color="000F60">验证码: </font> </strong>
   </td>
   <td>
      <input type="text" name="verifyCode" class="text" style="width: 50px;"/>
      <img id="m1" src="<%=pageContext.getServletContext().getContextPath()%>/vc?method=vc" style="height:30px;width:100px;"/>
   </td>
</tr>


UserServlet

/**
 * 用户登录
 * @return
 */
public String login(){
    //一、先进行验证码校验
    //1、分别获取表单验证码和正确验证码
    String verifyCode = getRequest().getParameter("verifyCode");
    String vci = (String) getRequest().getSession().getAttribute("vci");
    //2、为了防止被重复校验验证码,正确验证码使用一次,就要从session中消除
    getRequest().getSession().removeAttribute("vci");
    //3、校验判断,若校验失败,直接返回错误信息,不用进行用户登录判断
    //若用户未提交验证码 或者 正确验证码不存在  或者 两个验证码不同    ABCD和 abcd 相同
    if(verifyCode==null || vci==null || !vci.equalsIgnoreCase(verifyCode)){
        //校验失败
        getRequest().setAttribute("errorMsg","验证码校验失败");
        return "forward:/login/login.jsp";
    }
    //4、校验成功,继续进行登录校验【无代码,直接向后运行】
    //二、再进行用户登录校验
    //1、接收表单参数
    User param = toBean(User.class);
    //2、调用service进行登录处理
    User result = null;
    try {
        result = userService.login(param);
    } catch (Exception e) {
        //抛出异常,登录也是失败
        getRequest().setAttribute("errorMsg",e.getMessage());
        return "forward:/login/login.jsp";
    }
    //3、根据返回结果,跳转不同的页面
    if(result!=null){
        //登录成功
        getRequest().getSession().setAttribute("loginUser",result);
        return "redirect:/index.jsp";
    }else{
        //登录失败
        getRequest().setAttribute("errorMsg","用户名或密码错误");
        return "forward:/login/login.jsp";
    }
}

9、UMS-记住用户名【阶段2】


9.1、需求说明


9.2、需求分析


分析:


关键点:


1、使用cookie技术保存数据到浏览器7天


Cookie c = new Cookie("key","value");


c.setMaxAge(60*60*24*7);//秒


getResponse().addCookie(c);


2、cookie数据JSP回显


<%


//查找指定cookie的固定代码格式


Cookie[] arr = request.getCookies();


String value = "";//开关


//若浏览器没有发来任何cookie,null


if(arr!=null){


for(Cookie c:arr){


if(c.getName().equals("要查找的cookie名")){


value=c.getValue();


break;


}


}


}


//JSP数据回显


//回显


out.write(value);


%>


<%=cookieValue%>


3、cookie覆盖问题


两个cookie是追加还是相互覆盖主要看 唯一标识(域名+有效路径+cookie名)


注意:因为都是一个服务器进行编写,所以域名默认相同,我们在进行编码时,cookie名肯定相同。


有效路径统一设置为项目名:  /项目名


4、cookie保存中文问题


cookie不能直接保存中文。


URL编码来保存中文,URL解码来读取中文。


URL编码:URLEncoder.encode("","utf-8");


URL解码:URLDecoder.decode("","utf-8");


流程:


9.3、代码实现


//cookie数据保存:


/login/login.jsp


<tr>
   <td height="30" nowrap>
   </td>
   <td>
      <input type="checkbox" name="autoLogin" value="yes"/>自动登录
      <input type="checkbox" name="remember" value="yes"/>记住用户名
   </td>
</tr>


UserServlet


/**
 * 用户登录
 * @return
 */
public String login() throws UnsupportedEncodingException {
    //一、先进行验证码校验
    //1、分别获取表单验证码和正确验证码
    String verifyCode = getRequest().getParameter("verifyCode");
    String vci = (String) getRequest().getSession().getAttribute("vci");
    //2、为了防止被重复校验验证码,正确验证码使用一次,就要从session中消除
    getRequest().getSession().removeAttribute("vci");
    //3、校验判断,若校验失败,直接返回错误信息,不用进行用户登录判断
    //若用户未提交验证码 或者 正确验证码不存在  或者 两个验证码不同    ABCD和 abcd 相同
    if(verifyCode==null || vci==null || !vci.equalsIgnoreCase(verifyCode)){
        //校验失败
        getRequest().setAttribute("errorMsg","验证码校验失败");
        return "forward:/login/login.jsp";
    }
    //4、校验成功,继续进行登录校验【无代码,直接向后运行】
    //二、再进行用户登录校验
    //1、接收表单参数
    User param = toBean(User.class);
    //2、调用service进行登录处理
    User result = null;
    try {
        result = userService.login(param);
    } catch (Exception e) {
        //抛出异常,登录也是失败
        getRequest().setAttribute("errorMsg",e.getMessage());
        return "forward:/login/login.jsp";
    }
    //3、根据返回结果,跳转不同的页面
    if(result!=null){
        //登录成功
        getRequest().getSession().setAttribute("loginUser",result);
        //三、判断用户是否需要记住用户名
        //1、尝试从请求中获取remember参数
        String rememberStr = getRequest().getParameter("remember");
        //2、判断remember参数,如果remember不为null,记住用户名
        if(rememberStr!=null){
            Cookie remember = new Cookie("remember", URLEncoder.encode(result.getLoginName(), "utf-8"));
            remember.setPath(getRequest().getContextPath());
            remember.setMaxAge(60*60*24*7);
            getResponse().addCookie(remember);
        }else{
            //3、remember为null,删除之前记住的用户名
            Cookie remember = new Cookie("remember", "");
            remember.setPath(getRequest().getContextPath());
            remember.setMaxAge(0);
            getResponse().addCookie(remember);
        }
        return "redirect:/index.jsp";
    }else{
        //登录失败
        getRequest().setAttribute("errorMsg","用户名或密码错误");
        return "forward:/login/login.jsp";
    }
}


优化UserServlet


/**
 * 用户登录
 * @return
 */
public String login() throws UnsupportedEncodingException {
    //一、先进行验证码校验
    //1、分别获取表单验证码和正确验证码
    String verifyCode = getRequest().getParameter("verifyCode");
    String vci = (String) getRequest().getSession().getAttribute("vci");
    //2、为了防止被重复校验验证码,正确验证码使用一次,就要从session中消除
    getRequest().getSession().removeAttribute("vci");
    //3、校验判断,若校验失败,直接返回错误信息,不用进行用户登录判断
    //若用户未提交验证码 或者 正确验证码不存在  或者 两个验证码不同    ABCD和 abcd 相同
    if(verifyCode==null || vci==null || !vci.equalsIgnoreCase(verifyCode)){
        //校验失败
        getRequest().setAttribute("errorMsg","验证码校验失败");
        return "forward:/login/login.jsp";
    }
    //4、校验成功,继续进行登录校验【无代码,直接向后运行】
    //二、再进行用户登录校验
    //1、接收表单参数
    User param = toBean(User.class);
    //2、调用service进行登录处理
    User result = null;
    try {
        result = userService.login(param);
    } catch (Exception e) {
        //抛出异常,登录也是失败
        getRequest().setAttribute("errorMsg",e.getMessage());
        return "forward:/login/login.jsp";
    }
    //3、根据返回结果,跳转不同的页面
    if(result!=null){
        //登录成功
        getRequest().getSession().setAttribute("loginUser",result);
        //三、判断用户是否需要记住用户名
        //1、尝试从请求中获取remember参数
        String rememberStr = getRequest().getParameter("remember");
        //2、判断remember参数,如果remember不为null,记住用户名
        Cookie remember = new Cookie("remember", "");
        remember.setPath(getRequest().getContextPath());
        if(rememberStr!=null){
            remember.setValue(URLEncoder.encode(result.getLoginName(), "utf-8"));
            remember.setMaxAge(60*60*24*7);
        }else{
            //3、remember为null,删除之前记住的用户名
            remember.setMaxAge(0);
        }
        getResponse().addCookie(remember);
        return "redirect:/index.jsp";
    }else{
        //登录失败
        getRequest().setAttribute("errorMsg","用户名或密码错误");
        return "forward:/login/login.jsp";
    }
}


//cookie数据回显:  (用户名,复选框)


/login/login.jsp


<%
   //1、从cookie中获取用户名
   //1.1、获取cookie数组
   Cookie[] arr = request.getCookies();
   //1.2、遍历数组,寻找记录用户名cookie,取出value值
   String rememberUsername = "";//为了在展示JSP时,不存在记录的用户名不能展示null,不利于用户体现
   if(arr!=null){
      for (Cookie c : arr) {
         if(c.getName().equals("remember")){
            rememberUsername = URLDecoder.decode(c.getValue(),"utf-8");
            break;
         }
      }
   }
%>
<tr>
   <td height="30" nowrap>
      <font color="000F60"><strong>用户名:</strong> </font>
   </td>
   <td>
      <input type="text" name="loginName" class="test" style="width: 160px;" value="<%=rememberUsername%>"/>
   </td>
</tr>
<tr>
   <td height="30" nowrap>
   </td>
   <td>
      <input type="checkbox" name="autoLogin" value="yes"/>自动登录
      <input type="checkbox" name="remember" value="yes"
         <%
            //用户名不是空字符串,说明之前用户 记录用户名,框体就应该被回显选中
            if(!rememberUsername.equals("")){
               out.write("checked='checked'");
            }
         %>
      />记住用户名
   </td>
</tr>

10、UMS-MD5校验【扩展】


10.1、需求说明


密码   敏感数据可能存在泄露和丢失


担心:保存在服务器上会不会泄露


拷贝走数据(非项目组成员)


不道德程序员,记录下来


对敏感数据,例如密码进行加密操作。


public static void main(String[] args) {
    //因为加密算法是固定的,对同一个数据加密两次,加密结果是相同的
    String str = "沈洋洋";
    String md5 = UMSUtils.getMD5(str);
    System.out.println(md5);//f7370f7dc09f3ab88ea1d81283fb725f
    String md52 = UMSUtils.getMD5(str);
    System.out.println(md52);//f7370f7dc09f3ab88ea1d81283fb725f
}

10.2、需求分析


添加用户:输入用户密码进行保存,对密码进行md5加密


编辑用户:密码回显和修改,对修改密码进行md5加密


用户登录:对表单输入的密码进行md5加密


10.3、代码修改


添加用户:


UserService


/**
 * 添加用户
 * @param param
 * @return
 */
public boolean addUser(User param) {
    //1、生成随机ID
    param.setId(UUID.randomUUID().toString().replaceAll("-",""));
    //敏感数据进行MD5加密
    param.setLoginPwd(UMSUtils.getMD5(param.getLoginPwd()));
    //2、调用Dao进行数据保存
    //3、try...catch对处理结果进行判断:没有出现异常,保存成功,否则保存失败
    try {
        userDao.addUser(param);
    } catch (Exception e) {
        //出现异常,添加失败
        return false;
    }
    //没有出现异常,添加成功
    return true;
}

编辑用户:


可能性:


加密密码回显表单后,用户没有对加密密码进行过任何修改,加密密码不要被再次加密

加密密码回显表单后,用户对加密密码进行过修改,对密码进行重新加密

解决:


在页面添加一个隐藏域:pwdSource  源密码(加密密码)


servlet、service进行判断:


如果表单密码框数据 == 源密码,说明用户未对密码进行修改,不需要对表单密码进行再次加密


如果表单密码框数据 != 源密码,说明用户一定对密码进行了修改,需要对表单密码进行再次加密。


BUG:用户新改的密码 和 md5源加密密码一致,无法判断。


edit.jsp


<form method="post" action="<%=pageContext.getServletContext().getContextPath()%>/user">
<input type="hidden" name="method" value="modifyUser" />
      <input type="hidden" name="id" value="${user.id}" />
<input type="hidden" name="pwdResource" value="${user.loginPwd}" />


UserServlet

/**
 * 修改用户信息
 * @return
 */
public String modifyUser(){
    //获取源密码
    String pwdResource = getRequest().getParameter("pwdResource");
    //1、获取所有表单数据
    User param = toBean(User.class);
    //2、调用service进行保存
    boolean result = userService.modifyUser(param,pwdResource);
    //3、根据service保存结果,进行展示
    if(result){
        //修改成功
        return "redirect:/user?method=list";
    }else{
        //修改失败
        getRequest().setAttribute("errorMsg","修改失败");
        return "forward:/user/error.jsp";
    }
}

UserService


/**
 * 修改用户信息
 * @param param
 * @param pwdResource
 * @return
 */
public boolean modifyUser(User param, String pwdResource) {
    try {
        //1、查询所有用户信息
        List<User> ulist = userDao.searchAll();
        //2、迭代删除被修改的用户
        if(ulist!=null){
            Iterator<User> it = ulist.iterator();
            while (it.hasNext()){
                User next = it.next();
                if(next.getId().equals(param.getId())){
                    it.remove();
                    break;
                }
            }
        }
        //在向ulist追加之前,要对密码进行处理,用户表单密码到底要不要加密
        //表单密码==源密码,说明用户未修改,不要再次加密(无代码)
        //表单密码!=源密码,说明用户已修改,需要再次加密
        if(!param.getLoginPwd().equals(pwdResource)){
            param.setLoginPwd(UMSUtils.getMD5(param.getLoginPwd()));
        }
        //3、向集合追加被修改用户的新信息
        ulist.add(param);
        //4、以覆盖方式写回xml
        userDao.saveUlist(ulist);
    } catch (Exception e) {
        return false;
    }
    return true;
}


LoginServlet


/**
 * 用户登录。    用户登录成功,返回User对象。 登录失败,返回Null
 * @param param
 * @return
 */
public User login(User param) {
    //对表单密码进行加密
    param.setLoginPwd(UMSUtils.getMD5(param.getLoginPwd()));
    //1、获取所有用户信息
    List<User> ulist = userDao.searchAll();
    //2、遍历所有用户信息
    if(ulist!=null){
        for (User u : ulist) {
            //3、每遍历一个用户信息,对比表单用户名是否正确,对比表单密码是否正确. 都正确,登录成功
            if(u.getLoginName().equals(param.getLoginName())
                && u.getLoginPwd().equals(param.getLoginPwd())){
                return u;
            }
        }
    }
    //4、经过遍历,没有一个成功,登录失败
    return null;
}
相关文章
|
3天前
|
运维 自然语言处理 供应链
Java云HIS医院管理系统源码 病案管理、医保业务、门诊、住院、电子病历编辑器
通过门诊的申请,或者直接住院登记,通过”护士工作站“分配患者,完成后,进入医生患者列表,医生对应开具”长期医嘱“和”临时医嘱“,并在电子病历中,记录病情。病人出院时,停止长期医嘱,开具出院医嘱。进入出院审核,审核医嘱与住院通过后,病人结清缴费,完成出院。
20 3
|
2天前
|
前端开发 Java 数据库
如何实现一个项目,小白做项目-java
本教程涵盖了从数据库到AJAX的多个知识点,并详细介绍了项目实现过程,包括静态页面分析、数据库创建、项目结构搭建、JSP转换及各层代码编写。最后,通过通用分页和优化Servlet来提升代码质量。
10 1
|
7天前
|
Java 数据库连接 数据库
深入探讨Java连接池技术如何通过复用数据库连接、减少连接建立和断开的开销,从而显著提升系统性能
在Java应用开发中,数据库操作常成为性能瓶颈。本文通过问题解答形式,深入探讨Java连接池技术如何通过复用数据库连接、减少连接建立和断开的开销,从而显著提升系统性能。文章介绍了连接池的优势、选择和使用方法,以及优化配置的技巧。
11 1
|
9天前
|
JavaScript Java 项目管理
Java毕设学习 基于SpringBoot + Vue 的医院管理系统 持续给大家寻找Java毕设学习项目(附源码)
基于SpringBoot + Vue的医院管理系统,涵盖医院、患者、挂号、药物、检查、病床、排班管理和数据分析等功能。开发工具为IDEA和HBuilder X,环境需配置jdk8、Node.js14、MySQL8。文末提供源码下载链接。
|
12天前
|
移动开发 前端开发 JavaScript
java家政系统成品源码的关键特点和技术应用
家政系统成品源码是已开发完成的家政服务管理软件,支持用户注册、登录、管理个人资料,家政人员信息管理,服务项目分类,订单与预约管理,支付集成,评价与反馈,地图定位等功能。适用于各种规模的家政服务公司,采用uniapp、SpringBoot、MySQL等技术栈,确保高效管理和优质用户体验。
|
14天前
|
XML JSON 监控
告别简陋:Java日志系统的最佳实践
【10月更文挑战第19天】 在Java开发中,`System.out.println()` 是最基本的输出方法,但它在实际项目中往往被认为是不专业和不足够的。本文将探讨为什么在现代Java应用中应该避免使用 `System.out.println()`,并介绍几种更先进的日志解决方案。
38 1
|
18天前
|
Java 关系型数据库 API
介绍一款Java开发的企业接口管理系统和开放平台
YesApi接口管理平台Java版,基于Spring Boot、Vue.js等技术,提供API接口的快速研发、管理、开放及收费等功能,支持多数据库、Docker部署,适用于企业级PaaS和SaaS平台的二次开发与搭建。
|
6月前
|
JavaScript Java 测试技术
基于Java的通讯录管理系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的通讯录管理系统的设计与实现(源码+lw+部署文档+讲解等)
144 5
|
存储 Java 关系型数据库
Java+Swing实现通讯录管理系统
Java+Swing实现通讯录管理系统
361 0
Java+Swing实现通讯录管理系统
|
设计模式 前端开发 Java
Java通讯录管理系统
使用DAO分层设计模式设计了通讯管理系统 使用了c3p0地址池和dbutils,没有写前端,连接的是mysql数据库,不涉及到太多的技术,仅供入门JDBC的小伙伴参考一下
Java通讯录管理系统