自定义MVC(一)

前言

嘿,又来到了和大家以博客形式分享知识点的时候了,今天要分享的是,自定义mvc的一些准备工作和一些相关的案例,赶紧搬好小板凳听课啦!

mvc概念及相关了解

首先,在学习这个知识点之前,我们先来了解一下什么是自定义Mvc,以及自定义Mvc有什么作用吧!

MVC的概念:
MVC全名:Model View Controller
其中Model(模型层)、View(视图层)、Controller(控制层)
它是一种软件设计典范,可以用于业务逻辑处理、数据、界面显示分离!
MVC的作用:

1、自定义mvc是一种开源的框架,在学习的很多框架中都会使用到!

2、自定义mvc可以解决很多繁琐的操作,在一个类中就能完成增删改查!

mvc的工作原理图:
在这里插入图片描述
这是一张流程图噢!

mvc案例演示

说完这些,你可能脑子里还不太明白,那么我就以下面的案例来给你们演示一下具体的操作啦!不过需要注意的一点是,在操作前,你需要明白怎样去实现这个案例的一个整体思路:

我的整体思路是这个样子的:
1、新建一个动态的web项目,并导入需要使用的jar包,虽然我以下的操作暂时还没有用到,但是之后还是会用到的啦!

在这里插入图片描述
2、建包,再创建类
在这里插入图片描述
3、先写一个ActionServlet类,也就是中央控制器(充当公司中分配任务的上级领导)

package com.wangqiuping.mvc.framework;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.wangqiuping.mvc.action.AddAction;
import com.wangqiuping.mvc.action.HelloAction;

public class ActionServlet extends HttpServlet {
   
	/**
	 * 定义一个map集合  
	 */
	private Map<String,Action> map;
	
@Override
public void init() throws ServletException {
	// 初始化一个map集合
	map= new HashMap<String,Action>();
	//将子控制器添加到map集合
	map.put("/helloAction",new HelloAction());
	map.put("/addAction",new AddAction());
}	
	
	
@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doPost(req, resp);
	}	
	
	
@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//1、获取请求路径
	    String requestURI = req.getRequestURI();
	    System.out.println(requestURI);
	    System.out.println(req.getRequestURL());
        
	    int  start=requestURI.lastIndexOf("/");
	    int  end=requestURI.lastIndexOf(".action");
	   
	    
	    //2、截取请求路径中的/mvc/*.action的/*部分
	    String actionName= requestURI.substring(start,end);
	   
	    
	    //3、通过截取路径的actionName中找到对应的子控制器
	    Action action = map.get(actionName);//等同于new HelloAction()
	    // Action action=new HelloAction();
	    
	    //4、执行execute方法
	    action.execute(req, resp);
}
}

这个类实现的思路分为以下部分:
1、首先获取请求路径
2、其次截取请求路径中的/项目名/*.action中的/ * 部分
3、最后通过截取的actionName找到对应的子控制器
4、执行execute方法

注意:这个类中记得初始化一个map集合,然后把需要使用的子控制器添加到map集合中!

解析:
用我们生活中的案例来说,该类也就是我们的中央控制器,相当于一个公司中的上级领导,也就是负责分配任务的人!

4、写一个Action类,也就是子控制器(充当公司里的某个 部门的组长)

package com.wangqiuping.mvc.framework;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 子控制器  用来处理业务逻辑
 * @author 小汪同学  2020年6月2日 上午11:23:57
 *
 */

public abstract  class Action {

	public abstract String execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException;
	
}

解析:在Action类这个子控制器中,这个充当一个一个公司某部门的一个组长,用来接收上司分配的任务!

5、配置好与中央控制器对应的web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>Mvc</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <!--配置中央控制器  -->
  <servlet>
     <servlet-name>ActionServlet</servlet-name>
     <servlet-class>com.wangqiuping.mvc.framework.ActionServlet</servlet-class>
  </servlet>
  <!-- 映射中央控制器 -->
  <servlet-mapping>
    <servlet-name>ActionServlet</servlet-name>
    <url-pattern>*.action</url-pattern>
  </servlet-mapping>  
</web-app>

解析:
该配置文件中写好配置和映射ActionServlet类的具体节点,注意类的全路径名不要写错!

6、写一个HelloAction来测试一下

package com.wangqiuping.mvc.action;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.wangqiuping.mvc.framework.Action;

public class HelloAction extends Action {

	@Override
	public String execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("李易峰。。。。。。");
		return null;
	}
}

解析:
这个是我用来测试的一个HelloAction类,看是否能调用该方法,这个HelloAction类相当于某部门组长的组员,也就是具体完成这个任务的实现者!所以说如果出现以下这两张图片的结果,说明调用到了子控制器中的execute方法!

在这里插入图片描述
第一张是去Goole浏览器中访问HelloAction这个类!

在这里插入图片描述
第二张图片呢,是访问了该类后,调用了execute的方法,并输出了该方法中的数据,也就是说,我们可以把dao层这样的数据层的方法写在这个execute方法中!

案例(使用自定义mvc的方式完成加减乘除的操作)

案例来了,应该都已经坐在小板凳上准备认真听了吧!

1、首先写一个AddAction类,记得继承Action(子控制器)

package com.wangqiuping.mvc.action;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.wangqiuping.mvc.framework.Action;

public class AddAction extends Action {

	@Override
	public String execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	   int num3=0;
	   String num1 = req.getParameter("num1");
	   String num2 = req.getParameter("num2");
	   
	   String q=req.getParameter("+");
	   String w=req.getParameter("-");
	   String e=req.getParameter("*");
	   String r=req.getParameter("/");
	   
	   if("+".equals(q)) {
		    num3=Integer.parseInt(num1)+Integer.parseInt(num2);
	   }
	   if("-".equals(w)) {
		    num3=Integer.parseInt(num1)-Integer.parseInt(num2);
	   }
	   if("*".equals(e)){
		     num3=Integer.parseInt(num1)*Integer.parseInt(num2);
	   }
	   if("/".equals(r)) {
		   num3=Integer.parseInt(num1)/Integer.parseInt(num2);
	   }

	   req.setAttribute("num3",num3);
	   
	   req.getRequestDispatcher("add.jsp").forward(req,resp);
	   
	   return null;
	}
}

解析:
该类的实现需要以下部分:
1、获取jsp页面传过来的值,并进行判断
2、判断完之后,记得把定义的默认值存储起来
3、使用转发跳转到页面

2、然后是jsp页面,我这里以我自己写的add.jsp页面为例:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
   <form action="addAction.action" method="post">
       num1:<input name="num1"/><br>
       num2:<input name="num2"/><br>
            <input type="submit" value="+" name="+"/>
            <input type="submit" value="-" name="-" />
            <input type="submit" value="*" name="*"/>
            <input type="submit" value="/" name="/"/>
   </form>
   <h2>最终结果:${num3}</h2>
</body>
</html>

最终结果

加法:
在这里插入图片描述
在这里插入图片描述
减法:
在这里插入图片描述
在这里插入图片描述
乘法:

在这里插入图片描述
在这里插入图片描述

除法:

在这里插入图片描述

在这里插入图片描述

注意要点

1、直接运行ActionServlet类可能会出现空指针异常,因为这个Servlet一般是需要通过jsp页面去访问,才能获取到数据的!
2、在配置web.xml文件时,url-pattern节点放的应该是*.action,千万不要手贱加上了斜杠,那样的话很可能报子容器运行失败之类的错误,一般出现这个错误都是web.xml配置有问题!
3、需要实现子控制器中的方法时,一定要记得先继承!

在这里插入图片描述

补充知识点1(自定义mvc的常用模式)

常用模式:
model1:jsp+jdbc
model2:mvc

补充知识点2(自定义mvc的结构以及特点)

MVC的结构:

    V(视图层) --》JSP/HTML/freemarker

    C(控制层) --》Servlet/Action/Controller

    M(模型层) --》entity、dao   

    entity:实体域模型(名词)   
    dao:   过程域模型(动词)   因为会发生改变!
特点:1、高内聚  低耦合   各司其职
      2、不能跨层调用   
         只能由上往下调用
        View -> Controller -> Model

个人总结

之所以多次在这段时间的博客中提到自定义Mvc相关的知识点,说明都还比较重要,最后再强调一点,开源的很多框架中都有可能会用到自定义mvc呢,毕竟还比较方便!

猜你喜欢

转载自blog.csdn.net/qq_45464930/article/details/106502780