【SSM框架项目 客户关系管理系统CRM 学习开发 Day1】首页功能、用户登录、安全退出、登录验证、完整代码

首页功能

需求分析

用户访问项目首页,首先进入登录页面。

时序&流程

首页-流程图

前端要先访问首页index.jsp再跳转到登录页面login.jsp,但所有页面资源都WEB-INF中不能直接访问,所以要在后端要做两件事,先根据用户输入跳转到首页,再根据首页请求跳转到登录页面

Controller层

IndexController

用户http://127.0.0.1:8080/crm/输入跳转到首页

@Controller
public class IndexController {
    /*
        理论上,给Controller方法分配url:http://127.0.0.1:8080/crm/
        为了简便,协议://ip:port/应用名称必须省去,用/代表应用根目录下的/
     */
    @RequestMapping("/")
    public String index(){
        //请求转发
        return "index";
    }
}

UserController

接收到settings/qx/user/toLogin.do请求,跳转到login.jsp

@Controller
public class UserController {
    /**
     * url要和controller方法处理完请求之后,响应信息返回的页面的资源目录保持一致
     */
    @RequestMapping("/settings/qx/user/toLogin.do")
    public String toLogin(){
        //请求转发到登录页面
        return "settings/qx/user/login";
    }
}

前端页面

index.jsp

在浏览器中输入settings/qx/user/toLogin.do以通过UserController访问login.jsp

<body>
	<script type="text/javascript">
		window.location.href = "settings/qx/user/toLogin.do";
	</script>
</body>

用户登录

需求分析

用户在登录页面,输入用户名和密码,点击"登录"按钮或者回车,完成用户登录的功能.

​ *用户名和密码不能为空

​ *用户名或者密码错误,用户已过期,用户状态被锁定,ip受限 都不能登录成功

​ *登录成功之后,所有业务页面显示当前用户的名称

​ *实现10天记住密码

​ *登录成功之后,跳转到业务主页面

​ *登录失败,页面不跳转,提示信息

时序&流程

用户登录

后端需要接受前端传入的请求,在数据库中查找对应的用户名和密码,并返回查询结果

笔记1:mybatis逆向工程

1)简介:根据表生成mapper层三部分代码:实体类,mapper接口,映射文件。
2)使用mybatis逆向工程:
a)创建工程:crm-mybatis-generator
b)添加插件:

<!--myBatis逆向工程插件-->
<plugin>
	<groupId>org.mybatis.generator</groupId>
	<artifactId>mybatis-generator-maven-plugin</artifactId>
	<version>1.3.2</version>
	<configuration>
	    <verbose>true</verbose>
	    <overwrite>true</overwrite>
	</configuration>
</plugin>

c)添加配置文件:
数据库连接信息
代码保存的目录
表的信息
d)运行mybatis的逆向工程,根据指定表生成java代码,保存到指定的目录中。

c)添加配置文件:
数据库连接信息
代码保存的目录
表的信息
d)运行mybatis的逆向工程,根据指定表生成java代码,保存到指定的目录中。

利用mybatis逆向工程生成tbl_user表的三部分代码:实体类,mapper接口,映射文件

Mapper层

UserMapper.java

创建查询封装好的用户名和密码的方法

User selectUserByLoginActAndPwd(Map<String,Object> map);

UserMapper.xml

编写tbl_user表查询语句,查询与用户名和密码对应的用户的所有信息

<select id="selectUserByLoginActAndPwd" parameterType="map" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List" />
    from tbl_user
    where login_act=#{loginAct} and login_pwd=#{loginPwd}
</select>

Service层

UserService.java

创建查询用户的服务

User queryUserByLoginActAndPwd(Map<String, Object> map);

UserServiceImpl.java

调用userMapper中的selectUserByLoginActAndPwd方法实现UserService接口中的queryUserByLoginActAndPwd服务

@Autowired
private UserMapper userMapper;

@Override
public User queryUserByLoginActAndPwd(Map<String, Object> map) {
    return userMapper.selectUserByLoginActAndPwd(map);
}

Controller层

UserController.java

笔记2:作用域

​ 把控制层(controller)代码中处理好的数据传递到视图层(jsp),使用作用域传递

​ pageContext:用来在同一个页面的不同标签之间传递数据。
​ request:在同一个请求过程中间传递数据。
​ session: 同一个浏览器窗口的不同请求之间传递数据。(记住密码)
​ application:所有用户共享的数据,并且长久频繁使用的数据。

笔记3:记住密码

访问:login.jsp---->后台:.html:如果上次记住密码,自动填上账号和密码;否则,不填。
如何判断上次是否记住密码?cookie
–上次登录成功,判断是否需要记住密码:如果需要记住密码,则往浏览器写cookie;否则,删除cookie。
而且cookie的值必须是该用户的loginAct和loginPwd
–下次登录时,判断该用户有没有cookie:如果有,则自动填写账号和密码;否则,不写。
而且填写的是cookie的值.
----->浏览器显示

获取cookie:
1,使用java代码获取cookie:
Cookie[] cs=request.getCookies();
for(Cookie c:cs){
if(c.getName().equals(“loginAct”)){
String loginAct=c.getValue();
}else if(c.getName().equals(“loginPwd”)){
String loginPwd=c.getValue();
}
}
2,使用EL表达式获取cookie:
${cookie.loginAct.value}
${cookie.loginPwd.value}

@RequestMapping("/settings/qx/user/login.do")
public @ResponseBody Object login(String loginAct, String loginPwd, String isRemPwd, HttpServletRequest request, HttpServletResponse response, HttpSession session) {
    //封装参数
    Map<String,Object> map = new HashMap<>();
    map.put("loginAct",loginAct);
    map.put("loginPwd",loginPwd);

    //调用service层方法,查询用户
    User user = userService.queryUserByLoginActAndPwd(map);

    //根据查询结果,生成响应信息
    ReturnObject returnObject = new ReturnObject();
    if (user == null) {
        //登录失败,用户名或者密码错误
        returnObject.setCode(Contants.RETURN_OBJECT_CODE_FAIL);
        returnObject.setMessage("用户名或者密码错误");
    }else {//进一步判断账号是否合法
        //user.getExpireTime()   //2019-10-20
        //        new Date()     //2020-09-10
        if (DateUtils.formateDateTime(new Date()).compareTo(user.getExpireTime()) > 0) {
            //登录失败,账号已过期
            returnObject.setCode(Contants.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("账号已过期");
        } else if ("0".equals(user.getLockState())) {
            //登录失败,状态被锁定
            returnObject.setCode(Contants.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("状态被锁定");
        } else if (!user.getAllowIps().contains(request.getRemoteAddr())) {
            //登录失败,ip受限
            returnObject.setCode(Contants.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("ip受限");
        } else {
            //登录成功
            returnObject.setCode(Contants.RETURN_OBJECT_CODE_SUCCESS);

            //把user加入session
            session.setAttribute(Contants.SESSION_USER, user);

            Cookie c1=new Cookie("loginAct",user.getLoginAct());
            Cookie c2=new Cookie("loginPwd",user.getLoginPwd());
            if("true".equals(isRemPwd)){
                //如果需要记住密码,则往外写cookied
                c1.setMaxAge(10*24*60*60);
                c2.setMaxAge(10*24*60*60);
            }else{
                //把没有过期cookie删除
                c1.setMaxAge(0);
                c2.setMaxAge(0);
            }
            response.addCookie(c1);
            response.addCookie(c2);
        }
    }
    return returnObject;
}

WorkbenchIndexController.java

@RequestMapping("/workbench/index.do")
public String index(){
    //跳转到业务主页面
    return "workbench/index";
}

前端页面

笔记4:同步请求VS异步请求

同步请求:浏览器窗口发出的请求,响应信息返回到浏览器窗口,所以会进行全局刷新。
异步请求:ajax发出的请求,响应信息返回到ajax的回调函数,既可以进行全局刷新,也可以进行局部刷新。

小结: 如果需要进行全局刷新,推荐使用同步请求,当然也可以使用异步请求;
如果需要进行局部刷新,只能使用异步请求;
如果既可能进行全局刷新,也可能进行局部刷新,也是只能使用异步请求。

笔记5:使用jquery获取指定元素的指定属性的值

选择器.attr(“属性名”);//用来获取那些值不是true/false的属性的值.
选择器.prop(“属性名”);//用来获取值是true/false的属性的值.例如checked,selected,readonly,disabled等。

笔记6:jquery事件函数的用法

选择器.click(function(){//给指定的元素添加事件
//js代码
});

选择器.click();//在指定的元素上模拟发生一次事件

login.jsp

//给整个浏览器窗口添加键盘按下事件
$(window).keydown(function (e) {
    //如果按的是回车键,则提交登录请求
    if(e.keyCode==13){
        $("#loginBtn").click();
    }
});

//给"登录"按钮添加单击事件
$("#loginBtn").click(function () {
    //收集参数
    var loginAct=$.trim($("#loginAct").val());
    var loginPwd=$.trim($("#loginPwd").val());
    var isRemPwd=$("#isRemPwd").prop("checked");
    //表单验证
    if (loginAct=="") {
        alert("用户名不能为空");
        return;
    }
    if (loginPwd=="") {
        alert("密码不能为空");
        return;
    }
    //显示正在验证
    // $("#msg").text("正在努力验证...");
    //发送请求
    $.ajax({
        url:'settings/qx/user/login.do',
        data:{
            loginAct:loginAct,
            loginPwd:loginPwd,
            isRemPwd:isRemPwd
        },
        type:'post',
        dataType:'json',
        success:function (data) {
            if (data.code=="1"){
                //跳转到业务主页面
                window.location.href="workbench/index.do";
            }else {
                //提示信息
                $("#msg").text(data.message);
            }
        },
        beforeSend:function () {//当ajax向后台发送请求之前,会自动执行本函数;
            //该函数的返回值能够决定ajax是否真正向后台发送请求:
            //如果该函数返回true,则ajax会真正向后台发送请求;否则,如果该函数返回false,则ajax放弃向后台发送请求。
            $("#msg").text("正在努力验证....");
            return true;
        }
    });
});

安全退出

需求

用户在任意的业务页面,点击"退出"按钮,弹出确认退出的模态窗口;用户在确认退出的模态窗口,点击"确定"按钮,完成安全退出的功能.

​ *安全退出,清空cookie,销毁session

​ *退出完成之后,跳转到首页

时序&流程

安全退出

Controller层

UserController

@RequestMapping("/settings/qx/user/logout.do")
public String logout(HttpServletResponse response, HttpSession session){
    //清空cookie
    Cookie c1=new Cookie("loginAct","1");
    c1.setMaxAge(0);
    response.addCookie(c1);
    Cookie c2=new Cookie("loginPwd","1");
    c2.setMaxAge(0);
    response.addCookie(c2);
    //销毁session
    session.invalidate();
    //跳转到首页 重定向
    return "redirect:/";
}

前端页面

index.jsp

给确定退出按钮加id选择器

<button type="button" class="btn btn-primary" data-dismiss="modal" id="logoutBtn">确定</button>
//给“确定”按钮添加单击事件
$("#logoutBtn").click(function () {
//发送同步请求
window.location.href="settings/qx/user/logout.do";
});

登录验证

笔记7:过滤器

1)过滤器:
a)implements Filter{
–init
–doFilter
–destroy
}
b)配置过滤器:web.xml
2)拦截器:
a)提供拦截器类:implements HandlerInterceptor{
–pre
–post
–after
}
b)配置拦截器:springmvc.xml

LoginInterceptor.java

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        //如果用户没有登录成功,则跳转到登录页面
        HttpSession session=httpServletRequest.getSession();
        User user=(User) session.getAttribute(Contants.SESSION_USER);
        if(user==null){
            httpServletResponse.sendRedirect(httpServletRequest.getContextPath());//重定向时,url必须加项目的名称
            return false;
        }
        return true;
    }

applicationContext-mvc.xml

<mvc:interceptors>
    <mvc:interceptor>
        <!--配置拦截的请求-->
        <mvc:mapping path="/settings/**"/>
        <mvc:mapping path="/workbench/**"/>
        <!--配置排除拦截的请求(优先级高)-->
        <mvc:exclude-mapping path="/settings/qx/user/toLogin.do"/>
        <mvc:exclude-mapping path="/settings/qx/user/login.do"/>
        <!--拦截器类-->
        <bean class="com.yyp.crm.settings.web.interceptor.LoginInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
一、简介 通过这个课程带大家从零开发一款功能全面的后台管理系统,包括项目搭建、功能实现到最后的Linux系统部署全过程。本课程使用SpringMVC + Spring + Mybatis作为主体框架,使用AdminLTE作为前端框架,使用主流关系型数据库Mysql作为存储数据库,使用非关系型数据库Redis作为缓存数据库,并集成SpringSecuriy安全框架做权限的动态管理,集成Swagger2自动生成接口文档,集成Druid连接池进行SQL性能监控,集成ActiveMQ消息中间件进行异步解耦,提高性能。最后使用linux系统进行服务部署,并搭建nginx反向代理服务器提高网站性能。 二、学习目标 通过本课程的学习带大家掌握SSM框架开发流程,并熟练使用SpringSecurity做为安全框架进行权限管理,整合相关优秀的开源框架进行功能开发。还在项目中带大家学习前端相关的Jquery、Bootstrap等知识。课程结束之后希望大家能做到独立进行开发项目的目的,增强解决问题的能力,具备功能落地实现的能力。 三、课程涉及知识点 SpringMVC源码分析Mybatis源码分析通用MapperMysql数据库Redis缓存实现ActiveMQ消息中间件SpringSecurity鉴权Swagger2接口文档生成自定义注解AOP切面编程自定义过滤器Logback日志整合Druid性能监控Linux系统Nginx反向代理Ajax异步请求技术Jquery基本使用AdminLTE前端框架Chart图表-线状图和饼状图百度地图定位城市BootStrap前端框架BootStrap-Table插件BootStrap-Treeview插件Markdown编辑器403、404、500错误页面配置数据库事务消息提示插件toastr.js图片上传插件bootstrap fileinput数字滚动效果pv/uv流量统计...四、课程部分内容截图如下 1、首页 2、菜单管理 3、图床管理 4、图标管理 5、留言反馈管理 6、druid监控 7、登录日志

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

温柔说给风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值