目录
什么是mvc?
m:model------模型层
v:view-------视图层
c:controller-------控制层
优点:分工明确,各司其职
每一个方法都需要写一个类
一、以下就拿出一个类的代码来演示
- package com.dengxiyan.servlet;
-
- import java.io.IOException;
-
- import javax.servlet.ServletException;
- import javax.servlet.annotation.WebServlet;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- @WebServlet("/book/add")
- public class AddServlet extends HttpServlet{
-
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- doPost(req, resp);
- }
-
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- System.out.println("处理书籍的增加业务,调用BookBiz");
-
- }
-
- }
《jsp界面代码》
存在问题:
1.关于单个实体表操作场景越多,需要新建的类越多,造成了项目中类的数量过大
- <%@ page language="java" contentType="text/html; charset=UTF-8"
- pageEncoding="UTF-8"%>
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>Insert title here</title>
- </head>
- <body>
-
- <h3>目前的增删改查</h3>
- <a href="${pageContext.request.contextPath }/book/add">增加</a>
- <a href="${pageContext.request.contextPath }/book/del">删除</a>
- <a href="${pageContext.request.contextPath }/book/update">修改</a>
- <a href="${pageContext.request.contextPath }/book/select">查看</a>
-
-
- </body>
- </html>
效果图
《代码演示》
- package com.dengxiyan.servlet;
-
- import java.io.IOException;
- import java.lang.reflect.Method;
-
- import javax.servlet.ServletException;
- import javax.servlet.annotation.WebServlet;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- @WebServlet("/book.action")
- public class BookServlet extends HttpServlet {
-
-
-
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- doPost(req, resp);
- }
-
-
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- //为了区分当前请求的目的,增删改查的目的,就从前台将要调用方法名传递到后台
- String methodName = req.getParameter("methodName");
- //methodName可能是add/del/...
- //前台传递什么方法,就调用当前类对应的方法
- try {
- Method m = this.getClass()//相当于BookServlet
- .getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
- m.setAccessible(true);
- //调用当前类实例的methodName方法 传什么就掉什么方法
- m.invoke(this, req,resp);
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
-
- }
-
-
- /**
- 以上代码是对以下代码的优化
- */
- //如果前台传递后台的是一个新增的请求,那么后台就调用新增的方法
- /*if("add".equals(methodName)) {
- add(req,resp);
- }
- else if("del".equals(methodName)) {
- del(req,resp);
- }
- else if("update".equals(methodName)){
- update(req,resp);
- }
- else if("select".equals(methodName)) {
- select(req,resp);
- }
- else if("lod".equals(methodName)) {
- lod(req,resp);
- }*/
-
-
- private void lod(HttpServletRequest req, HttpServletResponse resp) {
- System.out.println("在同一个servlet中调用 回显");
-
- }
-
-
- private void select(HttpServletRequest req, HttpServletResponse resp) {
- System.out.println("在同一个servlet中调用 增加");
-
- }
-
-
- private void update(HttpServletRequest req, HttpServletResponse resp) {
- System.out.println("在同一个servlet中调用 修改");
-
-
- }
-
-
- private void del(HttpServletRequest req, HttpServletResponse resp) {
- System.out.println("在同一个servlet中调用 删除");
-
- }
-
-
- private void add(HttpServletRequest req, HttpServletResponse resp) {
- System.out.println("在同一个servlet中调用 查看 ");
-
- }
-
- }
jsp代码
存在问题:
当新增业务,除了要添加一个新的请求
反射相关的代码,在每一个实体类对应的servlet中都存在
- <%@ page language="java" contentType="text/html; charset=UTF-8"
- pageEncoding="UTF-8"%>
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>Insert title here</title>
- </head>
- <body>
-
-
- <h3>类数量问题过多问题优化</h3>
- <a href="${pageContext.request.contextPath }/book.action?methodName=add">增加</a>
- <a href="${pageContext.request.contextPath }/book.action?methodName=del">删除</a>
- <a href="${pageContext.request.contextPath }/book.action?methodName=update">修改</a>
- <a href="${pageContext.request.contextPath }/book.action?methodName=select">查看</a>
- <a href="${pageContext.request.contextPath }/book.action?methodName=lod">回显</a>
-
-
- </body>
- </html>
《效果图》
根据以上逻辑图得知需建立以下类
DispatcherServlet(中央控制器)
主要功能:接收浏览器请求,找到对应的处理人。不处理任何业务逻辑,只接受请求
《代码演示》
提示:@WebServlet("*.action")这样写的好处在于,只要含有action路径的都能识别,就不用在多个类里写
- package com.dengxiyan.framework;
-
- import java.io.IOException;
- import java.util.HashMap;
- import java.util.Map;
-
- import javax.servlet.ServletException;
- import javax.servlet.annotation.WebServlet;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- import com.dengxiyan.servlet.BookAction;
-
- /**
- * 中央控制器
- * @author DXY
- *2022年6月24日下午5:39:23
- */
-
- @WebServlet("*.action")
- public class DispatcherServlet extends HttpServlet{
-
- private Map<String, Action> actions = new HashMap<String, Action>();
-
-
- //程序启动时值加载一次
- @Override
- public void init() throws ServletException {
- actions.put("/book", new BookAction());
- // actions.put("/order", new BookAction());
- }
-
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- doPost(req, resp);
- }
-
-
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- //http://location:8080/mvc/book.action?me....
- String uri = req.getRequestURI();//路径
- // 要拿到/book,就是最后一个/到最会一个.的位置
- uri = uri.substring(uri.lastIndexOf("/"),
- uri.lastIndexOf("."));
-
- Action action = actions.get(uri);
- action.execute(req, resp);
-
- }
-
-
- }
Action(自控制器)接口类 对应请求处理的人
《代码演示》
- package com.dengxiyan.framework;
-
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- /**
- *
- * 子控制器
- * @author DXY
- *2022年6月24日下午5:42:03
- */
- public interface Action {
-
- //封装继承多态
- void execute(HttpServletRequest req, HttpServletResponse resp);
-
- }
ActionSupport类
《代码演示》
此类需要实现子控制器(Action),同时要实现自控制器的方法execute。
- package com.dengxiyan.framework;
-
- import java.lang.reflect.Method;
-
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- public class ActionSupport implements Action{
-
- @Override
- public void execute(HttpServletRequest req, HttpServletResponse resp) {
- String methodName = req.getParameter("methodName");
- //methodName可能是add/del/...
- //前台传递什么方法,就调用当前类对应的方法
- try {
- Method m = this.getClass()//相当于BookServlet
- .getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
- m.setAccessible(true);
- //调用当前类实例的methodName方法 传什么就掉什么方法
- m.invoke(this, req,resp);
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
-
- }
-
- }
BookAction类,需要继承ActionSupport类,不用调用doGet及doPost方法,只需要执行以下方法即可,因为每一个servlet都有doget,dopost方法
《代码演示》
- package com.dengxiyan.servlet;
-
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- import com.dengxiyan.framework.ActionSupport;
-
- public class BookAction extends ActionSupport {
-
- private void lod(HttpServletRequest req, HttpServletResponse resp) {
- System.out.println("在同一个servlet中调用 回显");
-
- }
-
-
- private void select(HttpServletRequest req, HttpServletResponse resp) {
- System.out.println("在同一个servlet中调用 增加");
-
- }
-
-
- private void update(HttpServletRequest req, HttpServletResponse resp) {
- System.out.println("在同一个servlet中调用 修改");
-
-
- }
-
-
- private void del(HttpServletRequest req, HttpServletResponse resp) {
- System.out.println("在同一个servlet中调用 删除");
-
- }
-
-
- private void add(HttpServletRequest req, HttpServletResponse resp) {
- System.out.println("在同一个servlet中调用 查看 ");
-
- }
-
- }
jsp界面代码
- <%@ page language="java" contentType="text/html; charset=UTF-8"
- pageEncoding="UTF-8"%>
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>Insert title here</title>
- </head>
- <body>
-
- <%-- <h3>目前的增删改查</h3>
- <a href="${pageContext.request.contextPath }/book/add">增加</a>
- <a href="${pageContext.request.contextPath }/book/del">删除</a>
- <a href="${pageContext.request.contextPath }/book/update">修改</a>
- <a href="${pageContext.request.contextPath }/book/select">查看</a>
- --%>
- <!--
- 存在问题:
- 1.关于单个实体表操作场景越多,需要新建的类越多,造成了项目中类的数量过大
- 2.当新增业务,除了要添加一个新的请求
- 3.反射相关的代码,在每一个实体类对应的servlet中都存在
- 4.每一个servlet都有doget,dopost方法
- -->
-
-
- <!-- 类数量问题过多问题优化 -->
- <h3>类数量问题过多问题优化</h3>
- <a href="${pageContext.request.contextPath }/book.action?methodName=add">增加</a>
- <a href="${pageContext.request.contextPath }/book.action?methodName=del">删除</a>
- <a href="${pageContext.request.contextPath }/book.action?methodName=update">修改</a>
- <a href="${pageContext.request.contextPath }/book.action?methodName=select">查看</a>
- <a href="${pageContext.request.contextPath }/book.action?methodName=lod">回显</a>
-
-
- </body>
- </html>
效果图
效果同上,只是编码方式不