基于bootstrap的web登陆实例

前情提要 之前已经搭好的springMVC+myBatis项目骨架,详情请看–>传送门

获取bootstrap

方法一

使用 Bootstrap 中文网提供的免费 CDN 加速服务(同时支持 http 和 https 协议)  将下面的代码copy到自己的JSP页面中即可。

<!-- 新 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">

<!-- 可选的Bootstrap主题文件(一般不用引入) -->
<link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">

<!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
<script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>

<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>

好处,不需要下载bootstrap的JS和CSS文件,只要有网络就能引用到。

方法二

  • 到官网下载编译好的bootstrap–>传送门,它是编译并压缩后的 CSS、JavaScript 和字体文件。不包含文档和源码文件。当然你也可以下载源码版,源码包含编译好的文件。
  • 另外bootstrap是完全基于jQuery开发的,要使用bootstrap,必须依赖jQuery。所以再把jQuery下载下来。
  • 把下载下来的文件copy到项目里面,如图: 

这样我们就能使用bootstrap给我提供的前端框架开发漂亮的web应用了。


添加JSP页面

在此之前,为了避免重复劳动,我们先创建一个JSP模板。  点击window–>搜索JSP–>templent–>new, Name随便输入,Context选择New JSP,如图: 

  • 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><!--Bootstrap 使用到的某些 HTML 元素和 CSS 属性需要将页面设置为 HTML5 文档类型-->
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=Edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
  <title>Document</title>

  <link rel="stylesheet" href="<%=basePath %>resources/css/bootstrap/bootstrap.css">
</head>
<body>

  <!--bootstrap需要依赖jQuery,所以必须在他之前先引入jQuery-->
  <script src="<%=basePath %>resources/js/bootstrap/jquery-1.11.3.min.js"></script>
  <script src="<%=basePath %>resources/js/bootstrap/bootstrap.js"></script>
</body>
</html>

在webapp目录下新建login.jsp

  • 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>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>login</title>

    <link rel="stylesheet" href="<%=basePath %>resources/css/bootstrap/bootstrap.css">
    <link rel="stylesheet" href="<%=basePath %>resources/css/myCss/login.css">
</head>
<body>
    <!--引入头部JSP-->
    <jsp:include page="head.jsp" ></jsp:include>
    <!--使用模态框的方式模拟一个登陆框-->
    <div class="modal show" id="loginModal">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close">&times;</button>
                    <h1 class="text-center text-primary">登录</h1>
                </div>
                <div class="modal-body">
                    <form class="form col-md-12 center-block" id="loginForm" action="main/successLogin.do" method="post">
                        <div class="form-group-lg"  id="accountDiv">
                            <label class="sr-only" for="inputAccount">账号</label>
                            <div class="input-group">
                                <div class="input-group-addon"><span class="glyphicon glyphicon-user" aria-hidden="true"></span></div>
                                <input class="form-control" id="inputAccount" name="accountNo" type="text" placeholder="账号" required autofocus>
                            </div>
                            <div class="hidden text-center" id="accountMsg"><span class="glyphicon glyphicon-exclamation-sign"></span>用户名不存在</div>
                        </div>
                        <br>
                        <div class="form-group-lg" id="pwdDiv">
                            <label class="sr-only" for="inputPassword">密码</label>
                            <div class="input-group">
                                <div class="input-group-addon"><span class="glyphicon glyphicon-lock"></span></div>
                                <input class="form-control" id="inputPassword" name="pwd" type="password" placeholder="密码" required>
                                <div class="input-group-addon"><span class="glyphicon glyphicon-eye-open"></span></div>
                            </div>
                            <div class="hidden text-center" id="pwdMsg"><span class="glyphicon glyphicon-exclamation-sign"></span>用户名密码错误</div>
                        </div>
                        <div class="checkbox">
                            <label> <input type="checkbox" value="remember-me">记住我</label>
                        </div>
                        <div class="form-group">
                            <button class="btn btn-default btn-lg col-md-6" id="btn_register" type="submit">注册</button>
                            <button class="btn btn-primary btn-lg col-md-6" id="btn_login" type="button" >登录</button>
                        </div>
                    </form>
                </div>
                <div class="modal-footer">

                </div>
            </div>
        </div>
    </div>
    <!-- /container -->
    <script src="<%=basePath %>resources/js/bootstrap/jquery-1.11.3.min.js"></script>
    <script src="<%=basePath %>resources/js/bootstrap/bootstrap.js"></script>
    <script src="<%=basePath %>resources/js/myJs/login.js"></script>
</body>
</html>

  • login.js
$("#btn_login").click(function(){
    var loginObj = new Object();
    loginObj.accountNo= $("#inputAccount").val();
    loginObj.pwd= $("#inputPassword").val();
    var loginJson = JSON.stringify(loginObj); //将JSON对象转化为JSON字符    
    $.post('main/validateLogin.do',
            {"loginObj":loginJson},
            function(e){
                e=JSON.parse(e); //由JSON字符串转换为JSON对象
                if(e.accountMsg){
                    $("#accountDiv").addClass("has-error");
                    $("#accountMsg").removeClass("hidden");

                    $("#pwdDiv").removeClass("has-error");
                    $("#pwdMsg").addClass("hidden");
                }else if (e.pwdMsg){
                    $("#accountDiv").removeClass("has-error");
                    $("#accountMsg").addClass("hidden");

                    $("#pwdDiv").addClass("has-error");
                    $("#pwdMsg").removeClass("hidden");
                }else if (e.user){
                    //location.href="main/successLogin.do";
                    $("#loginForm").submit();
                }
    });
});

  • login.css
#loginModal{
  position: absolute;
  top: 50%;
  -webkit-transform: translateY(-50%);
  -moz-transform:  translateY(-50%);
  -ms-transform:  translateY(-50%);
  -o-transform:  translateY(-50%);
  transform:  translateY(-50%);
  background-color: #eee;
}

完了之后效果基本就像这样了: 


接下来就得来写后台代码了

在controller包下面新增一个LoginController.class

  • LoginController.class
package com.dimon.xwater.controller;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSONObject;
import com.dimon.xwater.dao.XUserMapper;
import com.dimon.xwater.pojo.XUser;
import com.dimon.xwater.utils.RequestUtils;
import com.dimon.xwater.utils.ResponseUtils;

@Controller
@RequestMapping("/main")
public class LoginController {
    @Resource
    private XUserMapper userDao;

    /**
     * 登陆跳转
     * @param request
     * @param model
     * @return
     */
    @RequestMapping("/successLogin")
    public ModelAndView login(HttpServletRequest request,ModelAndView model){
        String accountNo = RequestUtils.getString(request, "accountNo");
        String pwd = RequestUtils.getString(request, "pwd");
        XUser user = new XUser();
        user.setAccountNo(accountNo);
        user.setPwd(pwd);
        model.addObject("user", user);
        //跳转到/jsp/main.jsp页面
        model.setViewName("main");
        return model;
    }

    /**
     * 登陆表单校验
     * @param request
     * @param response
     */
    @RequestMapping("/validateLogin")
    public void login(HttpServletRequest request, HttpServletResponse response){
        //获取form表单数据
        String loginObj = RequestUtils.getString(request, "loginObj");
        //JSON字符串序列化成JSON对象
        JSONObject loginJosn = JSONObject.parseObject(loginObj);
        String accountNo = loginJosn.getString("accountNo");
        String pwd = loginJosn.getString("pwd");
        //根据账号查询用户名是否存在
        XUser selectUser = userDao.selectByAcccountNo(accountNo);
        JSONObject result = new JSONObject();

        if (null == selectUser){
            result.put("accountMsg", "用户名不存在");
        }else if (!pwd.equals(selectUser.getPwd())){
            result.put("pwdMsg", "用户名密码错误");
        }else {
            result.put("user",selectUser);
        }
        String resultStr = result.toJSONString();

        ResponseUtils.send(response, resultStr);
    }
}

用到的两个工具方法,也记录一下。  - RequestUtils.getString();

    /**
     * 返回字符串,删除了首尾空格,如果不存在则返回null
     * 
     * @param request
     * @param key
     * @return
     */
    public static String getString(HttpServletRequest request, String key) {
        String value = request.getParameter(key);
        if (StringUtils.isEmpty(value)) {
            return StringUtils.trimWhitespace(value);
        }
        return value;
    }
  • ResponseUtils.send();
    /**
     * 发送json格式数据到页面
     * 
     * @param response
     * @param content
     */
    public static void send(HttpServletResponse response, String content) {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html");
        PrintWriter out = null;
        try {
            out = response.getWriter();
            //若发送数据为null 则默认为""
            if(content == null){
                content = "";
            }
            out.write(content);
        }
        catch (IOException e) {
            log.error(e.getLocalizedMessage(), e);
        }
        finally {
            if (out != null){
                out.close();
            }
        }
    }

还有根据账号去查询用户是否存在,因为账号不是表的主键,所以自动生成的mapping.xml中没有相应的查询SQL语句,需要我们手动给它加上:

  <select id="selectByAcccountNo" resultMap="BaseResultMap" parameterType="java.lang.String" >
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
    -->
    select 
    <include refid="Base_Column_List" />
    from X_USER
    where ACCOUNT_NO = #{id,jdbcType=VARCHAR}
  </select>

同时再到XUserMapping.java中添加一个selectByAcccountNo接口:

XUser selectByAcccountNo(String accountNo);

这样一个登陆页面实例就算完成了,登陆验证一下:

  • 输入错误的账号或密码: 
  • 输入正确的账号和密码: 

附上数据库表结构:

--系统用户表
truncate table xuser;
drop table xuser;
create table xuser(   
xuser_id number(10),
xuser_name varchar2(32),
xuser_realName varchar2(64),
xuser_acctno varchar2(64),
xuser_pwd varchar2(64),
xuser_email varchar2(64),
xuser_mphone varchar2(11),
xuser_addrId number(10),
xuser_lastLogin timestamp,
CONSTRAINT pk_xuser PRIMARY KEY (xuser_id),
CONSTRAINT uk_xuser UNIQUE (xuser_acctno)
);

COMMENT ON TABLE xuser IS '用户表';
COMMENT ON COLUMN xuser.xuser_name IS '昵称';
COMMENT ON COLUMN xuser.xuser_realName IS '真实姓名';
COMMENT ON COLUMN xuser.xuser_acctno IS '登陆账号';
COMMENT ON COLUMN xuser.xuser_pwd IS '密码';
COMMENT ON COLUMN xuser.xuser_email IS '邮箱';
COMMENT ON COLUMN xuser.xuser_mphone IS '手机号码';
COMMENT ON COLUMN xuser.xuser_addrId IS '地址ID,外键关联地址表';
COMMENT ON COLUMN xuser.xuser_lastLogin IS '最后登陆时间';

--创建序列
drop sequence xUser_seq;
CREATE SEQUENCE xUser_seq
INCREMENT BY 1
START WITH 1
NOMAXVALUE
NOCYCLE
NOCACHE;

--ID自增长的触发器
CREATE OR REPLACE TRIGGER ins_xUser_triger
  BEFORE INSERT ON xuser
  FOR EACH ROW
  WHEN (new.xuser_id is null)
begin
  select xUser_seq.Nextval into :new.xuser_id from dual;
end;


--地址表
drop table xaddr;
create table xaddr(
xaddr_id number(10),
xaddr_prov varchar2(32),
xaddr_ctiy varchar2(32),
xaddr_dist varchar2(32),
xaddr_detail varchar2(100),
xaddr_type char,
CONSTRAINT pk_xaddr PRIMARY KEY (xaddr_id)
);

COMMENT ON TABLE xaddr IS '地址表';
COMMENT ON COLUMN xaddr.xaddr_prov IS '省';
COMMENT ON COLUMN xaddr.xaddr_ctiy IS '市';
COMMENT ON COLUMN xaddr.xaddr_dist IS '区';
COMMENT ON COLUMN xaddr.xaddr_detail IS '详细地址';
COMMENT ON COLUMN xaddr.xaddr_type IS '地址类型';


--枚举字典表
drop table xdic;
create table xdic(
xdic_id number(10),
xdic_tab varchar2(32) not null,
xdic_col varchar2(32) not null,
xdic_key char(2),
xdic_val varchar2(32),
constraint pk_xdic primary key (xdic_id)
);
COMMENT ON TABLE xdic IS '枚举字典表';
COMMENT ON COLUMN xdic.xdic_id IS '所属表';
COMMENT ON COLUMN xdic.xdic_col IS '所属字段';
COMMENT ON COLUMN xdic.xdic_key IS '字典key';
COMMENT ON COLUMN xdic.xdic_val IS '字典值';

--登陆登出记录
create table xlogin(
xlogin_id number(10),
xlogin_localip varchar2(32),
xlogin_netip varchar2(32),
xlogin_logintime timestamp,
xlogin_logouttime timestamp,
xlogin_ipaddr varchar2(32),
constraint pk_xlogin primary key (xlogin_id)
);

COMMENT ON TABLE xlogin IS '登陆记录';
COMMENT ON COLUMN xlogin.xlogin_localip IS '本地地址';
COMMENT ON COLUMN xlogin.xlogin_netip IS '网络地址';
COMMENT ON COLUMN xlogin.xlogin_logintime IS '登陆时间';
COMMENT ON COLUMN xlogin.xlogin_logouttime IS '登出时间';
COMMENT ON COLUMN xlogin.xlogin_ipaddr IS 'IP所在地';

版权声明:本文为Dimon Ho整理,请随意转载 →_→ 知识共享,共创IT文明。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏数据和云

返璞归真:如何判断一个初始化参数是否来自默认设置

? 杨廷琨(yangtingkun) 云和恩墨 CTO 高级咨询顾问,Oracle ACE 总监,ITPUB Oracle 数据库管理版版主 Oracle初...

29770
来自专栏别先生

一脸懵逼学习Hive的使用以及常用语法(Hive语法即Hql语法)

Hive官网(HQL)语法手册(英文版):https://cwiki.apache.org/confluence/display/Hive/LanguageMa...

1.6K90
来自专栏Netkiller

服务器攻防·禁止穷举邮箱密码

本文节选自《Netkiller Linux 手札》 下面是一个脚本你可以放在crontab中运行,每个一定时间运行一次。 #!/bin/bash #######...

39260
来自专栏乐沙弥的世界

从ORA-27300,ORA-27301到ORA-00064

    最近由于session数量增加,需要调整session,也就是要调整process参数。看是比较简单的一个问题,却遭遇了ORA-27300,ORA-2...

10310
来自专栏乐沙弥的世界

Oracle 数据字典和数据字典视图

是元数据的集合,从逻辑上和物理上描述了数据库及内容,存储于SYSTEM与SYSAUX表空间内的若干段。

9230
来自专栏杨建荣的学习笔记

记一次数据库重启后归档急剧增加的问题(98天)

在本地的环境中测试外部表的性能,由于空间有限,不一会儿归档的空间就爆了。然后文件貌似出现了系统级的问题,刚刚rm掉的归档日志文件。隔了几秒钟再ls,就出现了。怎...

39040
来自专栏SpringBoot 核心技术

第七章:使用QueryDSL与SpringDataJPA实现子查询

49510
来自专栏Netkiller

怎样将 MySQL 数据表导入到 Elasticsearch

本文节选自《Netkiller Database 手札》 MySQL 导入 Elasticsearch 的方法有很多,通常是使用ETL工具,但我觉得太麻烦。于是...

82550
来自专栏数据小魔方

时间&日期函数

今天要跟大家简要介绍一下excel中经常会用到的日期与时间函数! 日期与时间类的函数虽然算所有函数中最难掌握的,但是因为格式众多,形式多样,而且作为其他高级函数...

36070
来自专栏数据和云

触类旁通:那些关于 TBL$OR$IDX$PART$NUM 的诡异案例和知识

你是否留意过数据库中有一个奇怪的函数 TBL$OR$IDX$PART$NUM ,你是否留意过很多场景下都出现过它的身影?

16040

扫码关注云+社区

领取腾讯云代金券