目录
六、MVC模式
1、MVC模式简介
使用BeanUtils
案例:MVC模式对数据库进行增删改查
View层:
Controllrer层:
Model层:
六、MVC模式
1、MVC模式简介
MVC模式认为,程序不论简单或是复杂,从结构上看,可以分为三层:
MVC代表Model(模型)、View(视图)、Controller(控制)
1)Model:是最底下的一层,就是最接近数据的一层,这一层主要负责业务和数据的处理,所以也叫业务模型层,主要有service和dao层;dao主要用于操作数据库。service层负责调用dao来完成业务。
2)Controller:控制层主要是servlet, 它负责根据用户从"视图层"输入的指令,选取"数据层"中的数据,然后对其进行相应的操作,产生最终结果。
3)View:主要是jsp页面或是html页面,直接面向用户的最上一层“视图层”,是提供给用户的操作界面。
三个层次相互联系又相互独立,每一层都对外提供了接口,所以某一层的变化,不会影响其它层,这样实现模块化之后,方便了维护和升级。
使用BeanUtils
将页面传来的参数转换成JavaBean对象,是一个没有任何技术含量的体力活,往往令程序员不胜其烦,这里要使用以下三个jar文件:
commons-beanutils-1.9.3.jar,核心工具包
commons-collections-3.2.2.jar,增强集合包
commons-logging-1.1.1.jar,工具日志包
这样以往的体力活就变成简单的转换
request.setCharacterEncoding("utf-8");
Map<String, String[]> map = request.getParameterMap();
Student stu=new Student();
try {
BeanUtils.populate(stu, map);//将map填充到stu对象中
} catch (IllegalAccessException e) {//非法访问异常
e.printStackTrace();
} catch (InvocationTargetException e) {//调用目标异常
e.printStackTrace();
}
System.out.println(stu);
/*以往的体力活
String stuid=request.getParameter("stuId");
String stuName=request.getParameter("stuName");
String sex=request.getParameter("sex");
String birthday=request.getParameter("birthday");
String dept=request.getParameter("dept");
String address=request.getParameter("address");
stu=new Student(Integer.parseInt(stuid),stuName,sex, Date.valueOf(birthday),dept,address);
*/
StudentDao sd=new StudentDaoImpl();
int i=sd.updateStudent(stu);
案例:MVC模式对数据库进行增删改查
View层:
增加修改用户界面(jsp):
<body align="center" >
<h1>增加/修改用户</h1>
<%--将添加和修改共用一个jsp页面,方便拓展和维护--%>
<%--在跳转时,把id给传送过去,添加的用户id为0,修改的用户id为对应的值,根据id可以判断将要进行的是添加操作或是修改操作--%>
<form action="userAll?method=add&id=${user.id}" method="post">
<%--如果是添加,value值是空,修改的value值是对应的名字--%>
用户名:<input type="text" name="username" value="${user.username}"><br>
<%-- 检验用户是否存在,如果存在,代表是修改,则判空为false,则该密码框不显示,否则为添加,显示密码框--%>
<c:if test="${empty user}">
密 码:<input type="password" name="password"><br>
</c:if>
<%--如果有性别的信息,且性别等于男则选中男,女也相同,若为空值,就是添加用户,未选择值--%>
性别:<input type="radio" name="sex" value="男" <c:if test="${user.sex=='男'}">checked</c:if> >男
<input type="radio" name="sex" value="女" <c:if test="${user.sex=='女'}">checked</c:if> >女<br>
<input type="submit" value="确定">
</form>
</body>
展示用户信息界面(.jsp):
<head>
<style>
a{
color: deepskyblue;
}
</style>
<title>展示信息</title>
</head>
<body align="center">
<table border="1" cellspacing="0" align="center" >
<thead><h1>展示信息</h1></thead>
<tr>
<th>id</th>
<th>名字</th>
<th>性别</th>
<th>操作</th>
</tr>
<c:forEach items="${all}" var="u">
<tr>
<td>${u.id}</td>
<td>${u.username}</td>
<td>${u.sex}</td>
<%-- 给修改方法和删除方法都绑定一个点击事件,绑定上对应的函数--%>
<td><a onclick="upd(${u.id})">修改</a> <a onclick="del(${u.id})" >删除</a></td>
</tr>
</c:forEach>
<tr><td colspan="4" align="center"><a href="index.jsp">添加用户</a></td></tr>
</table>
<script type="text/javascript">
//定义删除方法
function del(id){
var status = confirm("你确定删除这条数据吗?");
//如果确认删除,则跳转到删除user对应的servlet中
if (status==true){
//跳转时,将method参数对应的值,以及对应的用户id携带过去
window.location="/userAll?method=del&id="+id;
}
}
//定义修改方法
function upd(id){
//跳转时,将method参数对应的值,以及对应的用户id携带过去
window.location="userAll?method=upd&id="+id;
}
</script>
</body>
Controllrer层:
因为每个数据库的表都有可能进行增删改查,这样就会有很多的servlet,为解决这个问题,可以为每一个实体类创建一个Servlet,负责完成该实体来的增删改查等业务操作,
@WebServlet(name = "UserAllServlet", value = "/userAll")
public class UserAllServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
//根据关键字获取页面元素
String method = req.getParameter("method");
//如果没有任何请求,则执行查询所有用户信息的操作
if (method==null){
showAll(req,resp);
}else {
switch (method){
case "add":
addO(req,resp);
break;
case "del":
del(req,resp);
break;
case "upd":
upd(req,resp);
break;
default:
}
}
}
//查询用户信息的操作
private void upd(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
req.setCharacterEncoding("utf-8");
String id = req.getParameter("id");
IUserService iUserService = new UserServiceImpl();
//调用service层的方法查询用户的信息
Map<String, Object> map = iUserService.queryById(id);
//将用户的信息封装到request中,别名为user
req.setAttribute("user",map);
req.getRequestDispatcher("index.jsp").forward(req,resp);
}
//删除用户信息的操作
private void del(HttpServletRequest req, HttpServletResponse resp) throws IOException {
req.setCharacterEncoding("utf-8");
//通过id获取要删除的用户信息
String id = req.getParameter("id");
System.out.println(id);
IUserService iUserService = new UserServiceImpl();
//调用service的删除用户方法,删除用户信息
boolean b = iUserService.delUser(id);
if (b){
System.out.println("删除成功");
resp.sendRedirect("userAll");
}else{
System.out.println("删除失败");
resp.sendRedirect("index.jsp");
}
}
//添加用户信息的操作
private void addO(HttpServletRequest req, HttpServletResponse resp) throws IOException {
req.setCharacterEncoding("utf-8");
Map<String, String[]> parameterMap = req.getParameterMap();
IUserService iUserService = new UserServiceImpl();
//调用service的添加用户方法
boolean addStatus = iUserService.addUser(parameterMap);
if (addStatus==true){
System.out.println("添加成功");
resp.sendRedirect("userAll");
}else{
System.out.println("添加失败");
resp.sendRedirect("index.jsp");
}
}
//展示所有信息的方法
private void showAll(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
IUserService iUserService = new UserServiceImpl();
//调用service的查询所有用户方法
List<Map<String,Object>> allUser = iUserService.queryAll();
req.setAttribute("all",allUser);
req.getRequestDispatcher("showUser.jsp").forward(req,resp);
}
}
Model层:
dao接口及dao接口的实现:
public interface IUserDao {
int addU(User user);
List<Map<String, Object>> queryA();
List<Map<String, Object>> findB(String id);
int delU(String id);
int updU(User user);
}
public class UserDaoImpl extends BaseDao implements IUserDao {
//添加用户
@Override
public int addU(User user) {
String sql = "insert into t_user(username,password,salt,sex) values(?,?,?,?)";
return addOrUpdate(sql,user.getUsername(),user.getPassword(),user.getSalt(),user.getSex());
}
//查询所有用户信息
@Override
public List<Map<String, Object>> queryA() {
String sql = "select * from t_user";
return query(sql);
}
//根据用户id查询用户信息
@Override
public List<Map<String, Object>> findB(String id) {
String sql = "select * from t_user where id = ?";
return query(sql,id);
}
//删除用户信息
@Override
public int delU(String id) {
String sql = "delete from t_user where id = ?";
return addOrUpdate(sql,id);
}
//修改用户信息
@Override
public int updU(User user) {
String sql = "update t_user set username=? , sex=? where id = ?";
return addOrUpdate(sql,user.getUsername(),user.getSex(),user.getId());
}
}
service接口及service接口的实现:
public interface IUserService {
boolean addUser(Map<String, String[]> parameterMap);
boolean delUser(String id);
List<Map<String, Object>> queryAll();
Map<String, Object> queryById(String id);
//增加和修改可以共用一个Service方法
// boolean updUser(Map<String, String[]> parameterMap);
}
public class UserServiceImpl implements IUserService {
//添加和修改方法
@Override
public boolean addUser(Map<String, String[]> parameterMap) {
int i = -1;
User user = new User();
try {
BeanUtils.populate(user,parameterMap);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
IUserDao iUserDao = new UserDaoImpl();
System.out.println(user);
//判断传来的用户id值是多少,如果为0,则代表是用户添加操作
if (user.getId()==0){
//通过UUID方式获得一个随机且唯一的数字
String salt = UUID.randomUUID().toString();
//用这个随机数字盐给密码进行加密
String md5Password = MD5Util.MD5EncodeUtf8(user.getPassword(), salt);
//将密码和盐都赋值给用户
user.setPassword(md5Password);
user.setSalt(salt);
System.out.println(user);
//调用dao层方法添加用户信息
i = iUserDao.addU(user);
}else{
//调用dao层方法修改用户信息
i = iUserDao.updU(user);
}
return i>0 ? true:false;
}
//删除用户方法
@Override
public boolean delUser(String id) {
IUserDao iUserDao = new UserDaoImpl();
//调用dao层方法删除用户信息
int i =iUserDao.delU(id);
return i>0? true:false;
}
//查询所有用户信息的方法
@Override
public List<Map<String, Object>> queryAll() {
IUserDao iUserDao = new UserDaoImpl();
//调用dao层方法查找所有用户信息
List<Map<String,Object>> allU = iUserDao.queryA();
return allU;
}
//通过id查询用户信息
@Override
public Map<String, Object> queryById(String id) {
IUserDao iUserDao = new UserDaoImpl();
//调用dao层方法通过id查询用户信息
List<Map<String,Object>> userB = iUserDao.findB(id);
return userB.get(0);
}
//增加和修改可以共用同一个方法,只需要判断用户的id值是什么
// @Override
// public boolean updUser(Map<String, String[]> parameterMap) {
User user = new User();
try {
BeanUtils.populate(user,parameterMap);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
IUserDao iUserDao = new UserDaoImpl();
int i = iUserDao.updU(user);
return i>0? true:false;
// return true;
// }
}
其他:
实体类:
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String username;
private String password;
private String salt;
private String sex;
}
BaseDao(前面的章节有)
MD5加密类:
public class MD5Util {
//这里主要是遍历8个byte,转化为16位进制的字符,即0-F
private static String byteArrayToHexString(byte b[]) {
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < b.length; i++)
resultSb.append(byteToHexString(b[i]));
return resultSb.toString();
}
//这里是针对单个byte,256的byte通过16拆分为d1和d2
private static String byteToHexString(byte b) {
int n = b;
if (n < 0)
n += 256;
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
}
/**
* 返回大写MD5
* @param origin
* @param charsetname
* @return
*/
private static String MD5Encode(String origin, String charsetname) {
String resultString = null;
try {
resultString = new String(origin);
MessageDigest md = MessageDigest.getInstance("MD5");
if (charsetname == null || "".equals(charsetname))
resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
else
resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
} catch (Exception exception) {
}
return resultString.toUpperCase();
}
public static String MD5EncodeUtf8(String origin) {
origin = origin + "salt";
return MD5Encode(origin, "utf-8");
}
public static String MD5EncodeUtf8(String origin,String salt) {
origin = origin + salt;
return MD5Encode(origin, "utf-8");
}
private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
public static void main(String[] args) {
String password="207ACD61A3C1BD506D7E9A4535359F8A";
String pass="123456";// 输入密码
String s = MD5EncodeUtf8(pass);
System.out.println(s.equals(password));
}
}