J2EE(自定义MVC)

本文介绍了自定义J2EE MVC模式的过程,从MVC的基本概念开始,逐步讲解如何改进最初的增删改查操作,利用反射进行优化,以及自定义MVC的工作原理。通过实践,减少了代码冗余并提高了代码复用性。
摘要由CSDN通过智能技术生成

目录

前言

一、MVC简介

二、最初的增删改查改进

三、反射优化

四、mvc工作原理及对应打码

总结


前言

在之前我们就学习了JavaWeb中的MVC模式,今天我们就来自定义一个mvc模式


提示:以下是本篇文章正文内容,下面案例可供参考

一、MVC简介

mvc简介:http://t.csdn.cn/IVanV

二、最初的增删改查改进

前台:

<%@ 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>
<h3>目前增删改查的方法</h3>
<a href="${pageContext.request.contextPath }/book/add">增加</a>
<a href="${pageContext.request.contextPath }/book/del">删除</a>
<a href="${pageContext.request.contextPath }/book/edit">修改</a>
<a href="${pageContext.request.contextPath }/book/list">查询</a>
</body>
</html>

后台:

 增

package com.mgy.web;

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 AddBookServlet 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");
	}
}

package com.mgy.web;

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/del")
public class DelBookServlet 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");
	}
}

package com.mgy.web;

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/edit")
public class EditBookServlet 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");
	}
}

package com.mgy.web;

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/list")
public class ListBookServlet 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");
	}
}

效果:

 

 我们根据以上类可以知道问题

  关于单个实体/表操作场景越多,需要新建的类越多,造成了项目中类的数量过于庞大,

可以想一下我们是否能在一个类中调用所有的方法?

改进后:

前台:

<%@ 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>
<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=edit">修改</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=list">查询</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=load">回显</a>
</body>
</html>

后台:

package com.mgy.web;

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");		
		if("add".equals(methodName)){
//			如果前台传递到后台的是一个新增的请求,那么后台就调用新增方法
			add(req,resp);
		}
		else if("del".equals(methodName)) {
			del(req,resp);
		}
		else if("edit".equals(methodName)) {
			edit(req,resp);
		}
		else if("list".equals(methodName)) {
			list(req,resp);
		}
//       else if("load".equals(methodName)) {
//			load(req,resp);
//		}
	}

	private void list(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("在用一个servlet中调用 list 方法");
	}
	
//  private void load(HttpServletRequest req, HttpServletResponse resp) {
//		System.out.println("在用一个servlet中调用 list 方法");
//	}

	private void edit(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("在用一个servlet中调用 edit 方法");
	}

	private void del(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("在用一个servlet中调用 del 方法");
	}

	private void add(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("在用一个servlet中调用 add 方法");
	}
}

效果: 

那么问题出来了,当新增了业务,除了要添加该业务对应的方法(load),同时还要改动原有的代码。那我们是不是可以只加方法,上面代码不动?

三、反射优化

我们根据上述问题,用到我们之前学习的反射。

后台:

package com.mgy.web;

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/edit/list/load/xxx/yyy/aaa...
//		前台传递什么方法,就调用当前类的对应方法
		try {
			Method m = this.getClass().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();
		} 
		

	private void list(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("在用一个servlet中调用 list 方法");
	}
	
	private void load(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("在用一个servlet中调用 list 方法");
	}
	
	private void edit(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("在用一个servlet中调用 edit 方法");
	}

	private void del(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("在用一个servlet中调用 del 方法");
	}

	private void add(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("在用一个servlet中调用 add 方法");
	}
}

 前台:

<%@ 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>
<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=edit">修改</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=list">查询</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=load">回显</a>

</body>
</html>

效果:

我们已经进行两次优化,解决了类过多、新增业务改变原有业务的问题,现在相当于操作一张表,如果操作多张表呢,按照我们之前的代码所写,可以知道 反射相关代码,在每一个实体类对应的servlet中都存在、每一个servlet中都有doget、dopost方法;如果我们删掉了他是否还可以调用,答案是不可以的。

四、mvc工作原理及对应打码

自定义MVC工作原理图

 先建立中央控制器也就是ActionServlet

package com.mgy.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.mgy.web.BooKAction;

/**
 * 中央控制器:
 * 主要职能:接受浏览器请求,找到对应的处理人
 * 
 * @author Administrator
 *
 */
@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://localhost:8080/mvc/book.aciton?methodName=list
		String uri = req.getRequestURI();
//		要拿到/book,就是最后一个/到最后一个点的位置
		uri=uri.substring(uri.lastIndexOf("/")
						, uri.lastIndexOf("."));
		Action action = actions.get(uri);
		System.out.println(action);
		action.execute(req, resp);
	}
	
}

 对应处理人就是Action

package com.mgy.framework;

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

/**
 * 子控制器:
 * 对应请求的处理人
 * @author Administrator
 *
 */
public interface Action {
	void execute(HttpServletRequest req, HttpServletResponse resp);
}

ActionSupport继承于Action

package com.mgy.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/edit/list/load/xxx/yyy/aaa...
//		前台传递什么方法,就调用当前类的对应方法
		try {
			Method m = this.getClass().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();
		} 
	}
	
	private void list(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("在用一个servlet中调用 list 方法");
	}
	
	private void load(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("在用一个servlet中调用 list 方法");
	}
	
	private void edit(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("在用一个servlet中调用 edit 方法");
	}

	private void del(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("在用一个servlet中调用 del 方法");
	}

	private void add(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("在用一个servlet中调用 add 方法");
	}
}

 BooKAction实现ActionSupport

package com.mgy.web;

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

import com.mgy.framework.Action;
import com.mgy.framework.ActionSupport;

public class BooKAction extends ActionSupport {
	
	private void list(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("在用一个servlet中调用 list 方法");
	}
	
	private void load(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("在用一个servlet中调用 list 方法");
	}
	
	private void edit(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("在用一个servlet中调用 edit 方法");
	}

	private void del(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("在用一个servlet中调用 del 方法");
	}

	private void add(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("在用一个servlet中调用 add 方法");
	}
}

效果:

 


总结

今日的分享就到这了,本篇内容主要是自定义mvc。自定义mvc并不是很难,主要理解了流程就可以知道怎么去操作了。希望今日分享对大家有所帮助。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值