IntelliJ IDEA14.0.3+Maven+SpringMVC+Spring+Hibernate光速构建Java权限管理系统(三)
注册登录
--利用简单的编写注册登录系统来打通从前端到后台的数据传输路径。
一、建立数据库、基本表
基本环境:mysql5,7、Navicat for MySQL11.0.9企业版。
我们在本地mysql服务器中新建名为work的数据库,然后建立名为user的表,详细如下图所示:
二、hibernate与dao
hibernate是比较成熟的重量级ORM框架,利用它可以大大简化我们对数据库的操作(基本的操作数据库方式就是增删改查)。
在大型项目中我们通常会有个base包来存放最基础的公共类,其中的dao层存放可复用性强的数据库操作,比如对单个实体的增删改查,批量保存,批量删除,分页查询等等。这样,其他功能包中的dao层可以从base包中的dao层进行继承,从而使我们在编程时可以花更多时间在业务逻辑上。
为了照顾编程的规范性,base/dao层中先编写接口,再编写实现类。
这里先给出IBaseDao.java和BaseDaoImpl.java两个文件的代码:
IBaseDao.java
package com.whut.work.base.dao;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import org.hibernate.HibernateException;
import com.whut.work.base.model.Page;
import com.whut.work.base.vo.Parameter;
public interface IBaseDao<T> {
//单个CRUD
public void save(final T entity) throws Exception;
public void delete(final T entity) throws Exception;
public void deleteWithHql(final String hql) throws Exception;
public void update(final T entity) throws Exception;
public T getOne(final int id) throws Exception;
//批处理
public int batchSave(final List<T> list) throws Exception;
public void deleteAll(final Collection entities) throws Exception;
//createQuery(Query)
public T findOne(final String hql) throws Exception;
public T findOne(final String hql, final Parameter parameter) throws Exception;
//list查询
public List<T> findList(final String hql) throws Exception;
public List<T> findList(final String hql, final Parameter parameter) throws Exception;
//分页查询
public Page<T> findPage(final int currentPage, final int pageSize, final String queryHql, final String countHql, final Object[] values)
throws HibernateException,SQLException;
public Page<T> findPage(final int currentPage, final int pageSize, final String queryHql, final String countHql)
throws HibernateException,SQLException;
//查询满足条件的记录数
public long findCount(final String hql);
public long findCount(final String hql, final Object[] values);
}
BaseDaoImpl.java package com.whut.work.base.dao.Impl;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import javax.annotation.Resource;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import com.whut.work.base.dao.IBaseDao;
import com.whut.work.base.model.Page;
import com.whut.work.base.vo.Parameter;
public class BaseDaoImpl<T> implements IBaseDao<T> {
private int BATCH_MAX_ROW = 5;
private SessionFactory sessionFactory;
private Class<T> entityClass;
//construct methods
public BaseDaoImpl(){
}
public BaseDaoImpl(Class<T> entityClass){
this.entityClass = entityClass;
}
@Override
public void save(T entity) throws Exception {
Session session = this.getSession();
session.beginTransaction();
session.save(entity);
session.getTransaction().commit();
}
@Override
public int batchSave(List<T> list) throws Exception {
Session session = this.getSession();
session.beginTransaction();
for (int i = 0; i < list.size(); ++i) {
session.save(list.get(i));
if (i % BATCH_MAX_ROW == 0) {
session.flush();
session.clear();
}
}
session.flush();
session.clear();
session.getTransaction().commit();
return list.size();
}
@Override
public void deleteAll(Collection entities) throws Exception {
Session session = this.getSession();
session.beginTransaction();
for (Object entity : entities) {
session.delete(entity);
}
session.getTransaction().commit();
}
@Override
public void delete(T entity) throws Exception {
Session session = this.getSession();
session.beginTransaction();
session.delete(entity);
session.getTransaction().commit();
}
@Override
public void deleteWithHql(String hql) throws Exception {
Session session = this.getSession();
session.beginTransaction();
Query query = session.createQuery(hql);
query.executeUpdate();
session.getTransaction().commit();
}
@Override
public void update(T entity) throws Exception {
Session session = this.getSession();
session.beginTransaction();
session.update(entity);
session.getTransaction().commit();
}
@SuppressWarnings("unchecked")
@Override
public T getOne(int id) throws Exception {
Session session = this.getSession();
session.beginTransaction();
Object returnObject = session.get(entityClass, id);
session.getTransaction().commit();
return (T) returnObject;
}
@Override
public T findOne(String hql) throws Exception {
return findOne(hql,null);
}
@SuppressWarnings("unchecked")
@Override
public T findOne(final String hql, final Parameter parameter) throws Exception {
Session session = this.getSession();
session.beginTransaction();
Query query = session.createQuery(hql);
setParameter(query, parameter);
Object returnObject = query.setMaxResults(1).uniqueResult();
session.getTransaction().commit();
return (T) returnObject;
}
@Override
public List<T> findList(final String hql) throws Exception {
return findList(hql, null);
}
@SuppressWarnings("unchecked")
@Override
public List<T> findList(final String hql, final Parameter parameter) throws Exception {
Session session = this.getSession();
session.beginTransaction();
Query query = session.createQuery(hql);
setParameter(query, parameter);
List<T> returnList = query.list();
session.getTransaction().commit();
return returnList;
}
/**
*
* @param query
* @param parameter
* set sql parameters
*/
private void setParameter(Query query, Parameter parameter) {
if (parameter != null) {
Set<String> keySet = parameter.keySet();
for (String string : keySet) {
Object value = parameter.get(string);
if (value instanceof Collection<?>) {
query.setParameterList(string, (Collection<?>) value);
} else if (value instanceof Object[]) {
query.setParameterList(string, (Object[]) value);
} else {
query.setParameter(string, value);
}
}
}
}
public SessionFactory getSessionFactory() {
return sessionFactory;
}
@Resource(name="sessionFactory")//在applicationContext.xml文件中有配置
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
/**
* @return session
*/
private Session getSession() {
return sessionFactory.getCurrentSession();
}
@SuppressWarnings("unchecked")
@Override
public Page<T> findPage(int currentPage, int pageSize, String queryHql, String countHql, Object[] values)
throws HibernateException, SQLException {
Session session = this.getSession();
session.beginTransaction();
Query query = session.createQuery(queryHql);
if (values != null) {
for (int i = 0; i < values.length; i++) {
query.setParameter(i, values[i]);
}
}
// 如果pageSize<=0则查询全部,用于打印导出等...
if (pageSize > 0) {
query.setFirstResult(pageSize * (currentPage - 1));//设置要查询的结果集的开始索引位置
query.setMaxResults(pageSize);//设置要查询的结果集的数量
}
List<T> returnList = query.list();
session.getTransaction().commit();
long totalRecords = findCount(countHql, values);
return new Page<T>(returnList, totalRecords, currentPage, pageSize);
}
@Override
public Page<T> findPage(int currentPage, int pageSize, String queryHql, String countHql)
throws HibernateException, SQLException {
return findPage(currentPage, pageSize, queryHql, countHql, null);
}
@Override
public long findCount(String hql) {
return findCount(hql, null);
}
@Override
public long findCount(String hql, Object[] values) {
Session session = this.getSession();
session.beginTransaction();
Query query = session.createQuery(hql);
if (values != null) {
for (int i = 0; i < values.length; i++) {
query.setParameter(i, values[i]);
}
}
Long returnLong = (Long) query.setMaxResults(1).uniqueResult();
session.getTransaction().commit();
return returnLong;
}
}
通过以上代码我们可以发现,在分页查询以及设置hql参数的操作中还需要用到两个类:Page.java和Parameter.java。 Page.java
package com.whut.work.base.model;
import java.util.List;
public class Page<T> {
private int current = 1;
private int total = 0;
private long records = 0;
private int size = 10;
private String orderBy = "";
private String order = "";
public String getOrderBy() {
return orderBy;
}
public void setOrderBy(String orderBy) {
this.orderBy = orderBy;
}
public String getOrder() {
return order;
}
public void setOrder(String order) {
this.order = order;
}
private List<T> list = null;
public Page() {
}
public Page(int currentPage, int pageSize){
current=currentPage;
size=pageSize;
}
public Page(List<T> list, int current, int size) {
this.current = current;
this.size = size;
this.list = list;
}
public Page(List<T> list, long records, int current, int size, String orderBy, String order) {
this.list = list;
this.current = current;
this.records = records;
this.size = size;
this.orderBy = orderBy;
this.order = order;
this.total = records == 0 ? 1 : (int) ((records - 1) / size + 1);//分几页的计算方法
if (this.current > this.total) {
this.current = this.total;
}
if (current < 1) {
this.current = 1;
}
}
public Page(List<T> list, long records, int current, int size) {
this(list, records, current, size, null, null);
}
public int getCurrent() {
return current;
}
public void setCurrent(int current) {
this.current = current;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public int getTotal() {
return total;
}
public void setTotal(int l) {
this.total = l;
}
public long getRecords() {
return records;
}
public void setRecords(long records) {
this.records = records;
}
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
@Override
public String toString() {
return "Page{" +
"current=" + current +
", size=" + size +
", list=" + list +
'}';
}
}
Parameter.java package com.whut.work.base.vo;
import java.util.HashMap;
/**
* 查询参数类
*/
public class Parameter extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;
/**
* 构造类,例:new Parameter(id, parentIds)
*
* @param values 参数值
*/
public Parameter(Object... values) {
if (values != null) {
for (int i = 0; i < values.length; i++) {
put("p" + i, values[i]);
}
}
}
/**
* 构造类,例:new Parameter(new Object[][]{{"id", id}, {"parentIds", parentIds}})
*
* @param parameters 参数二维数组
*/
public Parameter(Object[][] parameters) {
if (parameters != null) {
for (Object[] os : parameters) {
if (os.length == 2) {
put((String) os[0], os[1]);
}
}
}
}
}
至此,我们先给出项目结构图,关于那个util包,以后我们遇到相应问题时再来讨论它(暂时不用建立它)。
当然,关于各种的包的命名大家完全可以根据自己喜好来进行。
三、用户实体(user包)
之前我们已经建立了数据库中的user表,现在我们来编写用户model层代码,并用注解配置。
package com.whut.work.user.model;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="user")
public class User {
@Id
@GeneratedValue
private Integer id;
private String username;
private String password;
private String tel;
private String email;
@Column(name="create_time")
private Date createTime;
@Column(name="is_delete")
private Boolean isDelete;
public Integer getId() {
return id;
}
public void setId(Integer 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 getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Boolean getIsDelete() {
return isDelete;
}
public void setIsDelete(Boolean isDelete) {
this.isDelete = isDelete;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
然后编写用户的dao层: IUserDao.java
package com.whut.work.user.dao;
import com.whut.work.base.dao.IBaseDao;
import com.whut.work.user.model.User;
public interface IUserDao extends IBaseDao<User>{
}
UserDaoImpl.java package com.whut.work.user.dao.impl;
import org.springframework.stereotype.Component;
import com.whut.work.base.dao.Impl.BaseDaoImpl;
import com.whut.work.user.dao.IUserDao;
import com.whut.work.user.model.User;
@Component
public class UserDaoImpl extends BaseDaoImpl<User> implements IUserDao {
public UserDaoImpl(){
super(User.class);
}
}
四、登录部分(login包) 我们暂时只需编写登录部分的controller层和service层。调用过程为:login下的controller接收到前台传送过来的用户登录信息,调用login下的service,接着通过user下的dao与数据库进行交互。login包中包含注册和登录功能。
ILoginService.java
package com.whut.work.login.service;
import java.util.Map;
public interface ILoginService {
//登录
public Map<String,Object> login(String username, String password) throws Exception;
//注册
public Map<String,Object> register(String username, String password, String tel, String email) throws Exception;
}
LoginServiceImpl.java package com.whut.work.login.service.impl;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.whut.work.login.service.ILoginService;
import com.whut.work.user.dao.IUserDao;
import com.whut.work.user.model.User;
@Component
public class LoginServiceImpl implements ILoginService {
@Autowired
private IUserDao userDao;
@Override
public Map<String, Object> login(String username, String password) throws Exception {
Map<String,Object> returnMap = new HashMap<String,Object>();
String hql = "from User u where u.username='"+username+"'";
User user = new User();
try {
user = userDao.findOne(hql);
} catch (Exception e) {
e.printStackTrace();
}
if(user != null){
if(user.getPassword().equals(password)){
returnMap.put("value", user);
returnMap.put("message", "登录成功");
returnMap.put("success", true);
}else{
returnMap.put("message", "密码错误");
returnMap.put("success", false);
}
}else{
returnMap.put("message", "该用户不存在!");
returnMap.put("success", false);
}
return returnMap;
}
@Override
public Map<String, Object> register(String username, String password,String tel,String email) throws Exception {
Map<String,Object> returnMap = new HashMap<String,Object>();
String hql = "from User u where u.username='"+username+"'";
User user = new User();
if(userDao.findOne(hql) != null){
returnMap.put("message", "该用户名已存在...");
returnMap.put("success", false);
return returnMap;
}else{
user.setUsername(username);
user.setPassword(password);
user.setTel(tel);
user.setEmail(email);
user.setCreateTime(new Date());
user.setIsDelete(false);
userDao.save(user);
returnMap.put("value", user);
returnMap.put("message", "注册成功");
returnMap.put("success", true);
return returnMap;
}
}
}
LoginCtrl.java package com.whut.work.login.controller;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.whut.work.base.model.Page;
import com.whut.work.login.service.ILoginService;
import com.whut.work.user.model.User;
import com.whut.work.user.service.IUserService;
@Controller
@RequestMapping("/login")
public class LoginCtrl {
@Autowired
private ILoginService loginService;
@RequestMapping(value="/login",method=RequestMethod.POST)
@ResponseBody
public Map<String,Object> login(HttpServletRequest request,String username,String password){
Map<String,Object> returnMap = new HashMap<String,Object>();
try {
Map<String,Object> map = loginService.login(username, password);
//获取user实体
Object object = map.get("value");
if(object != null){
User user = (User) object;
HttpSession session = request.getSession();
session.setAttribute("userId", user.getId());
}
returnMap.put("value", object);
returnMap.put("message", map.get("message"));
returnMap.put("success", map.get("success"));
} catch (Exception e) {
returnMap.put("message", "异常:登录失败!");
returnMap.put("success", false);
e.printStackTrace();
}
return returnMap;
}
@RequestMapping(value="/register",method=RequestMethod.POST)
@ResponseBody
public Map<String,Object> register(HttpServletRequest request,String username,String password,String tel,String email){
Map<String,Object> returnMap = new HashMap<String,Object>();
try {
Map<String,Object> map = loginService.register(username, password,tel,email);
//获取user实体
Object object = map.get("value");
if(object != null){
User user = (User) object;
HttpSession session = request.getSession();
session.setAttribute("userId", user.getId());
}
returnMap.put("value", object);
returnMap.put("message", map.get("message"));
returnMap.put("success", map.get("success"));
} catch (Exception e) {
returnMap.put("message", "异常:注册失败!");
returnMap.put("success", false);
e.printStackTrace();
}
return returnMap;
}
}
至此,项目的结构如下图所示:
关于user包下的controller、service以及vo我们以后会遇到的,这里先忽略。
五、前端页面
前端页面效果部分我就不多讲了,代码也只贴部分重点的。前端css框架为bootstrap,js框架为angularjs。
login.js
angular.module("mainapp",[])
.controller("maincontroller",function($scope){
$scope.inputUsername = "";
$scope.inputPassword = "";
//登录
$scope.login = function(){
if(checkFirst() != false){
login_ajax($scope.inputUsername,$scope.inputPassword);
}else{
alert("请将信息填写完整...");
};
};
function checkFirst(){
if($scope.inputUsername!=null && $scope.inputUsername!=""
&& $scope.inputPassword!=null && $scope.inputPassword!=""){
return true;
}else{
return false;
}
};
function login_ajax(username,password){
this.username = username;
this.password = hex_md5(password);
$.ajax({
type:"POST",
url:"/login/login",
data:{"username":this.username,"password":this.password},
contentType:"application/x-www-form-urlencoded",
dataType:"json",
success:function(data){
console.log(data);
$scope.$apply(function(){
if(data.success == true && data.message == "登录成功"){
$scope.inputUsername = "";$scope.inputPassword = "";
//alert("登录成功1!");
window.location.href = "../jsp/infojsp/info.jsp?userName="+data.value.username+
"&userId="+data.value.id;
}else if(data.success == false && data.message == "密码错误"){
$scope.inputUsername = "";$scope.inputPassword = "";
alert("密码错误!");
}else if(data.success == false && data.message == "该用户不存在!"){
$scope.inputUsername = "";$scope.inputPassword = "";
alert("该用户不存在!");
}
});
}
});
};
})
signup.js angular.module("mainapp",[])
.controller("maincontroller",function($scope){
$scope.inputUsername = "";
$scope.inputPassword = "";
$scope.inputEmail = "";
$scope.inputTel = "";
function checkFirst(){
if($scope.inputUsername!=null && $scope.inputUsername!=""
&& $scope.inputPassword!=null && $scope.inputPassword!=""
&& $scope.inputEmail!=null && $scope.inputEmail!=""
&& $scope.inputTel!=null && $scope.inputTel!=""){
return true;
}else{
return false;
}
};
//注册
$scope.register = function(){
if(checkFirst() != false){
$scope.inputPassword = hex_md5($scope.inputPassword);
$.ajax({
type:"POST",
url:"/login/register",
data:{"username":$scope.inputUsername,"password":$scope.inputPassword,"tel":$scope.inputTel,"email":$scope.inputEmail},
contentType:"application/x-www-form-urlencoded",
dataType:"json",
success:function(data){
console.log(data);
$scope.$apply(function(){
if(data.success == true && data.message == "注册成功"){
$scope.inputUsername = "";$scope.inputPassword = "";
$scope.inputEmail = "";$scope.inputTel = "";
alert("注册成功!");
window.location.href = "login.html";
}else if(data.success == false && data.message == "该用户名已存在..."){
$scope.inputUsername = "";$scope.inputPassword = "";
$scope.inputEmail = "";$scope.inputTel = "";
alert("该用户名已被注册...");
}
});
}
});
}else{
alert("请将信息填写完整...");
};
};
})
login.html <!DOCTYPE html>
<html lang="en">
<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>Bootstrap Login Form Template</title>
<!-- CSS -->
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Roboto:400,100,300,500">
<link rel="stylesheet" href="login&signup/loginassets/assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="login&signup/loginassets/assets/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="login&signup/loginassets/assets/css/form-elements.css">
<link rel="stylesheet" href="login&signup/loginassets/assets/css/style.css">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<!-- Favicon and touch icons -->
<link rel="shortcut icon" href="login&signup/loginassets/assets/ico/favicon.png">
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="login&signup/loginassets/assets/ico/apple-touch-icon-144-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="login&signup/loginassets/assets/ico/apple-touch-icon-114-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="login&signup/loginassets/assets/ico/apple-touch-icon-72-precomposed.png">
<link rel="apple-touch-icon-precomposed" href="login&signup/loginassets/assets/ico/apple-touch-icon-57-precomposed.png">
</head>
<body ng-app="mainapp">
<!-- Top content -->
<div class="top-content">
<div class="inner-bg">
<div class="container">
<div class="row">
<div class="col-sm-8 col-sm-offset-2 text">
<h1><strong>User</strong> MS</h1>
<!--<div class="description">
<p>
This is a free responsive login form made with Bootstrap.
Download it on <a href="http://azmind.com"><strong>AZMIND</strong></a>, customize and use it as you like!
</p>
</div>-->
</div>
</div>
<div class="row">
<div class="col-sm-6 col-sm-offset-3 form-box">
<div class="form-top">
<div class="form-top-left">
<h3>Login to our site</h3>
<p>Enter your username and password to log on:</p>
</div>
<div class="form-top-right">
<i class="fa fa-lock"></i>
</div>
</div>
<div class="form-bottom" ng-controller="maincontroller">
<form role="form" οnsubmit="return ;" class="login-form">
<div class="form-group">
<label class="sr-only" for="form-username">Username</label>
<input type="text" name="form-username" placeholder="Username..." class="form-username form-control" id="form-username" ng-model="inputUsername">
</div>
<div class="form-group">
<label class="sr-only" for="form-password">Password</label>
<input type="password" name="form-password" placeholder="Password..." class="form-password form-control" id="form-password" ng-model="inputPassword">
</div>
<button type="submit" ng-click="login()" class="btn">Log in!</button>
</form>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6 col-sm-offset-3 social-login">
<h3>not an account?</h3>
<span>click to <a href="./signup.html"><strong>sign up</strong></a></span>
</div>
</div>
</div>
</div>
</div>
<!-- Javascript -->
<!--<script src="login&signup/signupassets/assets/js/jquery-1.11.1.min.js"></script>-->
<script src="https://cdn.static.runoob.com/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="login&signup/loginassets/assets/bootstrap/js/bootstrap.min.js"></script>
<script src="login&signup/loginassets/assets/js/jquery.backstretch.min.js"></script>
<script src="login&signup/loginassets/assets/js/scripts.js"></script>
<script src="http://cdn.static.runoob.com/libs/angular.js/1.4.6/angular.min.js"></script>
<script src="login&signup/md5.js"></script>
<script src="login&signup/login.js"></script>
<!--[if lt IE 10]>
<script src="login&signup/loginassets/assets/js/placeholder.js"></script>
<![endif]-->
</body>
</html>
signup.html <!DOCTYPE html>
<html lang="en">
<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>Sign up UMS</title>
<!-- CSS -->
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Roboto:400,100,300,500">
<link rel="stylesheet" href="login&signup/signupassets/assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="login&signup/signupassets/assets/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="login&signup/signupassets/assets/css/form-elements.css">
<link rel="stylesheet" href="login&signup/signupassets/assets/css/style.css">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<!-- Favicon and touch icons -->
<link rel="shortcut icon" href="login&signup/signupassets/assets/ico/favicon.png">
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="login&signup/signupassets/assets/ico/apple-touch-icon-144-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="login&signup/signupassets/assets/ico/apple-touch-icon-114-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="login&signup/signupassets/assets/ico/apple-touch-icon-72-precomposed.png">
<link rel="apple-touch-icon-precomposed" href="login&signup/signupassets/assets/ico/apple-touch-icon-57-precomposed.png">
</head>
<body ng-app="mainapp">
<!-- Top content -->
<div class="top-content">
<div class="inner-bg">
<div class="container">
<div class="row">
<div class="col-sm-8 col-sm-offset-2 text">
<h1><strong>User</strong> MS</h1>
<!--<div class="description">
<p>
This is a free responsive login form made with Bootstrap.
Download it on <a href="http://azmind.com"><strong>AZMIND</strong></a>, customize and use it as you like!
</p>
</div>-->
</div>
</div>
<div class="row">
<div class="col-sm-6 col-sm-offset-3 form-box">
<div class="form-top">
<div class="form-top-left">
<h3>Singup to our site</h3>
<p>Enter your information to sign up:</p>
</div>
<div class="form-top-right">
<i class="fa fa-book"></i>
</div>
</div>
<div class="form-bottom" ng-controller="maincontroller">
<form role="form" οnsubmit="return ;" class="login-form">
<div class="form-group">
<label class="sr-only" for="form-username">Username</label>
<input type="text" name="form-username" placeholder="Username..." class="form-username form-control" id="form-username" ng-model="inputUsername">
</div>
<div class="form-group">
<label class="sr-only" for="form-password">Password</label>
<input type="password" name="form-password" placeholder="Password..." class="form-password form-control" id="form-password" ng-model="inputPassword">
</div>
<div class="form-group">
<label class="sr-only" for="form-email">Email</label>
<input type="text" name="form-email" placeholder="Email..." class="form-email form-control" id="form-email" ng-model="inputEmail">
</div>
<div class="form-group">
<label class="sr-only" for="form-tel">Tel</label>
<input type="text" name="form-tel" placeholder="Tel..." class="form-tel form-control" id="form-tel" ng-model="inputTel">
</div>
<button type="submit" ng-click="register()" class="btn">Sign up!</button>
</form>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6 col-sm-offset-3 social-login">
<h3>yet have an account?</h3>
<span>click to <a href="./login.html"><strong>log in</strong></a></span>
</div>
</div>
</div>
</div>
</div>
<!-- Javascript -->
<!--<script src="login&signup/signupassets/assets/js/jquery-1.11.1.min.js"></script>-->
<script src="https://cdn.static.runoob.com/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="login&signup/signupassets/assets/bootstrap/js/bootstrap.min.js"></script>
<script src="login&signup/signupassets/assets/js/jquery.backstretch.min.js"></script>
<script src="login&signup/signupassets/assets/js/scripts.js"></script>
<script src="http://cdn.static.runoob.com/libs/angular.js/1.4.6/angular.min.js"></script>
<script src="login&signup/md5.js"></script>
<script src="login&signup/signup.js"></script>
<!--[if lt IE 10]>
<script src="login&signup/signupassets/assets/js/placeholder.js"></script>
<![endif]-->
</body>
</html>
到这里,本文已经很长了,项目的演示就放在下一篇博客中啦。