用户模块-管理员注册功能
不管是前台程序,还是后台程序都是可以独立运行web服务程序,只是面向的用户不同而已,前台的用户更加广泛(所有需要此功能的用户)。后台的用户则是管理员,用于对整个程序平台的管理。不管是前台还是后台都需要数据库表存储各种信息,都需要界面来与用户进行互动,所以前边我们介绍了数据建模工具(PowerDesigner)和前端框架bootstrap的简单使用。
bootstrap用于界面样式的绘制,很大的方便了我们的开发工作,可是bootstrap所绘制的原型界面我们是不能拿来直接用的,需要经过修改,比如编码修改为utf-8,html页面改为jsp。
好,现在我们先把整个原型界面中的index界面导入我们的项目中,在倒入之前需要先导入原型界面样式依赖库,至于bootstrap库应该属于插件,所以应该新建一个插件文件夹,放在插件文件夹中,之后再有插件也放在其中。
再将index界面的编码转为utf-8和更改后缀为jsp。转码时应该先将界面代码中的GB18030替换为UTF-8后,再转码;
转码后,将index.html拷入项目中修改后缀为jsp,修改后缀的步骤是,先修改html的头信息为jsp的头信息,再修改后缀为jsp,这样就可以了。
好了,index界面添加好了,我们打开看看能不能正常显示。
我们发现页面可以显示,并且没有乱码,我们修改的没有问题,可是布局是乱的,这是因为我们页面中依赖bootstrap的路径出了问题,还记得刚才我们把bootstrap的库放到plugin下了嘛,所以依赖的路径需要修改。这里我们的项目中使用的所有路都是绝对路径,这里推荐使用 ServletContextListener监听器,监听服务器的启动和停止,在项目启动的时候将我们的项目路径放在application域中,这样我们就可以随时取得项目路径了。
好,我们马上来自定义一个监听器来实现于ServletContextListener,并且添加项目路径到application域中,在web.xml中加载这个自定义的监听器。
好了,application域中已经有了我们的项目路径,现在我们去页面中修改所有的依赖资源路径,将页面中所有带有herf=和src=的依赖资源的路径统统修改。
再显示看看效果。
好,这下完美了,万事开头难,index页面已经搞定了,现在此页面还不能跳转到其他页面,下面我们按照这个方法来添加用户模块的页面,并让index可以正确跳转到用户模块的页面。
添加 登录、注册 页面,修改编码为utf-8,修改后缀为jsp,修改页面中的依赖路径,并且将页面中跳转到.html的链接全部修改为.jsp。再来显示,并点击登录和注册试试。。
好了,我们把index页面到用户登录和注册的页面打通了,下面我们要把管理员注册的代码逻辑打通,让注册后可以跳转到管理员可见的main页面(控制面板)。
同样的为main.html修改编码、修改后缀,由于这个页面是不可以直接访问的,必须要经过登录和注册,所以我们要把main页面保护起来,如何保护起来呢,webapp下的页面都是可以直接访问的,而webapp下的WEB-INF文件夹下的页面都是受保护的,外界不可以直接访问,所以我们在WEB-INF下创建了一个jsps文件夹,用来保存那些我们不希望被外界直接访问的页面,并为了防止界面过多影响查看,我们为不同的模块创建不同的文件夹,比如(main页面属于manager系统,他是整个manager系统的主界面,所以main就放在manager文件夹下,manager下又有其他小模块,权限管理、业务审核、业务管理、参数管理等,同时在manager下分别创建相应的模块文件夹用于区分功能页面)。
然后我们来创建业务代码,因为管理员登录后的控制面板main页面有几个功能,所以为了简洁、清晰,我们也按照功能进行分包,分别是权限管理、业务审核、业务管理、参数管理;并在权限管理包中创建用户维护类(UserController.java)
接下来修改注册页面reg.jsp中的请求连接,应该向 permission/user/reg地址发送post请求。
运行一下看看。。
ok 完美!!!!! 管理员注册界面打通。。。。
这里我要特别提示一下:
springMVC的视图解析器InternalResourceViewResolver配置的时候一定要注意,一定一定一定要这样配置:
千万千万不要手欠的添加“.”或者把“/”去掉,不然的话就会导致返回的路径信息很奇怪《根路径+类上接收请求的路径+方法返回的路径》最终404错误。。。
好了,这个bug只是个小插曲,但是也应该要引起重视,这里记录一下,免得日后再犯同样的错误。接下来我们继续,将注册页面传过来的表单数据封装成TUser对象用于我们想数据库存储,再将封装好的TUser对象打印出来,看看是否封装正确。
好了,页面的数据已经可以传输到Controller中了,剩下的只是对数据的处理,并保存到数据库中就可以了,不过我们也不是什么数据都进行保存的,我们需要对页面的数据进行一些必要的判断,比如那些信息是必须填写的,长度不得少于xx,email格式是否正确等,这些信息的校验应该在页面将数据传输到controller之前就做好,否则都拿到服务器做的话,用户体验会很差。
form表单校验插件的使用
这里我们推荐一个jQuery的校验插件jquery-validation-1.13.1,这个校验插件使用起来很简单,添加到工程后,在页面导入jquery-validation-1.13.1/dist/jquery.validate.min.js就可以使用了,其他多余的库都可以删掉,附上jquery-validation-1.13.1的下载地址:https://download.csdn.net/download/qq_25106373/11057391。先去的需要校验的form表单,调用validate方法,并传入需要的参数,rules参数是需要校验的数据和校验规则,messages参数是数据根据校验规则显示的校验提示信息。具体使用方法请看下图。。
运行后页面已经有校验信息了,但是效果不好,我们发现页面显示校验信息后就乱了,图标是歪的,所以还需要微调一下。我们打开页面的源码查看一下。
我们发现页面填充的校验信息 将用户名的图标给挤下去了,所以要从这里入手,我们应该自定义效果。查看校验插件说明文档(demo文件夹中)查找自定义效果。
现在from表单中的每个div中添加一个空的<span>标签,专门用来显示我们的错误信息。
在校验器设置策略中自定义错误信息的显示策略,在list中取得每一项有校验错误的表单项,获取其错误信息并显示到该项的errorinfo中,并且改变状态,还要清理状态。
好了 ,这下OK了。。
接下来我们要对页面传输过来的数据进行一些处理,并保存到数据库中,完成管理员注册这个逻辑功能。
1,要对用户的密码进行加密存储,不应该明码存储,加密算法这里使用md5,也可以自定义加密算法或盐值加密都可以。
2,页面传过来的信息有限,而我们存储到数据库时却不应该让你其他数据都为空值,所以需要设定初始值。
3,操作数据库的时候记得try。。catch一下,因为我们数据库表中的登录账号应该是不可重复的,如果已存在,数据库会抛出异常,我们要利用这个异常提示用户已存在错误信息。
4,用户不存在,保存数据成功,这个时候应该将整个的用户信息保存到session域中供后续页面使用,跳转到控制面板main.jsp页面,这个时候的用户信息一般是不包括主键id的,如果想要信息中自动保护主键信息,需要修改tUserMapper.xml中的自动获取主键信息<insert id="insertSelective" useGeneratedKeys="true" keyProperty="id">。
5,用户已存在,保存失败,这个时候应该回显用户填写的数据,并转发回注册reg.jsp页面,再在页面显示用户信息。
UserController.java
package com.gome.scw.manager.controller.permission;
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.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import com.gome.scw.manager.bean.tUser;
import com.gome.scw.manager.service.UserService;
@Controller
@RequestMapping(value="/permission/user")
public class UserController {
private String managerString = "manager/";
@Autowired
UserService userService;
@RequestMapping(value="/reg")
public String reg(tUser tuser, Model model, HttpSession session){
//管理员用户注册成功后来到控制面板main.jsp
//1,用户注册
boolean flag = userService.register(tuser);
if(flag==true){
//将用户的全部信息存储到session中,用于后序页面的使用(为了让tuser中带有主键信息,
//所以需要修改tUserMapper.xml中的自动获取主键信息<insert id="insertSelective"
//useGeneratedKeys="true" keyProperty="id">)
session.setAttribute("login_user", tuser);
//注册成功,跳转到控制面板
return managerString + "main";
}
else {
//注册失败,回显信息
model.addAttribute("regError", "用户名已经被使用");
//因为tuser是从隐含模型中拿的,只要确定是pojo,系统会自动的存入隐含模型中,不需要我们手动存储
//使用的key名就是类名首字母小写,页面取值${tUser.loginacct}
return "forward:/reg.jsp";
}
}
}
UserServiceImpl.java
package com.gome.scw.manager.service.impl;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.ibatis.javassist.expr.NewArray;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.gome.scw.manager.bean.tUser;
import com.gome.scw.manager.dao.tUserMapper;
import com.gome.scw.manager.service.UserService;
@Service
public class UserServiceImpl implements UserService {
@Autowired
tUserMapper tUserMapper;
@Override
public tUser getUserById(Integer id) {
// TODO Auto-generated method stub
return tUserMapper.selectByPrimaryKey(id);
}
@Override
public boolean register(tUser tuser) {
// TODO Auto-generated method stub
//1,那到用户信息,先加密,用户密码在数据库中采用加密存储
tuser.setUserpswd(md5(tuser.getUserpswd()));
//2,数据库很多属性字段默认是非空,所以我们要将用户的其他信息设置默认值
tuser.setUsername(tuser.getLoginacct());
tuser.setCreatetime(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
//3,去数据库保存用户信息
int i = 0;
try {
i = tUserMapper.insertSelective(tuser);
} catch (Exception e) {
// TODO Auto-generated catch block
//e.printStackTrace();
return false;
}
return i==1?true:false;
}
//写一个md5加密的方法
public static String md5(String plainText) {
//定义一个字节数组
byte[] secretBytes = null;
try {
// 生成一个MD5加密计算摘要
MessageDigest md = MessageDigest.getInstance("MD5");
//对字符串进行加密
md.update(plainText.getBytes());
//获得加密后的数据
secretBytes = md.digest();
}
catch (NoSuchAlgorithmException e) {
throw new RuntimeException("没有md5这个算法!");
}
//将加密后的数据转换为16进制数字
String md5code = new BigInteger(1, secretBytes).toString(16);
// 16进制数字 // 如果生成数字未满32位,需要前面补0
for (int i = 0; i < 32 - md5code.length(); i++) {
md5code = "0" + md5code;
}
return md5code;
}
}
数据库表保存唯一账号设置
修改用户表t_user中登录账号唯一,不可重复
注册成功后跳转到控制面板,并从session域中取出用户信息,将用户名显示出来。用户信息中默认是没有主键id的,想要拿到用户的全部信息还需要设置自动获取主键id的值,需要修改tUserMapper.xml中相应的插入方法。
注册失败,回显数据,跳转到注册页面,并从隐藏域中拿到用户信息显示。。
成功注册:
注册失败: