EasyMall项目重构之经典MVC
EasyMall项目重构之经典MVC
技术需求
平台前台技术后台技术 环境搭建
项目创建导入页面修改jsp中的图片路径 注册功能实现项目流程
通过浏览器接收数据验证数据的正确性将数据存入数据库向前台浏览器做出响应进行页面跳转 登陆功能实现项目流程
修改loginjsp创建LoginServlet 并实现登陆修改UserServiceImpl 添加登陆的方法修改UserDaoImpl 添加根据用户名和密码查询用户信息的方法修改主页中_headjsp 根据用户的登陆状态进行显示修改loginjsp获取Cookie中记住的用户名勾选记住用户名复选框
技术需求
平台
编译工具: MyEclipse2016 数据库: MySQL 服务器: TomCat 浏览器: fox browser
前台技术
HTML:组成基本的前台页面 css:控制页面布局与色彩 JavaScript:嵌入到静态的HTML中的脚本 ajax:用来与后台进行连接完成异步访问 jQuery:集成JavaScript的框架 JSP:负责前台数据的动态显示 el:负责展示数据 jstl负责处理页面的数据逻辑
后台技术
Servlet:与前台进行交互负责接收和请求数据 c3p0:负责创建数据库的连接池 BeanUtils:负责将数据封装到JavaBean中 JavaBean:用来建立用户模型,描述用户行为 反射:有效的解耦方便通过配置文件来控制 BeanHandler:封装JavaBean service:处理服务器发来的请求逻辑 dao:处理服务器与数据库服务器内部数据等交互式用到的逻辑 single pattern:单利模式用来实现单一实例为了工厂模式 factory pattern:工厂模式 properties:外部的实例化集合,用来存放可替换数据 验证码:负责生成页面的验证码
环境搭建
项目创建
创建EasyMall项目配置www.easymall.com主机, 并正hosts文件中配置主机名和IP地址的映射关系将EasyMall项目部署到easymall主机中
导入页面
首页: _head.jsp _foot.jsp index.jsp
注意: 需要在index.jps中将_head.jsp和_foot.jsp包含进来注册页面: regist.jsp登陆页面: login.jsp
修改jsp中的图片路径
因为图片路径默认是相对路径,要更改成绝对路径
${pageContext
.request.contextPath }/img/index/adv1
.jpg
通过EL表达式来展示数据
注册功能实现
项目流程
Created with Raphaël 2.1.0
注册页面
注册页面
script
script
servlet
servlet
service
service
dao
dao
db
db
主页面
主页面
前台验证
将验证信息返回
ajax验证
异步发送请求
交由服务层
交给dao处理数据
与数据库核对用户名
返回验证信息
进行页面显示
后台验证数据
交由服务层
交给dao处理数据
进行数据解析
数据不合理
数据不合理
返回不合理的数据并且重新填写表单
将数据存入数据库
存储成功
注册成功
注册就是为了实现将页面的数据通过浏览器存入到服务器中
通过浏览器接收数据
通过jQuery进行验证在页面进行数据验证如果有数据为空则在鼠标离开选框的时候进行提示. 通过ajax与后台数据库连接进行用户名是否存在的验证.
详情见regist.jsp页面中的script
验证数据的正确性
通过获取前台传过来的数据,经数据整合校验之后与数据库进行交互,对数据的处理一定要认真仔细包括乱码,数据是否可用,是否为垃圾数据等等
处理乱码请求参数乱码响应正文乱码通过创建user对象来存储访问数据
User user =
new User();
这里下面的代码利用了bean的工具类通过BeanUtils将数据封装到user类中
try {
BeanUtils.populate(user, request.getParameterMap());
}
catch (
Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
这里调用user的方法checkDate()来处理校验数据的逻辑通过向上抛出异常的方法来传递数据
if (WebUtils.isNull(username)) {
throw new MsgException(
"用户名不能为空111");
}
if (WebUtils.isNull(password)) {
throw new MsgException(
"密码不能为空");
}
这里在创建UserService的时候使用了工厂创建有效的实现了解耦通过单利模式的工厂来创建一个由反射组成的方法,从properties中获取想要使用的service
//
5.实现注册(将用户信息保存进数据库)
UserService service = BasicFactory
.getFactory()
.getInstance(UserService
.class)
工厂方法利用反射获取要加载的类
String className=prop
.getProperty(clazz
.getSimpleName())
//
2.根据类的权限定名称获取该类的Class对象
Class
clz=Class
.forName(className)
//
3.利用反射技术根据该类的class对象创建该类的实例
Object obj=
clz.newInstance()
return (T)obj
将数据存入数据库
通过service的方发完成数据的存入,调用registUser后通过访问dao中的方法来存储数据
service
.registUser(user)
通过接口来重写service中的方法,使用静态工厂调用dao,之后使用dao中的方法完成注册用户
private UserDao dao=BasicFactory.getFactory().getInstance(UserDao.class);
public void registUser(User user)
throws MsgException{
boolean result=dao.findUserByUsername(user.getUsername());
}
这里是使用自定义的工具类中的方法,通过BeanHandler方法将从数据库中获取的数据封装到user对象中
User user = JDBCUtils.query("
select * from user where username=?", new BeanHandler<User>(User.class), username);
向前台浏览器做出响应进行页面跳转
request
.setAttribute(
"msg", e
.getMessage())
request
.getRequestDispatcher(request
.getContextPath() +
"/regist.jsp")
.forward(request, response)
return
将验证过后的数据响应给浏览器在注册之后进行跳转
//
6.提示用户注册成功,
3秒之后跳转到首页!
response
.getWriter()
.write(
"<h1 style='color:red;text-align:center'>恭喜您注册成功, 3秒之后将会跳转到首页...</h1>")
response
.setHeader(
"refresh",
"3;url=" + request
.getContextPath() +
"/index.jsp")
登陆功能实现
项目流程
Created with Raphaël 2.1.0
登录页面
登录页面
script
script
servlet
servlet
service
service
dao
dao
db
db
主页面
主页面
是否记住用户名
传递remname
接收数据
交由服务层
交由dao层处理数据
判断用户密码
访问数据库
返回结果
返回结果
判断remname
传递cookie
处理remname
返回登录结果
登陆失败重新登录
登录成功
修改login.jsp
将登陆表单的地址执行LoginServlet
<form action=
"${pageContext.request.contextPath}/servlet/LoginServlet" method=
"POST">
创建LoginServlet, 并实现登陆
处理请求参数乱码
获取请求参数(用户登陆信息) String username = .. String password = .. String remname = …
调用UserService层的loginUser方法检查用户名密码是否正确
User user
= service
.loginUser(username, passsword);
if(user
!= null){
if(“
true”
.equals(remname)){
}
else{
}
实现登陆, 将User对象保存进session中作为登陆的标识
request.getSession().setAttribute(“user”, user);
response.sendRedirect(request.getContextPath+“/
index.jsp”);
}
else{
}
修改UserServiceImpl, 添加登陆的方法
通过调动dao中的方法来实现该功能
public User
loginUser(String username, String password) {
return dao.findUserByUsernameAndPassword(username,password);
}
修改UserDaoImpl, 添加根据用户名和密码查询用户信息的方法
同样使用自定义的工具类来完成
JDBCUtils.
update("insert into user values(null,?,?,?,?)", user.getUsername(), user.getPassword(),user.getNickname(), user.getEmail());
修改主页中_head.jsp, 根据用户的登陆状态进行显示
通过cookie来判断用户是否处于登录状态
if (
"true".equals(remname)) {
Cookie cookie = new Cookie(
"remname", URLEncoder
.encode(username,
"utf-8"))
cookie
.setPath(request
.getContextPath() +
"/")
cookie
.setMaxAge(
60 *
60)
response
.addCookie(cookie)
} else {
Cookie cookie = new Cookie(
"remname",
"")
cookie
.setPath(request
.getContextPath() +
"/")
cookie
.setMaxAge(
0)
response
.addCookie(cookie)
}
修改login.jsp
获取登陆失败后的提示消息可以通过EL表达式直接 获取因为提示信息是通过reponse响应到页面的
获取Cookie中记住的用户名
在用户名input输入框中的value属性中通过el来获取记住的用户名 使用js代码对取出的用户名进行url解码
window.onload=
function(){
var oInp=document.getElementsByName(
"username")[
0];
oInp.value=
decodeURI(oInp.value);
}
勾选”记住用户名”复选框
通过三目运算来判断是否选中来控制开关
value=
"true" ${
empty cookie.remname?
"":
"checked='checked'" }