1.思维导图:
?
2.解决框架配置文件名及放置问题:
?2.1 中央控制器代码:
package com.huangdeng.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 org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import com.huangdeng.web.GoodsAction;
/**
* 目标:
* 根据自定义MVC框架的原理图完成 框架的研发
*
* @author zjjt
*
* 中央控制器
* 目标:寻找子控制器
*
*/
/*@WebServlet("*.action")*/
public class DispatchServlet extends HttpServlet {
//专门存放子控制器的容器
private ConfigModel configModel = null;
//初始化子控制器容器(集合),经过初始化,actions容器内部就有了子控制器
/*
* 需求:
* 在增加一个商品类的增删改查
* 步骤:
* 改动init中代码
* 思考:
* 能不能不改动代码完成这个需求
* 1.参考DBAcess的数据源配置文件config.prooerties
* 1.1 减少代码改动风险性
* 1.2 减少代码的编译次数(对于已经部署到服务器后)
* 解决方案:
* 改成子控制器可配置
* 解决步骤:
* 1.必须有配置文件config.xml
* 2.配置文件config.xml中要包含处理业务的子控制器
* 3.读取到配置文件config.xml中的对应的处理浏览器请求的子控制器
* 编码:
*
*/
@Override
public void init() throws ServletException {
//缺陷:需要改动原有代码,伴随着很大的风险
try {
//配置的位置:web.xml
String configurationLocation = this.getInitParameter("configurationLocation");
if(configurationLocation==null || "".equals(configurationLocation)) {
configurationLocation="/zking.xml";
}
configModel=ConfigModelFactory.build(configurationLocation);
} catch (Exception e) {
e.printStackTrace();
}
}
@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/t266_mvc/book.action?methodName=add
//目标:BookAction.add()...
/*
* 思路:
* 1.从浏览器URL中获取到“book”字符串
* 2.在子控制器容器中拿到BookAction
* 3.BookAction.add()
*/
/*
* Debug的使用效果:
* 1.调试代码(找错)
* 2.观看\观察代码的一个流程走向,每一个参数的值
*/
String uri = req.getRequestURI();
uri = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));
ActionModel actionModel = configModel.pop(uri);
String type = actionModel.getType();
ActionSupport action;
try {
//放射实例化
action = (ActionSupport) Class.forName(type).newInstance();
//ActionSupport action=new BookAction();
if(action instanceof ModelDriver) {
ModelDriver m=(ModelDriver) action;
Object obj = m.getModel();
//有对象
//接收所有的前端jsp传递到后台的参数
Map<String, String[]> parameterMap = req.getParameterMap();
//给对象赋值
//PropertyUtils.getProperty(obj, "");
BeanUtils.populate(obj, parameterMap);
}
//execute->delete
String res = action.execute(req, resp);
/*
* 思路:
* 1.方法执行宪法完毕必须有一个返回值
* 2.通过返回值决定是否重定向还是转发
* 3.通过返回值决定跳转那一页
*/
ForwardModel forwardModel = actionModel.pop(res);
if(forwardModel.isRedirect()) {
//重定向
resp.sendRedirect(req.getContextPath()+forwardModel.getPath());
}
else {
//转发
req.getRequestDispatcher(forwardModel.getPath()).forward(req, resp);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
?2.1 配置文件代码:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>J2ee13</display-name>
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>com.tyf.framework.DispatchServlet</servlet-class>
<init-param>
<param-name>configurationLocation</param-name>
<param-value>/mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>
3.通用的增删改:
3.1 BaseDao代码:
package com.huangdeng.util;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.huangdeng.util.DBAccess;
import com.huangdeng.util.PageBean;
import com.huangdeng.util.StringUtils;
/**
* 所有Dao层的父类
*
* @param zjjt
*/
public class BaseDao<T> {
/**
* 通用的增删改
* @param sql 具体的增删改SQL
* @param t 具体要操作的表对应实体类
* @param attrs 具体操作表的某些字段对应的实体类属性
* @throws Exception
*/
public void executeUpdate(String sql, T t, String[] attrs) throws Exception {
//?->sid;?->sname;?->remark;
//attrs = new String[] {"sid","sname","remark"};
Connection con = DBAccess.getConnection();
PreparedStatement pst = con.prepareStatement(sql);
/*pst.setObject(1, student.getSid());
pst.setObject(2, student.getSname());
pst.setObject(3, student.getRemark());*/
//遍历
for (int i = 0; i < attrs.length; i++) {
//attrs[0]=sid;attrs[1]=sname;
Field f = t.getClass().getDeclaredField(attrs[i]);
f.setAccessible(true);
//f.get(t); sid.get(student)
pst.setObject(i+1, f.get(t));
}
pst.executeUpdate();
}
/**
* 通用分页查询
* @param sql
* @param clz
* @return
* @throws Exception
*/
public List<T> executeQuery(String sql,Class<T> clz,PageBean pageBean) throws Exception{
List<T> list = new ArrayList<T>();
Connection con = DBAccess.getConnection();;
PreparedStatement pst = null;
ResultSet rs = null;
/*
* 是否需要分页?
*/
if(pageBean != null && pageBean.isPagination()) {
String countSQL = getCountSQL(sql);
pst = con.prepareStatement(countSQL);
rs = pst.executeQuery();
if(rs.next()) {
pageBean.setTotal(String.valueOf(rs.getObject(1)));
}
// pageSql=sql limit (page-1)*rows,rows 对应某一页的数据
// countSql=select count(1) from (sql) t 符合条件的总记录数
String pageSQL = getPageSQL(sql,pageBean);//符合条件的某一页数据
pst = con.prepareStatement(pageSQL);
rs = pst.executeQuery();
}else {
//不分页
pst = con.prepareStatement(sql);//符合条件的所有数据
rs = pst.executeQuery();
}
while (rs.next()) {
T t = clz.newInstance();
Field[] fields = clz.getDeclaredFields();
for (Field f : fields) {
f.setAccessible(true);
f.set(t, rs.getObject(f.getName()));
}
list.add(t);
}
return list;
}
/**
* 将原SQL转换成符合条件的总记录数countSQL
* @param sql
* @return
*/
private String getCountSQL(String sql) {
// countSql=select count(1) from (sql) t 符合条件的总记录数
return "select count(1) from ("+sql+") t";
}
/**
* 将原SQL转换成pageSQL
* @param sql
* @param pageBean
* @return
*/
private String getPageSQL(String sql,PageBean pageBean) {
// (this.page - 1) * this.rows
// pageSql=sql limit (page-1)*rows,rows
return sql + " limit "+ pageBean.getStartIndex() +","+pageBean.getRows();
}
}
3.3 子控制器
package com.huangdeng.web;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.huangdeng.dao.StudentDao;
import com.huangdeng.entity.Student;
import com.huangdeng.framework.ActionSupport;
import com.huangdeng.framework.ModelDriver;
import com.huangdeng.util.PageBean;
/**
* 子控制器
* @author zjjt
*
*/
public class StudentAction extends ActionSupport implements ModelDriver<Student>{
//操作的实体类定义在外面
private Student student=new Student();
private StudentDao studentDao=new StudentDao();
@Override
public Student getModel() {
return student;
}
public String add(HttpServletRequest req, HttpServletResponse resp) {
try {
studentDao.add(student);
} catch (Exception e) {
e.printStackTrace();
}
return "toList";
}
public String delete(HttpServletRequest req, HttpServletResponse resp) {
try {
studentDao.delete(student);
} catch (Exception e) {
e.printStackTrace();
}
return "toList";
}
public String edit(HttpServletRequest req, HttpServletResponse resp) {
try {
studentDao.edit(student);;
} catch (Exception e) {
e.printStackTrace();
}
return "toList";
}
public String list(HttpServletRequest req, HttpServletResponse resp) {
PageBean pageBean=new PageBean();
pageBean.setRequest(req);
try {
List<Student> list = studentDao.list(student, pageBean);
req.setAttribute("students", list);
req.setAttribute("pageBean", pageBean);
} catch (Exception e) {
e.printStackTrace();
}
return "list";
}
public String toEdit(HttpServletRequest req, HttpServletResponse resp) {
//如果跳转的新增界面 无需查询,如果跳转的是修改界面,需要查询当前sid对应的数据,回显到界面
if(student.getSid()!=0) {//修改
try {
List<Student> list = studentDao.list(student, null);//根据id查询,有且只有一条数据
req.setAttribute("b", list.get(0));
} catch (Exception e) {
e.printStackTrace();
}
}
return "toEdit";
}
}
|