从IO 到框架(5)-手写简单框架

手写简单框架,对上篇"从IO 到框架(4)-Servlet + JDBC (Idea Maven)" 的第一次迭代。

1)控制层:

核心思想:使用反射、泛型和注解技术设计通用(批量处理) 的工具类。

反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性,这种动态获取信息以及动态调用对象的方法的功能称为java语言的反射机制。一直以来反射技术都是Java中的闪亮点,这也是目前大部分框架(如Spring / Mybatis等)得以实现的支柱。在Java中,Class类与java.lang.reflect类库一起对反射技术进行了全力的支持。

  • 简化事件分发步骤
  • 简化页面提交参数获取
  • 参数列表的简化
  • 跳转的简化 - 默认就是转发,重定向加上前缀 "redirect:"
public class BaseServlet extends HttpServlet {
	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//处理事件分发
		String method = request.getParameter("method");
		if (method == null) {
			System.out.println("method Can't be null!");
			return;
		}
		/* 获得其Class 实例的三种方法:1)通过被页面调用的servlet 的实例,这是Class类从Object 继承的方法
		2)通过Class的静态方法Class.forName(String className), 可用配置文件
		3)Class字面常量  类名.class
		其中实例类的getClass方法和Class类的静态方法forName都将会触发类的初始化阶段,
		而字面常量获取Class对象的方式则不会触发初始化。*/
		Class<? extends BaseServlet> aClass = this.getClass();
		Method[] methods = aClass.getMethods();
		for (Method m : methods) {
			int modifiers = m.getModifiers();
			if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers)) {
				if (m.getName().equals(method)) {
					Login l = m.getAnnotation(Login.class);
					Object obj = request.getSession().getAttribute("user");
					if (l == null || (l != null && obj != null)) {

						Object[] params = getParams(request, response, m);
						try {
							String result = (String) m.invoke(this, params);
							if (result != null) {
								if (result.startsWith("redirect:")) {
									response.sendRedirect(result.split(":")[1]);
								} else {
									request.getRequestDispatcher(result).forward(request, response);
								}
							}
						} catch (IllegalAccessException e) {
							e.printStackTrace();
						} catch (InvocationTargetException e) {
							e.printStackTrace();
						}
					}else{
						String url = request.getRequestURI();
						url += "?" + request.getQueryString();
						response.sendRedirect("front/login.jsp?gotourl=" + url);
					}
				}
			}
		}
	}

	private Object[] getParams(HttpServletRequest request, HttpServletResponse response, Method m) throws IOException {
		List<Object> list = new ArrayList<>();
		Class<?>[] types = m.getParameterTypes();
		for (Class<?> type : types) {
			if (type == HttpServletRequest.class) {
				list.add(request);
			} else if (type == HttpServletResponse.class) {
				list.add(response);
			} else if (type == HttpSession.class) {
				list.add(request.getSession());
			} else if (type == PrintWriter.class) {
				list.add(response.getWriter());
			} else if (type.isAnnotationPresent(Entity.class)) {
				list.add(parseRequest(request, type));
			} else if (type == Page.class) {
				//@Rock 此处Goods 写死了,记得修改
				Page<Goods> pageObj = new Page<>();
				String page = request.getParameter("page");
				if (page == null) {
					pageObj.setPage(1);
				} else {
					pageObj.setPage(Integer.parseInt(page));
				}
				String uri = request.getRequestURI();
				pageObj.setUrl(uri);
				String params = request.getQueryString();
				if (params != null && params.trim() != "") {
					if (params.lastIndexOf("page") != -1) {
						params = params.substring(0, params.lastIndexOf("page") - 1);
					}
				} else {
					params = "1=1";
				}
				pageObj.setParams(params);
				list.add(pageObj);
			} else {
				list.add(null);
			}
		}
		return list.toArray();
	}

	public <T> T parseRequest(HttpServletRequest request, Class<T> cls) {
		T t = null;
		try {
			t = cls.newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}

		Field[] fields = cls.getDeclaredFields();
		for (Field field : fields) {
			int modifiers = field.getModifiers();
			if (Modifier.isPrivate(modifiers) && !Modifier.isStatic(modifiers) && !Modifier.isFinal(modifiers)) {
				field.setAccessible(true);
				String value = request.getParameter(field.getName());
				if (value != null) {
					Object v = null;
					Format annotation = field.getAnnotation(Format.class);
					if (annotation != null) {
						RequestTypeHandler<?> typeHandler = null;
						try {
							typeHandler = annotation.value().newInstance();
						} catch (InstantiationException e) {
							e.printStackTrace();
						} catch (IllegalAccessException e) {
							e.printStackTrace();
						}
						v = typeHandler.string2Field(value);
					} else {
						if (field.getType() == String.class) {
							v = value;
						} else if (field.getType() == int.class || field.getType() == Integer.class) {
							v = Integer.parseInt(value);
						} else if (field.getType() == Double.class || field.getType() == double.class) {
							v = Double.parseDouble(value);
						} else if (field.getType() == Float.class || field.getType() == float.class) {
							v = Float.parseFloat(value);
						} else if (field.getType() == Short.class || field.getType() == short.class) {
							v = Short.parseShort(value);
						} else if (field.getType() == Boolean.class || field.getType() == boolean.class) {
							v = Boolean.parseBoolean(value);
						} else if (field.getType() == Long.class || field.getType() == long.class) {
							v = Long.parseLong(value);
						} else if (field.getType() == Character.class || field.getType() == char.class) {
							v = value.toCharArray()[0];
						} else if (field.getType() == Byte.class || field.getType() == byte.class) {
							v = Byte.parseByte(value);
						}
					}
					try {
						field.set(t, v);
					} catch (IllegalAccessException e) {
						e.printStackTrace();
					}
				}
			}
		}
		return t;
	}
}

2)持久层:将常用操作的增删改查封装在一个工具类

public class BaseDaoImpl {

	public int insert(String sql, Object... params) {
		Connection conn = ConnectionUtil.getConnection();
		PreparedStatement ps = null;
		try {
			ps = conn.prepareStatement(sql);
			for (int i = 0; i < params.length; i++) {
				ps.setObject(i + 1, params[i]);
			}
			int result = ps.executeUpdate();
			if (result > 0) {
				ResultSet rs = ps.getGeneratedKeys();
				if (rs.next()) {
					return rs.getInt(1);
				}
			}
			return result;
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			ConnectionUtil.close(conn, ps, null);
		}
		return 0;
	}

	public int update(String sql, Object... params) {
		Connection conn = ConnectionUtil.getConnection();
		PreparedStatement ps = null;
		try {
			ps = conn.prepareStatement(sql);
			for (int i = 0; i < params.length; i++) {
				ps.setObject(i + 1, params[i]);
			}
			return ps.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			ConnectionUtil.close(conn, ps, null);
		}
		return 0;
	}

	public <T> List<T> queryAll(String sql, Class<T> tcls, Object... params) {
		Connection conn = ConnectionUtil.getConnection();
		PreparedStatement ps = null;
		ResultSet rs = null;
		List<T> list = new ArrayList<>();
		try {
			ps = conn.prepareStatement(sql);
			for (int i = 0; i < params.length; i++) {
				ps.setObject(i + 1, params[i]);
			}
			rs = ps.executeQuery();
			while (rs.next()) {
				T t = null;
				try {
					t = tcls.newInstance();
				} catch (Exception e) {
					e.printStackTrace();
				}
				Field[] fields = tcls.getDeclaredFields();
				for (Field field : fields) {
					try {
						field.setAccessible(true);
						Object o = rs.getObject(field.getName());
						field.set(t, o);
					} catch (Exception e) {
					}
				}
				list.add(t);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			ConnectionUtil.close(conn, ps, rs);
		}
		return list;
	}

	public <T> T queryOne(String sql, Class<T> tcls, Object... params) {
		List<T> ts = queryAll(sql, tcls, params);
		return ts != null && ts.size() > 0 ? ts.get(0) : null;
	}

	public ResultSet query(String sql, Object... params) throws SQLException {
		Connection conn = ConnectionUtil.getConnection();
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			ps = conn.prepareStatement(sql);
			for (int i = 0; i < params.length; i++) {
				ps.setObject(i + 1, params[i]);
			}
			rs = ps.executeQuery();
			RowSetFactory rowSetFactory = RowSetProvider.newFactory();
			CachedRowSet cachedRowSet = rowSetFactory.createCachedRowSet();
			cachedRowSet.populate(rs);
			return cachedRowSet;
		} finally {
			ConnectionUtil.close(conn, ps, rs);
		}
	}

	public <T> Page<T> queryByPage(Page<T> pageObj, Class<T> cls, String sql, Object... params) throws SQLException {
		sql = sql.toLowerCase();
		String sqlcount = "select count(*) " + sql.substring(sql.indexOf("from"));
		ResultSet rs = query(sqlcount, params);
		int sum = 0;
		if (rs.next()) {
			sum = rs.getInt(1);
		}
		pageObj.setPageSum(sum);
		pageObj.setPageCount((sum - 1) / pageObj.getPageSize() + 1);

		List<Object> list = new ArrayList<>();
		for (Object param : params) {
			list.add(param);
		}
		list.add((pageObj.getPage() - 1) * pageObj.getPageSize());
		list.add(pageObj.getPageSize());
		sql = sql + " limit ?,?";
		List<T> ts = queryAll(sql, cls, list.toArray());
		pageObj.setDatas(ts);
		return pageObj;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值