SSM实战之商品信息管理系统《二》

版权声明:本文为博主原创文章,未经博主允许不得转载,追究法律责任。 https://blog.csdn.net/ITBigGod/article/details/79949511

SSM实战之商品信息管理系统《二》

1.前言

本系统属于SSM的常用功能整合使用练习。
涉及到SSM框架整合+前端框Bootstrap+Ajax校验+登录拦截器+图片文件上传+日期类型转换器+json格式传参等常用功能的使用。
上一篇点这里 完成了ssm的整合以及写了一个login.jsp页面,引入了Bootstrap和jquery。

下面开始完善登录功能。
使用ajax提交json数据,使用date日期类型转换器来完成登录功能。

2.SSM实战之登录功能完善

  1. 登录原理:我们在登录的时候,前端需要让你输入账户和密码,然后后台接收到这个数据以后,通过一层一层的传递,最后传到数据库当中,跟存储的数据进行对比。如果正确,那么你就登录成功。如果错误那么返回给你错误提示。

那么既然要跟数据库打交道了,我们就需要从底往上写。
不懂的可以参考:SSM框架下web项目运行流程

实现登录模块:

一. entity实体类:对应数据库表的字段,

生成getset方法并且写重定向tostring和重构父类。

二. Dao层接口:声明数据库操作方法

查询登录账户CheckLoginAndPwd方法
添加账号addUser方法。

三. mapper映射文件-写sql语句。

Id对应dao方法名:一个增加语句一个查询语句的sql。

四. service服务层:实现业务逻辑控制。

继续声明dao层的方法名。

五. Impl实现层:实现服务层里面的方法。

注解为service,实现接口,声明dao层对象,               
写对应方法的返回值,dao对象来调用自身的方法。

六. Controller控制层:实现业务流程控制

声明注解controller,添加映射注解@RequestMapping,
指明当前路径URL。声明实体类对象。写对应的路径下的实现方法和控制信息。

七. 写前端view视图:login.jsp文件

引用json和ajax传递登录参数。

八. 写一个日期转换的工具类。

让涉及到日期的地方有一个固定格式显示。

好了,整理好了流程,我们就开始一一实现对应的代码。
首先要保证你的项目结构跟我的一样:
缺少的话,你就自己创建对应的包名.
这里写图片描述

一. 在entity包下新建一个User.java实体类:
代码如下:

package com.aaa.entity;

import java.util.Date;

/**
 * @class_name:User
 * @param: 1.User表
 * @return: 用户实体类
 * @author:Zoutao
 * @createtime:2018年3月21日
 */

public class User {
    private int id; // id
    private String username; // 用户名
    private String password; // 密码
    private Date birthday; // 注册日期
    private int sex; // 性别
    private String address; // 地址

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    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;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public int getSex() {
        return sex;
    }

    public void setSex(int sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", username=" + username + ", password=" + password + ", birthday=" + birthday
                + ", sex=" + sex + ", address=" + address + "]";
    }
}

二. Dao层接口:
在mapper包下新建一个UserMapper.java接口类:
代码如下:

package com.aaa.mapper;

import org.apache.ibatis.annotations.Param;
import com.aaa.entity.User;

/**
 * @class_name:UserMapper
 * @param: 2.dao层接口
 * @return: 数据持久化
 * @author:Zoutao
 * @createtime:2018年3月21日
 */
public interface UserMapper {

    // 查询登录账户-用户密码为参数
    public User CheckLoginAndPwd(@Param("username") String name, @Param("password") String pwd);

    // 注册用户
    public void addUser(User user);
}

三. 在mapper包下新建一个UserMapper.xml:
代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!-- 1.指定映射的对象是usermapper类 -->
<mapper namespace="com.aaa.mapper.UserMapper">

    <!-- 查询,写定义的方法对应的sql操作 -->
    <select id="CheckLoginAndPwd" resultType="user" parameterType="user">
        select*from user where username=#{username} and password=#{password}
    </select>
    <!-- 增加,性别以数字替代1=男 0=女 -->
    <insert id="addUser" parameterType="user">
        insert into user
        values(default,#{username},#{password},#{birthday},1,#{address})
    </insert>

</mapper>

四. 在biz包下新建一个UserBiz.java接口类:
代码如下:

package com.aaa.biz;

import com.aaa.entity.User;

/**
 * @class_name:UserBiz
 * @param: 4.service层接口
 * @return: 业务逻辑层
 * @author:Zoutao
 * @createtime:2018年3月21日
 */

public interface UserBiz {
    // 登录查询
    public User CheckLoginAndPwd(String name, String pwd);

    // 注册用户
    public void addUser(User user);
}

五. 在com.aaa.biz.impl包下新建一个UserBizImpl.java实现类类:
代码如下:

package com.aaa.biz.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.aaa.biz.UserBiz;
import com.aaa.entity.User;
import com.aaa.mapper.UserMapper;

/**
 * @class_name:UserBizImpl
 * @param: 5.impl层实现接口
 * @return: 实现service接口
 * @author:Zoutao
 * @createtime:2018年3月21日
 */

@Service
public class UserBizImpl implements UserBiz {
    @Autowired
    private UserMapper userMapper;

    @Override
    public User CheckLoginAndPwd(String name, String pwd) {
        // TODO Auto-generated method stub
        return userMapper.CheckLoginAndPwd(name, pwd);
    }

    @Override
    public void addUser(User user) {
        // TODO Auto-generated method stub
        userMapper.addUser(user);
    }
}

六.在controller包下新建一个UserController.java控制类:
代码如下:

package com.aaa.controller;

import java.util.List;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.aaa.biz.UserBiz;
import com.aaa.entity.Items;
import com.aaa.entity.User;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

/**
 * @class_name:UserController
 * @param:6.控制层controller
 * @return: 逻辑控制层
 * @author:Zoutao
 * @createtime:2018年3月21日
 */

// 设置默认先映射到("/user")路径下
@Controller
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserBiz userBiz;

    // 设置映射路径和以json格式传送参数
    @RequestMapping(value = "/checkLogin", produces = { "application/json;charset=UTF-8" })
    public @ResponseBody User checkLogin(@RequestBody User user, Model model, HttpSession session) {
        User user1 = userBiz.CheckLoginAndPwd(user.getUsername(), user.getPassword());
        // 登录以后添加到session中
        session.setAttribute("user1", user1);
        return user1;
    }

     @RequestMapping("/queryItems") 
     public String queryItems(Model model) {
     System.out.println("欢迎登录!");  
     return "showItems"; 
     }
}

七.在WebRoot文件夹下的Login.jsp中添加登录功能。
代码如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
            + path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>登录页-qxb</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="登录,ssm练习,web项目">
<meta http-equiv="description" content="This is login page">

<!-- 引入css和js -->
<link rel="stylesheet" href="css/bootstrap.min.css" />
<link rel="stylesheet" href="css/bootstrap-datetimepicker.min.css" />
<script type="text/javascript" src="js/jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="js/bootstrap.min.js"></script>
<script type="text/javascript" src="js/bootstrap-datetimepicker.min.js"></script>
<script type="text/javascript"
    src="js/bootstrap-datetimepicker.zh-CN.js"></script>
</head>

<!-- ajax提交方式 -->
<script type="text/javascript">
    /* Js控制通过#myModal的状态:*/
    $("#myModal").modal({
        keyboard : false,
        backdrop : false
    });

    /* Js控制注册日期的状态:*/
    $(function() {

        $(".form_datetime").datetimepicker({
            format : "yyyy-mm-dd hh:ii",
            autoclose : true,
            todayBtn : true,
            todayHighlight : true,
            showMeridian : true,
            pickerPosition : "bottom-left",
            language : 'zh-CN', //中文,需要引用zh-CN.js包
            startView : 2, //月视图
            minView : 2
        //日期时间选择器所能够提供的最精确的时间选择视图
        });

        /* 以json的格式提交登录传参 */
        $("#lo")
                .click(
                        function() {
                            $
                                    .ajax({
                                        type : 'post',
                                        //提交路径
                                        url : '${pageContext.request.contextPath}/user/checkLogin.action',
                                        //声明为json格式
                                        contentType : 'application/json;charset=utf-8',
                                        //转为json格式
                                        data : JSON.stringify({
                                            "username" : $("#loginusername")
                                                    .val(),
                                            "password" : $("#loginpassword")
                                                    .val()
                                        }),
                                        //点击登录以后拿到数据
                                        success : function(data) {
                                            //判断
                                            if (data == "" || data == null) {
                                                $("#message").html("用户名或密码错误!");
                                            } else {
                                                //正常跳转--已修改
                                                window.location.href = "${pageContext.request.contextPath}/user/queryItems.action";
                                            }
                                        }
                                    });
                        });
    });
</script>

<style>
#login {
    width: 450px;
    height: 100px;
    margin: 50px auto;
}
</style>

<body>
    <div class="container">
        <div id="login">
            <!-- 登录模块,以json提交from就可以不写action -->
            <form class="form-horizontal" role="form">
                <div class="form-group">
                    <label for="inputEmail3" class="col-sm-2 control-label">用户名:</label>
                    <div class="col-sm-10">
                        <input type="text" class="form-control" id="loginusername"
                            name="username" placeholder="请输入用户名" required autofocus>
                    </div>
                </div>
                <div class="form-group">
                    <label for="inputPassword3" class="col-sm-2 control-label">密&nbsp;&nbsp;&nbsp;码:</label>
                    <div class="col-sm-10">
                        <input type="password" class="form-control" id="loginpassword"
                            name="password" placeholder="请输入密码" required> <label
                            class="control-label" for="inputSuccess1" style="color: red;"
                            id="message"></label>
                    </div>
                </div>
                <!-- 登录注册按钮 -->
                <div class="form-group">
                    <div class="col-sm-offset-2 col-sm-10">
                        <button type="button" class="btn btn-info" id="lo">登录</button>
                        <button type="button" class="btn btn-danger" data-toggle="modal"
                            data-target="#myModal">注册</button>
                    </div>
                </div>
            </form>
        </div>
    </div>                              
</body>
</html>

login.jsp中用到的技术点相关说明:
可以不看跳过。

登录模块,以json提交from就可以不写action 
其中:required autofocus分别表示:

Required:html5属性,表示required 属性规定必需在提交之前填写输入字段。如果使用该属性,则字段是必填(或必选)的。

Autofocus:html5属性,表示当设置该属性后,它规定在页面加载后文本区域自动获得焦点。

Bootstrap中的data-target和data-toggle:
data-toggle:以什么事件触发,如modal,popover,tooltips等; 

data-target:事件的目标;
HTML5允许开发者自由为其标签添加属性,这种自定义属性一般用“data-”开头。
data-target指事件的目标,

<button type="button" class="btn btn-danger" data-toggle="modal"
data-target="#myModal">注册</button>
这段代码的意思就是指将#myModal这个DOM元素的内容以模态框(modal)的形式展示。

tabindex="-1"
tabindex 属性规定元素的 tab 键控制次序(当 tab 键用于导航时)。
若把tabIndex属性设为一个负值(如tabIndex="-1"),那么这个链接将被排除在TAB键的序列之外。   如果最初选择了[Tab]键,带这个输入栏的网页会将光标移动到firstName栏。  

如果一个元素同时有aria-labelledby和aria-label,读屏软件会优先读出aria-labelledby的内容

<input type=”text” aria-labelledby=”用户名”/>
此时,当焦点落到该输入框时,读屏软件就会读出aria-label里的内容,即“用户名”。
当想要的标签文本已在其他元素中存在时,可以使用aria-labelledby,并将其值为所有读取的元素的id。如下:
当ul获取到焦点时,屏幕阅读器是会读:“选择用户名”

aria-hidden="true"
为了避免 屏幕识读设备抓取非故意的和可能产生混淆的输出内容。为这些图标设置了 aria-hidden="true" 属性,这样就表示图标有可访问性。

注册以表单提交,提交到注册的url下。

Js控制通过#myModal的状态:
keyboard : false, 设置键盘关闭模态框 (当设置为true时,按下 esc 键时关闭模态框,设置为 false 时则按键无效。)

backdrop : false:一个对话框背景元素. 另外 static(false情况) 背景下, 点击对话框外的区域不会关闭对话框。为true时,显示对话框的遮蔽背景,鼠标点击背景即可关闭对话框。                                 
为false时,无背景。

到了这里,我们的登录模块的流程就完成了,但是当输入正确的账户密码时候,我们是不是应该跳转到某个界面或者是有什么反应?

所以我们在登录的ajax提交方式下写得是:
以id的名称来提交触发
url:’${pageContext.request.contextPath}/user/checkLogin.action’,
提交到/user/checkLogin下,转到控制层:
然后后面的判断,如果登录账户正确以后,跳转到:showItems.jsp

八.在WEB-INF文件夹下新建一个jsp文件夹,在建立一个showItems.jsp页面,来显示登录以后的显示页面。
代码如下:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">

    <title>欢迎页面</title>

  </head>

  <body>
    <div class="container">
        <!-- 标题 -->
        <div class="row">
            <div class="col-md-7">
                <h2>SSM的CRUD+分页+拦截器+日期转换+</h2>
                <span>柒晓白</span>
            </div>
        </div>
    </div>      
  </body>
</html>

最后右键运行项目:

输入账户密码:
admin+admin

登录成功跳转如图:

这里写图片描述

输入错误账户提示如图:
这里写图片描述

运行没有报错也就表示SSM登录模块成功。
报错的话,请评论贴出错误信息。

下一篇将完善登录以后的商品显示模块。


You got a dream, you gotta protect it.
如果你有梦想的话,就要去捍卫它 。 ——《当幸福来敲门》

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页