目录

六、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));
    }
}