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

简介: 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 设计模式之观察者模式:构建松耦合的事件响应系统
观察者模式是Java中常用的行为型设计模式,用于构建松耦合的事件响应系统。当一个对象状态改变时,所有依赖它的观察者将自动收到通知并更新。该模式通过抽象耦合实现发布-订阅机制,广泛应用于GUI事件处理、消息通知、数据监控等场景,具有良好的可扩展性和维护性。
349 8
|
3月前
|
移动开发 监控 小程序
java家政平台源码,家政上门清洁系统源码,数据多端互通,可直接搭建使用
一款基于Java+SpringBoot+Vue+UniApp开发的家政上门系统,支持小程序、APP、H5、公众号多端互通。涵盖用户端、技工端与管理后台,支持多城市、服务分类、在线预约、微信支付、抢单派单、技能认证、钱包提现等功能,源码开源,可直接部署使用。
283 24
|
3月前
|
安全 前端开发 Java
使用Java编写UDP协议的简易群聊系统
通过这个基础框架,你可以进一步增加更多的功能,例如用户认证、消息格式化、更复杂的客户端界面等,来丰富你的群聊系统。
193 11
|
3月前
|
机器学习/深度学习 人工智能 自然语言处理
Java与生成式AI:构建内容生成与创意辅助系统
生成式AI正在重塑内容创作、软件开发和创意设计的方式。本文深入探讨如何在Java生态中构建支持文本、图像、代码等多种生成任务的创意辅助系统。我们将完整展示集成大型生成模型(如GPT、Stable Diffusion)、处理生成任务队列、优化生成结果以及构建企业级生成式AI应用的全流程,为Java开发者提供构建下一代创意辅助系统的完整技术方案。
249 10
|
3月前
|
人工智能 监控 Java
Java与AI智能体:构建自主决策与工具调用的智能系统
随着AI智能体技术的快速发展,构建能够自主理解任务、制定计划并执行复杂操作的智能系统已成为新的技术前沿。本文深入探讨如何在Java生态中构建具备工具调用、记忆管理和自主决策能力的AI智能体系统。我们将完整展示从智能体架构设计、工具生态系统、记忆机制到多智能体协作的全流程,为Java开发者提供构建下一代自主智能系统的完整技术方案。
539 4
|
3月前
|
机器学习/深度学习 分布式计算 Java
Java与图神经网络:构建企业级知识图谱与智能推理系统
图神经网络(GNN)作为处理非欧几里得数据的前沿技术,正成为企业知识管理和智能推理的核心引擎。本文深入探讨如何在Java生态中构建基于GNN的知识图谱系统,涵盖从图数据建模、GNN模型集成、分布式图计算到实时推理的全流程。通过具体的代码实现和架构设计,展示如何将先进的图神经网络技术融入传统Java企业应用,为构建下一代智能决策系统提供完整解决方案。
397 0
|
4月前
|
JavaScript Java 大数据
基于JavaWeb的销售管理系统设计系统
本系统基于Java、MySQL、Spring Boot与Vue.js技术,构建高效、可扩展的销售管理平台,实现客户、订单、数据可视化等全流程自动化管理,提升企业运营效率与决策能力。
|
4月前
|
IDE 安全 Java
Lombok 在企业级 Java 项目中的隐性成本:便利背后的取舍之道
Lombok虽能简化Java代码,但其“魔法”特性易破坏封装、影响可维护性,隐藏调试难题,且与JPA等框架存在兼容风险。企业级项目应优先考虑IDE生成、Java Records或MapStruct等更透明、稳健的替代方案,平衡开发效率与系统长期稳定性。
215 1
|
4月前
|
存储 小程序 Java
热门小程序源码合集:微信抖音小程序源码支持PHP/Java/uni-app完整项目实践指南
小程序已成为企业获客与开发者创业的重要载体。本文详解PHP、Java、uni-app三大技术栈在电商、工具、服务类小程序中的源码应用,提供从开发到部署的全流程指南,并分享选型避坑与商业化落地策略,助力开发者高效构建稳定可扩展项目。
java中获取当前系统日期
java中获取当前系统日期