mvc框架upgrade

upgrade...

  • 1. actionservlet核心控制器更改以上1,2点
  • 2. 工具类(对反射拿到的属性对象数据转型)
  • 3. 业务服务类使用适配器设计模式

  • 针对上一篇文字做出了改造,既然要写手写lowb版mvc框架,就得付出一定代价,加大代码量,只考虑实现业务
    上一篇的升级版
  • 更改的地方:
    1. 使用xml配置文件代替config.properties,更灵活方便,用来映射请求方式与实现业务类的路径
    2. 按规则封装了request请求对象中的数据,规则(a. 表单中的表单元素名称同实体类中属性的名称一样 b. 表单中的元素名称 以 实体对象.属性名称命名)
    3. 一个服务类就可完成增删改查业务逻辑操作

1. actionservlet核心控制器更改以上1,2点

  • action.xml 映射请求路径和服务类全路径
  • 描述action.xml 的数据结构
package com.lovely.mvc;/*** * @author echo lovely* * action.xml 映射数据, 加载xml中的类**/
public class MapperAction {private String path; // 请求路径private String type; // 类的全路径public String getPath() {return path;}public void setPath(String path) {this.path = path;}public String getType() {return type;}public void setType(String type) {this.type = type;}@Overridepublic String toString() {return "MapperAction [path=" + path + ", type=" + type + "]";}}
  • 核心控制器实现更改
package com.lovely.mvc;import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;import com.lovely.util.ConvertUtil;public class ActionServlet extends HttpServlet {/*** 核心控制servlet* 根据访问方式 和 类的路径信息 到对应的servlet来处理*/private static final long serialVersionUID = 1L;Map<String, MapperAction> map = new HashMap<String, MapperAction>();@Overridepublic void init() throws ServletException {// 加载xml内容 调用具体服务类SAXReader reader = new SAXReader();InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/action.xml");try {Document doc = reader.read(in);List<Element> list = doc.selectNodes("//action");for (Element action : list) {String path = action.elementText("path");String type = action.elementText("type");MapperAction mapper = new MapperAction();mapper.setPath(path);mapper.setType(type);map.put(path, mapper);}} catch (DocumentException e) {e.printStackTrace();} finally {try {if (in != null)in.close();} catch (IOException e) {e.printStackTrace();}}}@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {String uri = req.getRequestURI();String key = uri.substring(uri.lastIndexOf("/") + 1, uri.lastIndexOf("."));// 根据请求对象 拿到对应的类 进行服务String value = map.get(key).getType();if (value == null) {resp.sendError(404, key + "不在配置文件xml中");return;}try {// 反射拿到类对象Class<?> c = Class.forName(value);// 创建action对象Action action = (Action) c.newInstance();// 对request请求数据进行封装		// xxx服务类直接拿到 前台数据Map<String, String[]> requestMap = req.getParameterMap();Set<Entry<String,String[]>> entrySet = requestMap.entrySet();// 对表单提交过来的每个值 封装到xxxaction服务类中的属性for (Entry<String, String[]> entry : entrySet) {// 表单的名字String name = entry.getKey();// 表单的值 String[] formValue = entry.getValue();// 判断表单元素的名称是p.name 或者 是name 这里判断是 nameif (name.indexOf(".") == -1) {// 直接提交属性名 为xxxAction中的属性赋值try {Field field = c.getDeclaredField(name);field.setAccessible(true);// 属性的类型可能是 String int/Integer double/Double boolean Date/Timstamp Integer[]/int[] Double[]/doble[] 转型field.set(action, ConvertUtil.convert(field, formValue));} catch (NoSuchFieldException e) {//e.printStackTrace(); 可能没这个属性} catch (SecurityException e) {e.printStackTrace();}} else {// 提交的值 封装到对象中try {// p.name p.age 表单元素的名称写法  对象.属性String[] split = name.split("\\.");// 父级对象属性Field fieldEntity = c.getDeclaredField(split[0]);fieldEntity.setAccessible(true);// 取到对象Object entity = fieldEntity.get(action);// 空对象if (entity == null) {// 拿到属性对象的类型 创建对象entity = fieldEntity.getType().newInstance();fieldEntity.set(action, entity);}		// 取到二级对象 // f.name 取到name			// 父级属性类对象Class<?> ff = fieldEntity.getType();Field field = ff.getDeclaredField(split[1]);field.setAccessible(true);// 设置 p.name 的值 转型field.set(entity, ConvertUtil.convert(field, formValue));} catch (NoSuchFieldException e) {// e.printStackTrace();} catch (SecurityException e) {e.printStackTrace();}}}String result = action.service(req, resp);if (result == "")return;if (result != null) {// 根据返回结果 决定是请求转发 还是重定向if (result.startsWith("forward")) {String path = result.split(":")[1];req.getRequestDispatcher(path).forward(req, resp);} else if (result.startsWith("redirect")) {String path = result.split(":")[1];resp.sendRedirect(req.getContextPath() + path);} else {// 写路径默认请求转发req.getRequestDispatcher(result).forward(req, resp);}				}} catch (ClassNotFoundException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}}

2. 工具类(对反射拿到的属性对象数据转型)

  • 由于数据库dao层使用ConverUtil中的convert, 所以为了不改代码,使用重载设计
package com.lovely.util;import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.sql.Date;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;public class ConvertUtil {/*** 把数据库查出来的string转换为对应的属性类型* @param f 属性对象* @param value rs结果集中返回的string值* @return 返回属性对象的值*/public static Object convert(Field f, String value) {if (value == null)return null;Object obj = null;try {if (f.getType() == Date.class) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");java.util.Date date = sdf.parse(value);			// 把util日期转换成 sql 日期obj = new Date(date.getTime());} else if (f.getType() == Timestamp.class) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");java.util.Date date = sdf.parse(value);obj = new Timestamp(date.getTime());} else {// 属性对象 是Double Integer 之类的转型Class<?> type = f.getType();// getClass 得到本身类名路径 getType得到当前类型// System.out.println(type + "\t" + f.getClass() + "\t" + (type == f.getClass()));Constructor<?> con = type.getDeclaredConstructor(String.class);obj = con.newInstance(value);}			} catch (Exception e) {e.printStackTrace();}return obj;}/*** 封装的属性对象值可能是 各种类型滴 考虑转型...* @param f 要被赋值的属性对象* @param value 被转换的值* @return 转换属性对象对应类型的值*/public static Object convert(Field f, String[] value) {if (value == null || value.length == 0)return null;Object obj = null;try {if (f.getType() == Date.class) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");java.util.Date date = sdf.parse(value[0]);			// 把util日期转换成 sql 日期obj = new Date(date.getTime());} else if (f.getType() == Timestamp.class) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");java.util.Date date = sdf.parse(value[0]);obj = new Timestamp(date.getTime());} else if ((f.getType() == int.class || f.getType() == Integer.class) && value[0] != "") { // 判断提交的数不是空字符obj = new Integer(value[0]);} else if ((f.getType() == double.class || f.getType() == Double.class) && value[0] != "") {obj = new Double(value[0]);} else if (f.getType() == String.class && value[0] != "") {obj = value[0];} else if (f.getType() == Integer[].class) {Integer[] integer = new Integer[value.length];for (int i = 0; i < value.length; i++) {integer[i] = new Integer(value[i]);}obj = integer;} else if (f.getType() == int[].class) {int[] arr = new int[value.length];for (int i = 0; i < arr.length; i++) {arr[i] = Integer.parseInt(value[i]);}} else if ((f.getType() == boolean.class || f.getType() == Boolean.class) && value[0] != "") {if (value[0] == "y" || value[0] == "1" || value[0] == "true") {obj = true;} else {obj = false;}		}} catch (Exception e) {e.printStackTrace();}return obj;}}

3. 业务服务类使用适配器设计模式

  • 表现层接口
package com.lovely.mvc;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public interface Action {// service服务方法接口public String service(HttpServletRequest req, HttpServletResponse resp);}
  • 适配器实现接口
package com.lovely.mvc;import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;// 实体服务类规范
public class DispatcherAction implements Action {public String service(HttpServletRequest req, HttpServletResponse resp) {// 反射执行子类方法Class<?> c = this.getClass();// 请求方法String method = req.getParameter("method");String returnValue = "";try {// 反射拿到子类的方法对象Method methodObj = c.getDeclaredMethod(method, HttpServletRequest.class, HttpServletResponse.class);// 调用具体的方法returnValue = methodObj.invoke(this, req, resp).toString();		} catch (NoSuchMethodException e) {try {resp.sendError(404, method + "方法不存在...");} catch (IOException e1) {e1.printStackTrace();}} catch (SecurityException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}		return returnValue;}}
  • 作为使用者,使用服务类完成业务
package com.lovely.action;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import com.lovely.dao.CommonDao;
import com.lovely.entity.Ticket;
import com.lovely.mvc.DispatcherAction;public class TicketAction extends DispatcherAction {CommonDao dao = new CommonDao();// 查询public String queryAll(HttpServletRequest req, HttpServletResponse resp) {req.setAttribute("list", dao.queryAll(Ticket.class));return "/index.jsp";}// 会被核心控制器封装数据的 对象private Ticket t;// 新增票public String save(HttpServletRequest req, HttpServletResponse resp) {System.out.println(t);int count = dao.save(t);if (count > 0)return "/TicketAction.do?method=queryAll";return "/add.jsp";}// 根据id查询票public String findOneTicket(HttpServletRequest req, HttpServletResponse resp) {req.setAttribute("ticket", dao.queryOne(t));return "/update.jsp";}// 修改票public String update(HttpServletRequest req, HttpServletResponse resp) {int count = dao.update(t);if (count > 0)return "redirect:/TicketAction.do?method=queryAll";return "/TicketAction.do?method=findOneTicket";}// 删除票public String delete(HttpServletRequest req, HttpServletResponse resp) {int count = dao.delete(t);if (count > 0)return "/TicketAction.do?method=queryAll";else return "/TicketAction.do?method=queryAll";}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/420824.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

discuz中又拍云在ie8,chrome22下不能上传的问题

chrome22: 解决方法&#xff1a;http://www.baidufe.com/item/b17db6c1136a986b4272.html ie8&#xff1a;flash不能生成 重新安装flash player 14转载于:https://www.cnblogs.com/zhaozhilu/p/3807440.html

1013 数素数 (20分)

输入样例&#xff1a; 5 27 输出样例&#xff1a; 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 # -*- encoding: utf-8 -*- import mathdef get_primes(n):prime_list [1] * (n 1)for i in range(2, int(math.sqrt(n)) 1):if prime_list[i]…

Oracle 更新Opatch、打补丁

1.更新Opatch; 2.打补丁; 3.grid 打补丁; 1.更新Opatch(实验版本:oracle:11.2.0.3.0): 默认安装数据库后,在ORACLE_HOME 下会有个OPatch 文件夹,更新前先检查当前Opatch 版本: 1: [oraclesywu2 OPatch]$ ./opatch lsinventory 2: Invoking OPatch 11.2.0.1.7 3: 4: Ora…

jQuery学习--选择器的使用

jQuery基本选择器1. jQuery的ready事件 -> js的onload2. 选择器的使用1. jQuery的ready事件 -> js的onload 大多是第一种&#xff0c;匿名函数写法 <script type"text/javascript">// 匿名函数写法 ready 开始函数$(function() {// -> js的窗体加载事…

jQuery复选框多选问题

<html><head><title>work.html</title><script type"text/javascript" src"js/jquery-3.2.1.js"> </script><script type"text/javascript">$(function() { // 全选 / 全不选$($("#CheckedAll&…

1014 福尔摩斯的约会 (20分)

输入样例&#xff1a; 3485djDkxh4hhGE 2984akDfkkkkggEdsb s&hgsfdk d&Hyscvnm 输出样例&#xff1a; THU 14:04 # -*- coding: utf-8 -*- import stringweek {A: MON,B: TUE,C: WED,D: THU,E: FRI,F: SAT,G: SUN}hour {0:00, 1:01, 2:02, 3:03, 4:04, 5:05, 6:0…

MSSQL如何在没有主键的表中删除重复数据

MSSQL如何在没有主键的表中删除重复数据 原文:MSSQL如何在没有主键的表中删除重复数据为了对重复数据进行实验&#xff0c;下面建一个设计不太好&#xff08;没有主键&#xff09;表并插入了一些重复数据&#xff1a; create database testdbuse testdb ; go create table Dups…

jQuery 属性,css,文档操作

dom对象与jQuery对象的区别 $(function() {// dom 与 jQuery对象间的转换var $txt $(":input");// jQuery -> js// 取下标第0位var txt $txt[0];txt $txt.get(0);console.log(txt.value);txt document.getElementById("in1");// js -> jQuery$tx…

1015 德才论 (25分)

输入样例&#xff1a; 14 60 80 10000001 64 90 10000002 90 60 10000011 85 80 10000003 85 80 10000004 80 85 10000005 82 77 10000006 83 76 10000007 90 78 10000008 75 79 10000009 59 90 10000010 88 45 10000012 80 100 10000013 90 99 10000014 66 60 输出样例&#…

shell之文本过滤(grep)

shell之文本过滤&#xff08;grep&#xff09; 分类&#xff1a; linux shell脚本学习2012-09-14 14:17 588人阅读 评论(0) 收藏 举报shell正则表达式扩展工具存储grep&#xff08;全局正则表达式版本&#xff09;允许对文本文件进行模式查找。如果找到匹配模式&#xff0c; gr…

1016 部分A+B (15分)

输入样例 1&#xff1a; 3862767 6 13530293 3 输出样例 1&#xff1a; 399 输入样例 2&#xff1a; 3862767 1 13530293 8 输出样例 2&#xff1a; 0 # -*- coding: utf-8 -*-if __name__ __main__:input_list input().split()a, d_a, b, d_b input_list[0], input_li…

张小二:做一个幸福的胖子

最近听完了单田芳的大唐惊雷。秦琼病重&#xff0c;单田芳在评书中分析&#xff1a; 1.多次负伤 2.心机重&#xff0c;看不开&#xff0c;平时的状态都是一副严肃的表情&#xff1b; 在看程咬金&#xff1a; 每天笑哈哈&#xff0c;有着肥胖的身躯&#xff0c;看似憨厚&#xf…

IDEA2020安装

下载1 https://souyunku.lanzous.com/b0aki3kna 下载2 https://pan.baidu.com/s/1YF6o2M4PA3_97kEP4qCqGQ 提取码&#xff1a;kg7f把jar包往idea里面一丢&#xff0c;就可正常使用。

马哥学习笔记二十七——IO复用

I/O动作模式  阻塞 非阻塞 I/O复用 信号驱动 异步 转载于:https://www.cnblogs.com/wangyongbin/p/3817353.html

1017 A除以B (20分)

输入样例&#xff1a; 123456789050987654321 7 输出样例&#xff1a; 17636684150141093474 3 # -*- coding: utf-8 -*- import redef big_division(a, b):q_list, r [], 0len_a len(a)for i in range(0, len_a):dividend 10 * r eval(a[i])q_list.append(dividend // …

Idea创建web项目,配置tomcat服务器

使用idea创建web项目 新下载的idea&#xff0c;需要启用插件&#xff0c;才可创建web项目 启用Java ee&#xff0c;servlet有web项目选项 创建项目 选好jdk&#xff0c;要配置好jdk环境变量https://blog.csdn.net/crossing2012/article/details/81292547 选路径 to…

CSS 最核心的几个概念

本文将讲述 CSS 中最核心的几个概念&#xff0c;包含&#xff1a;盒模型、position、float等。这些是 CSS 的基础&#xff0c;也是最经常使用的几个属性&#xff0c;它们之间看似独立却又相辅相成。为了掌握它们&#xff0c;有必要写出来探讨一下&#xff0c;如有错误欢迎指正。…