Java Web登录Demo(SSM+Ajax)

一、前言

这一周在公司接触到了实际的项目,学到了一些比较实用的Java Web开发技术和框架技巧,公司主要运用的框架是spring、springMVC和MyBatis(SSM),前后台使用Ajax交互。经过几天的学习和实践,我有了一个想法:总结经验并应用相关的框架技术去做一个小Deme,也希望广大码友能不吝赐教,不断改进,相互提升。

二、项目简介

1、demo主要运用SSM框架完成用户的登录功能,项目集成度还是挺大的,要理解起来需要花一些时间,不过当你理解后,你就会发现SSM框是真的好用。demo功能不多,当然,登录功能也是比较简单的,我写这个项目的主要目的是展示SSM框架是如何完成功能开发、JSP前台如何与后台进行交互。如果要深入体会框架的运作,真的要多多调试!
2、demo集成了MyBatis反向生成工程(工具类和配置文件),工程在java目录下,目录名称为generator。我们可以通过反向生成工程来生成实体类和DAO层,大大提高开发效率。
3、demo运用了MVC框架模式的思想,将项目分成三层:Model业务层(Service层)、View层(JSP)、Controller层(控制器层)。将项目分层之后,模块之间的耦合度就会降低,带来的好处就是项目具有良好的扩展性和可维护性,当需要修改功能的时候不用大范围改动代码,从而提高开发效率。
4、demo的后台运用了spring的自动注入、springMVC的请求驱动、MyBatis面向接口数据库编程技术。
5、在这个demo当中,我想着重介绍一下JSP前台和后台交互的响应模式,即服务器返回给客户端的响应数据是什么结构、客户端如何处理这种数据并把结果反馈给用户。后面再详细叙述。
6、开发环境:Intellij IDEA 2017.2.6、Tomcat 7.0、JDK8
7、注意事项:项目在IDEA发布不要发布根目录下;如图下发布
这里写图片描述

三、项目运用的主要技术

1、后台框架:spring、springMVC、MyBatis。
2、前端框架:Layui。
3、使用Ajax进行数据的传输以及处理服务器返回的响应数据。

四、项目运行演示

项目功能流程:用户登录–>登录成功进入主界面–>退出登录。

1、用户登录

用户登录成功后,后台会将用户信息存放到Session当中。如果用户没有登录成功,将无法进入主界面,因为项目使用了过滤器来过滤没有登录的用户请求。当用户没有登录的时候想进入主界面,就会触发过滤器进行工作,将浏览器重定向到登录界面。
这里写图片描述

2、登录成功进入主界面

这里写图片描述
用户登录之后会显示其用户名,后台处理截图:
这里写图片描述

3、退出登录
退出登录后,后台将会清除Session存放的用户信息。

五、项目详解(叙述如何完成登录功能)

1、项目目录结构

这里写图片描述

2、登录界面JSP代码(前台)

<script language="javascript">
    //显示消息
    function showMessage(msg) {
        layer.msg(msg);
    }
    //检查输入内容
    function checkInput(operCode, operPwd) {
        if (0 == operCode.length) {
            showMessage("请输入用户名");
            $("#input_username").focus();
            return false;
        }
        if(0 == operPwd.length){
            showMessage("请输入密码");
            $("#input_password").focus();
            return ;
        }
        return true;
    }

    //请求成功后回调方法
    function onSuccess(data) {
        layer.close(index);
        //在这里对服务器返回的JSON数据进行处理,可通过 “对象名.属性名”获取对应的属性
        showMessage(data.message);
        if (200 == data.state ) {
            $(window).attr('location', '${ctx}/home');
        } else {
            $("#input_username").val("");
            $("#input_password").val("");
            $("#input_username").focus();
        }
    }

    //请求失败后回调方法
    function onError(msg) {
        showMessage(msg);
    }

    var index;
    //执行登录
    function login() {
        var username = $("#input_username").val();
        var password = $("#input_password").val();
        if (checkInput(username, password)) {
            index=layer.load(); //打开登录动画
            setTimeout(function () {
                $.ajax({
                    type: "POST",
                    url: "${ctx}/user/login",   //请求URL地址
                    dataType: "json",           //服务器返回数据类型
                    data: {username: username, password: password}, //请求参数
                    success: onSuccess, //请求成功回调方法
                    error: onError      //请求失败回调方法
                });
            },1000);

        }
    }

    $(function () {
        //监听回车键
        $('.login-box-body').bind('keypress', function (event) {
            var theEvent = event || window.event;
            var code = theEvent.keyCode || theEvent.which || theEvent.charCode;
            if (13 == code) {
                login();
            }
        });
        $("#btn_login").click(function () {
            login();
        });

        //清除输入的内容
        $("#btn_reset").click(function () {
           $("#input_username").val("");
           $("#input_password").val("");
           $("#input_username").focus();
        });
    });
</script>

3、后台处理代码

(1)Controller层

@Controller
@RequestMapping("/user")
public class UserController {

    /**
     * Session存放登录用户实体类的属性名
     */
    public static final String USER_SESSION_NAME="user";

    /**
     * 自动写入注解,要在对应实现类添加@Service注解
     */
    @Autowired
    private IUserService mUserService;

    /**
     * 用户登录方法<p></p>
     * springMVC可将HTTP请求的参数封装到对应实体参数UserEntity对象中,注意请求参数名称和实体类属性名称要相同
     * @param session
     * @param userEntity
     * @return
     */
    @RequestMapping("/login")
    @ResponseBody
    public ResultEntity login(HttpSession session,UserEntity userEntity){
        System.out.println("登录");
        System.out.println(userEntity.toString());
        ResultEntity resultEntity=mUserService.login(userEntity);
        if(200 == resultEntity.getState()){
            //登录成功,保存用户信息到Session
            session.setAttribute(USER_SESSION_NAME,resultEntity.getData());
        }
        return resultEntity;
    }



    /**
     * 模拟登录方法,不连接数据库
     * @param session
     * @param username
     * @param password
     * @return
     */
    @RequestMapping("/testLogin")   //
    @ResponseBody   //@ResponseBody标签可将方法的返回值作为响应主体返回给客户端
    public ResultEntity testLogin(HttpSession session,String username,String password){
        System.out.println("username:"+username);
        System.out.println("password:"+password);
        ResultEntity resultEntity=new ResultEntity();
        if("123".equals(username) && "123".equals(password)){
            //模拟登录成功
            session.setAttribute(USER_SESSION_NAME,"user"); //存放用户登录的信息
            resultEntity.setState(200);
            resultEntity.setMessage("登录成功");
        }else{
            resultEntity.setMessage("登录失败,用户名或密码错误");
        }
        return resultEntity;
    }
}

(2)Service层

/**
 * 用户服务接口实现类
 *
 * @author clw
 * @create 2018-01-20 10:31
 **/
@Service
public class UserSeiviceImpl implements IUserService {

    @Autowired
    private UserEntityMapper mUserEntityMapper;

    public ResultEntity login(UserEntity userEntity) {
        ResultEntity resultEntity=new ResultEntity();
        //Example类指定如何构建一个动态的where子句.
        UserEntityExample example=new UserEntityExample();
        //创建SQL语句条件对象
        UserEntityExample.Criteria criteria=example.createCriteria();
        //添加SQL语句where子句的条件:相当于 select * from tb_user where username=123 and password=123;
        criteria.andUsernameEqualTo(userEntity.getUsername());
        criteria.andPasswordEqualTo(userEntity.getPassword());
        example.or(criteria);
        //执行查询,返回结果
        List<UserEntity> list=mUserEntityMapper.selectByExample(example);
        if(list.size()>0){
            resultEntity.setState(200);
            resultEntity.setMessage("登录成功");
            resultEntity.setData(list.get(0));
        }else{
            resultEntity.setMessage("登录失败");
        }
        return resultEntity;
    }
}

4、前台处理后台返回的响应数据ResultEntity

//请求成功后回调方法
function onSuccess(data) {
    layer.close(index);
    //在这里对服务器返回的JSON数据进行处理,可通过 “对象名.属性名”获取对应的属性
    showMessage(data.message);
    if (200 == data.state ) {
        //登录成功,进入主界面
        $(window).attr('location', '${ctx}/home');
    } else {
        $("#input_username").val("");
        $("#input_password").val("");
        $("#input_username").focus();
    }
}

5、数据库表设计
这里写图片描述

项目详解到这里就结束了,不过里面的内容需要花时间好好去理解和运用!虽然简单,但比较实用!

六、JSP前台和后台交互的响应模式

1、基本概念

JSP页面常常需要通过表单或者Ajax往后台(服务器)传输用户输入的数据,并且要对服务器返回的响应数据进行处理,实际开发中主要使用Ajax进行数据的传输以及处理服务器返回的响应数据。本章主要讲JSP前台和后台交互的响应模式,即服务器返回给客户端的响应数据是什么结构、客户端如何处理这种数据并把结果反馈给用户。
以用户登录为例,客户端使用Ajax把用户输入的用户名和密码传送到服务器对应接口,然后服务器处理客户端发来的数据进行处理并且返回结,最后客户端对服务器返回的数据进行处理、反馈登录结果给用户。

2、服务器响应数据实体类设计

/**
 * 接口返回的result类(普通json响应实体)<p>
 * 一般作为响应主体( @ResponseBody)返回给浏览器客户端进行处理,客户端使用Ajax进行处理<p>
 * <p>客户使用方法</p>
 * 通过“对象名.属性名”来获得相应数据,根据数据进行处理
 */
public class ResultEntity{
    /**
     * 状态码,推荐参考http响应码进行设置,以下是HTTP常见错误状态代码<p>
     * 200:响应成功。<p>
     * 400:错误的请求。客户端发送的HTTP请求不正确。<p>
     * 404:文件不存在,在服务器上没有客户端请求访问的文档。<p>
     * 405:服务器不支持客户端的请求方式。<p>
     * 500:服务器内部错误。<p>
     */
    private int state;

    /**
     * message为接口返回的个人编的提示消息;状态信息,返回错误的时候进行设置以方便调试。
     */
    private String message;

    /**
     * 具体数据
     */
    private Object data;

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

3、接口返回的result类(普通json响应实体)的使用

这里写图片描述

如图所示,Controller层的login()方法添加了@ResponseBody注解,这个标签的作用是可将方法的返回值作为响应主体返回给客户端。当客户端拿到这个响应数据,实际上就是拿到了上面的ResultEntity实体类对象,在客户端这是一个JSON对象,可通过 “对象名.属性名”获取对应的属性(注意使用Ajax的时候要设置服务器返回类型为JSON),这个时候客户端就可以根据属性把登录结果反馈给用户。

本项目在Service层对ResultEntity对象进行了属性设置:当用户登录成功的时候,将ResultEntity对象的state属性设置为200,说明用户登录成功了,并设置提示信息,同时把从数据库查出来的用户实体类存放到ResultEntity对象内的data属性。Service层处理完毕后将ResultEntity对象返回给了客户端,客户端根据返回的ResultEntity对象的state属性判断用户是否登录成功(只有state=200的时候才表示用户登录成功)并反馈登录结果给用户。这个就是我要着重说明的JSP前台和后台交互的响应模式。

七、最后

到此,我写的登录demo就结束了。谢谢大家!
项目源码下载地址:http://download.csdn.net/download/qq_33721382/10215607

猜你喜欢

转载自blog.csdn.net/qq_33721382/article/details/79114594