從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;
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章