- Model2模式
Jsp+Servlet+JavaBean
MVC:开发模式
M:Model 模型层 ----> JavaBean
V:View 视图层 ----> Jsp
C:Controller 控制层 ----> Servlet
分层思想:强内聚,低耦合
- 案例
先看效果图
通过这张图,我们简单的分析一下如何通过MVC实现登录注册功能.请看下图
此图并非原创,感谢原创!
通过分层,开发人员只需关注每个模块的具体实现,一个模块的改变不会影响另一个模块。
1.导入相应的jar包
2.开发一个数据库(表名为users)
`
CREATE TABLE users(
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(20) ,
PASSWORD VARCHAR(50),
email VARCHAR(100),
birthday DATE) `
3.JavaBean的实现
比较简单,只要生成和表的列名一样就ok了,并生成get和set方法,这里就不列出代码了。相信聪明的你一定知道我在说什么吧!
4.数据访问层
`public interface UserDao {
//注册
public void adduser(User user) throws Exception;
//登录查询
public User queryuser(User user)throws Exception;
//用户名输入是否一致
public boolean queryUserByName(String name) throws Exception;
}`
实现类:
addUser():
` psPreparedStatement =connection.prepareStatement("INSERT INTO users (username,PASSWORD,email,birthday) VALUES(?,?,?,?)");
psPreparedStatement.setString(1, user.getUsername());
psPreparedStatement.setString(2, user.getPassword());
psPreparedStatement.setString(3, user.getEmail());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String date = sdf.format(user.getBirthday());
psPreparedStatement.setString(4, date);
psPreparedStatement.executeUpdate();`
queryuser():
` ps = connection.prepareStatement("select * from users where username=? and password=?");
ps.setString(1, user.getUsername());
ps.setString(2, user.getPassword());
rs =ps.executeQuery();
if(rs.next()){
u = new User();
u.setId(rs.getInt("id"));
u.setUsername(rs.getString("username"));
u.setPassword(rs.getString("password"));
u.setEmail(rs.getString("email"));
u.setBirthday(rs.getDate("birthday"));`
queryUserByName():
` ps = connection.prepareStatement("select * from users where username=?");
ps.setString(1, name);
rs =ps.executeQuery();
if(rs.next()){
return true;
}`
5.业务层
很简单就是调用数据层的对应方法
`public class UserServiceImpl implements UserService {
UserDao mUserDao = new UserImpl();
public void registerUser(User user) throws Exception {
mUserDao.adduser(user);
}
public User loginUser(User user) throws Exception {
User user2 =mUserDao.queryuser(user);
return user2;
}
public boolean queryUserByName(String name) throws Exception {
return mUserDao.queryUserByName(name);
}`
web层待会写,先生成几个表单
6.表单实现
1.登录注册(这里就算是首页吧。)
` <c:if test="${empty u }">
<a href="login.jsp">登录</a>
<a href="reg.jsp">注册</a>
</c:if>
<c:if test="${not empty u }">
欢迎你:${u.username } <a href="${pageContext.request.contextPath }/servlet/removeLogin">注销</a>
</c:if>`
这里用到了EL表达式,不懂的童鞋自行谷歌!不要忘了倒库哈!
login.jsp(登录页面)太简单,代码不贴了。
reg.jsp(注册页面)
` <form action="${pageContext.request.contextPath }/servlet/regServlet" method="post">
用户名:<input type="text" name="username" value="${userForm.username }">${userForm.map.username } ${error }<br>
密码:<input type="password" name="password"><br>
确认密码:<input type="password" name="repassword"><br>
邮箱:<input type="text" name="email" value="${userForm.email }"> ${userForm.map.email }<br>
生日:<input type="text" name="birthday" value="${userForm.birthday }">${userForm.map.birthday }<br>
<input type="submit" value="提交"><br>
</form>`
同样这里用到了EL表达式!
7.Web层实现
1.注册Servlet(RegServlet.java)
` User user = new User();
//如果输入不合法,就提示。
UserForm userForm = new UserForm();
try {
BeanUtils.populate(userForm, request.getParameterMap());
boolean validate = userForm.validate();
if(!validate){
//有错误
request.setAttribute("userForm", userForm);
//转发
request.getRequestDispatcher("/reg.jsp").forward(request,response);
return;
}
} catch (Exception e1) {
e1.printStackTrace();
}`
`//获取表单数据
ConvertUtils.register(new DateLocaleConverter(), java.util.Date.class);
BeanUtils.populate(user, request.getParameterMap());
//调用业务逻辑
UserService reg = new UserServiceImpl();
boolean queryUserByName = reg.queryUserByName(user.getUsername());
if(queryUserByName){
request.setAttribute("error","用户名已存在" );
request.getRequestDispatcher("/reg.jsp").forward(request,response);
}else {
reg.registerUser(user);
//分发转向
writer.print("注册成功!3秒后自动跳转首页!");
response.setHeader("refresh", "3;url="+request.getContextPath()+"/index.jsp");
}`
看一下UserForm的代码:
` private Map<String, String> map =new HashMap<String, String>();
/*
* 验证
* */
public boolean validate(){
if("".equals(username)){
map.put("username", "用户名不能为空");
}else if(!username.matches("\\w{3,8}")){
map.put("username", "用户名应该在3到8位");
}
if("".equals(password)){
map.put("password", "用户名不能为空");
}else if(!password.matches("\\d{3,8}")){
map.put("password", "密码应该在3到8位");
}
if(!repassword.equals(password)){
map.put("repassword", "二次密码不一致");
}
if("".equals(email)){
map.put("email", "邮箱不能为空!");
}else if(!email.matches("\\b^['_a-z0-9-\\+]+(\\.['_a-z0-9-\\+]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*\\.([a-z]{2}|aero|arpa|asia|biz|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|nato|net|org|pro|tel|travel|xxx)$\\b")){
map.put("email", "邮箱格式不正确!");
}
if("".equals(birthday)){
map.put("birthday", "生日不能为空");
}else {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
sdf.parse(birthday);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
map.put("birthday", "格式不正确");
}
}
return map.isEmpty();//正确
}`
如果用户输入的都合法,那么Map集合是空的,返回true,否则false.
2.登录Servlet(LoginServlet.java)
`UserService us = new UserServiceImpl();
//通过数据库中用户名和密码是否存在
user2 = us.loginUser(user);
if(user2==null){
//数据库中没有响应的用户名和密码,重定向到登录界面
response.sendRedirect(request.getContextPath()+"/login.jsp");
}else {
//用户名用session保存
request.getSession().setAttribute("u", user2);
request.getRequestDispatcher("/index.jsp").forward(request,response);
}`
3.注销功能实现(RemoveServlet.java):
很简单,就是删除session并返回首页
` request.getSession().invalidate();
response.sendRedirect(request.getContextPath()+"/index.jsp");`
最后:这里只贴了每个模块的核心代码,有什么不懂的欢迎和我讨论!功能虽然简单,但涉及的知识点还是比较多的,除了逻辑问题以外,还有转发,重定向,JDBC,MySql,正则表达式等知识点。