前情提要
之前已经搭好的springMVC+myBatis项目骨架,详情请看–>传送门。
获取bootstrap
方法一
使用 Bootstrap 中文网提供的免费 CDN 加速服务(同时支持 http 和 https 协议)
将下面的代码copy到自己的JSP页面中即可。
<link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css"><link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap-theme.min.css"><script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script><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,如图:
<%@ 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>Document</title> <link rel="stylesheet" href="<%=basePath %>resources/css/bootstrap/bootstrap.css"></head><body> <script src="<%=basePath %>resources/js/bootstrap/jquery-1.11.3.min.js"></script> <script src="<%=basePath %>resources/js/bootstrap/bootstrap.js"></script></body></html>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
在webapp目录下新建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: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">×</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> <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>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
$("#btn_login").click(function(){ var loginObj = new Object(); loginObj.accountNo= $("#inputAccount").val(); loginObj.pwd= $("#inputPassword").val(); var loginJson = JSON.stringify(loginObj); $.post('main/validateLogin.do', {"loginObj":loginJson}, function(e){ e=JSON.parse(e); 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){ $("#loginForm").submit(); } });});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
#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
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); model.setViewName("main"); return model; } /** * 登陆表单校验 * @param request * @param response */ @RequestMapping("/validateLogin") public void login(HttpServletRequest request, HttpServletResponse response){ String loginObj = RequestUtils.getString(request, "loginObj"); 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); }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
用到的两个工具方法,也记录一下。
- 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; }
/** * 发送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(); if(content == null){ content = ""; } out.write(content); } catch (IOException e) { log.error(e.getLocalizedMessage(), e); } finally { if (out != null){ out.close(); } } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
还有根据账号去查询用户是否存在,因为账号不是表的主键,所以自动生成的mapping.xml中没有相应的查询SQL语句,需要我们手动给它加上:
<select id="selectByAcccountNo" resultMap="BaseResultMap" parameterType="java.lang.String" > 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_seqINCREMENT BY 1START WITH 1NOMAXVALUENOCYCLENOCACHE;--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所在地';
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100