用户注册
- 需求分析
- 步骤实现
- 创建自定义异常
- 创建转换器Conventer
需求分析
需求描述
查看注册界面
用户可以填写信息(账号,密码,email,姓名,性别,出生日期)完成注册,注册后需要对账号进行邮箱激活,激活后可以使用该账号进行登录。
步骤实现
- 在entity包下新建实体类User映射数据库的user数据表用于实体封装,在dao包和service包下新建UserDao接口和UserService接口,分别在其impl包下新建UserDaoImpl和UserServiceImpl实现类。
- 进入注册界面
①修改register.html为jsp
②修改首页注册的超链接地址,通过servlet转发到注册界面register.jsp - 在servlet中获取请求参数,完成实体封装,调用service执行注册
①封装实体,设置id和激活码为自动生成
②调用service执行注册
③转发到msg.jsp - 在service中调用dao执行注册
- 在dao层使用beanutils完成注册(增加操作)
- 测试
- 编写自定义异常
- 编写转换器Conventer
1)User实体类
在com.zhumengkj.entity下新建实体类User
public class User implements Serializable{
/**
*
*/
private static final long serialVersionUID = -243642070602497283L;
private String uid;
private String username;
private String name;
private String email;
private String telephone;
private String birthday;
private String sex;
private Integer state;
private String code;
//...getter和setter方法
}
2)进入注册界面
以前很多同学喜欢直接使用超链接跳转到注册界面,如下:
<a href="${path}/jsp/register.jsp">注册</a>
这样的话跳转之后会在地址栏显示静态资源的位置:
为了提高安全性,我们需要隐藏静态资源的路径,则需要先访问servlet,然后通过转发进入到注册几面,修改超链接地址为:
<a href="${path}/user/toRegister">注册</a>
在com.zhumengkj.web.servlet包中新建UserServlet,重写service方法,添加@WebServlet("/user/*")用于处理所有user下的请求
@WebServlet("/user/*")
public class UserServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
得到请求路径真名URI,分析路径并进行处理:
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//得到URI
String uri=request.getRequestURI();
if(uri.endsWith("/toRegister")) {
toRegister(request,response);
}
}
private void toRegister(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//转发到注册界面
request.getRequestDispatcher("/jsp/register.jsp").forward(request, response);
}
重启项目,点击注册:
3)Servlet处理
不要忘了修改注册界面的form表单
private void register(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
//1、得到参数,实体封装
User user=new User();
//1.1 使用BeanUtils替换掉原始封装方法
try {
BeanUtils.populate(user, request.getParameterMap());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(user);
//1.2 设置用户id--随机生成
user.setUid(UUIDUtils.getId());
//1.3 设置激活码--随机生成
user.setCode(UUIDUtils.getCode());
//2、调用service完成注册
userService.regist(user);
//3、页面请求转发
request.setAttribute("msg", "用户注册成功,请去邮箱激活");
request.getRequestDispatcher("/jsp/msg.jsp").forward(request, response);
}
4)Service层处理
接口:
public interface UserService {
/**
* 注册
* @param user 要注册的用户信息
*/
void regist(User user);
}
实现类:
public class UserServiceImpl implements UserService{
//创建dao层对象
private UserDao userDao=new UserDaoImpl();
@Override
public void regist(User user) {
userDao.regist(user);
}
}
5)Dao层处理
使用beanUtils完成注册
UserDao接口:
public interface UserDao {
/**
* 增加一个用户信息
* @param user 要添加的用户信息
*/
void add(User user);
}
实现类:
public class UserDaoImpl implements UserDao{
//QueryRunner
private QueryRunner qr=new QueryRunner(DBUtil.getDataSource());
@Override
public void add(User user) {
String sql="insert into `user` values (?,?,?,?,?,?,?,?,?,?)";
try {
qr.update(sql,user.getUid(),user.getUsername(),user.getPassword(),user.getName()
,user.getEmail(),user.getTelephone(),user.getBirthday(),user.getSex()
,user.getState(),user.getCode());
} catch (SQLException e) {
e.printStackTrace();
}
}
}
6)测试
点击注册,显示用户注册成功,但是后台报错:
7)创建自定义异常
点击注册,后台报错,但是显示用户注册成功,没有跳转到500.jsp中
原因是我们在各个层次都处理了异常,现在我们把异常全部抛给web容器去处理
① 自定义异常
在com.zhumengkj.exception中创建MyException
/**
* 自定义异常,因为要在servlet中的service中抛出该异常,
* 所以该异常类型不能大于重写的service方法本身的异常,
* 所以要继承ServletException而不能继承Exception
*/
public class MyException extends ServletException{
/**
*
*/
private static final long serialVersionUID = -1031514310435909910L;
private String msg;
public MyException(String msg) {
this.msg=msg;
}
public MyException() {
super();
}
}
② 自定义异常
在dao层和service层把异常向上抛出
UserDao:
/**
* 增加一个用户信息
* @param user 要添加的用户信息
* @throws SQLException
*/
void add(User user) throws SQLException;
UserService:
/**
* 注册
* @param user 要注册的用户信息
* @throws SQLException
*/
void regist(User user) throws SQLException;
servlet:
//得到URI
String uri=request.getRequestURI();
//处理各个方法抛出的异常
try {
if(uri.endsWith("/toRegister")) {
toRegister(request,response);
}else if(uri.endsWith("/register")) {
register(request,response);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
//抛出自定义异常
throw new MyException();
}
③ 测试
注册,出错时跳转到500.jsp:
8)创建转换器Conventer
① 编写一个类,实现Conventer接口
② 实现方法
convert(转换成的类型,前台页面传入的字符串)
③ 注册转换器 在封装数据之前注册
ConvertUtils.register(…);
① 转换器MyConventer,实现convert方法,完成转换逻辑
public class MyConventer implements Converter{
/**
* 将传入的字符串转换为Date类型
* @param c 要封装的类型
* @param value 传入的值
*/
@Override
public Object convert(Class c, Object value) {
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
try {
Date date=sdf.parse((String)value);
return date;
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
② 注册转换器 在封装数据之前注册-UserServlet
···
//1、得到参数,实体封装
User user=new User();
//注册自定义转换器
ConvertUtils.register(new MyConventer(), Date.class);
//1.1 使用BeanUtils替换掉原始封装方法
BeanUtils.populate(user, request.getParameterMap());
···
③ 测试
进行注册:
点击注册:
查看数据库:
数据添加成功,但是在name处的姓名“张三”和sex性别的“男”是乱码。下一章我们讲解如何处理中文乱码。