1.mvc概念
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,
它是一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码
2.MVC流程
3.代码展示
3.1实体类
package com.tanle.entity;
public class Job {
private String id;
private String job;
private String company;
private String address;
private String salary;
private String url;
private String limito;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getSalary() {
return salary;
}
public void setSalary(String salary) {
this.salary = salary;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getLimito() {
return limito;
}
public void setLimito(String limito) {
this.limito = limito;
}
public Job(String id, String job, String company, String address, String salary, String url, String limito) {
super();
this.id = id;
this.job = job;
this.company = company;
this.address = address;
this.salary = salary;
this.url = url;
this.limito = limito;
}
public Job() {
super();
}
@Override
public String toString() {
return "Job [id=" + id + ", job=" + job + ", company=" + company + ", address=" + address + ", salary=" + salary
+ ", url=" + url + ", limito=" + limito + "]";
}
}
3.2dao层
package com.tanle.dao;
import java.sql.SQLException;
import java.util.List;
import com.tanle.entity.Job;
import com.tanle.util.PageBean;
import com.tanle.util.StringUtils;
public class JobDao extends BaseDao<Job>{
//查询
public List<Job> list(Job job,PageBean pageBean) throws InstantiationException, IllegalAccessException, SQLException{
String sql="select * from t_solr_job where true";
//获取前台界面传过来的值
String company = job.getCompany();
//修改查询传值id
String id = job.getId();
if(StringUtils.isNotBlank(company)) {
sql+=" and company like '%"+company+"%'";
}
if(id != null) {
sql+=" and id='"+id+"'";
}
return super.executeQuery(sql, Job.class, pageBean);
}
//增加
public int add(Job job) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, SQLException {
String sql="insert into t_solr_job(id,job,company,address,salary,url,limito) values(?,?,?,?,?,?,?)";
return super.executeUpdate(sql, job, new String[] {"id","job","company","address","salary","url","limito"});
}
//修改
public int Edit(Job job) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, SQLException {
String sql="update t_solr_job set job=?,company=?,address=?,salary=?,url=?,limito=? where id=?";
return super.executeUpdate(sql, job, new String[] {"job","company","address","salary","url","limito","id"});
}
//增加
public int del(Job job) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, SQLException {
String sql="delete from t_solr_job where id=?";
return super.executeUpdate(sql, job, new String[] {"id"});
}
//测试
public static void main(String[] args) throws InstantiationException, IllegalAccessException, SQLException {
JobDao jobdao=new JobDao();
Job job=new Job();
PageBean pageBean=new PageBean();
List<Job> list = jobdao.list(job, pageBean);
for (Job j : list) {
System.out.println(j);
}
}
}
分页basedao
package com.tanle.dao;
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.tanle.entity.Book;
import com.tanle.util.DBAccess;
import com.tanle.util.PageBean;
import com.tanle.util.StringUtils;
public class BaseDao<T> {
public List<T> executeQuery(String sql,Class clz,PageBean pageBean) throws SQLException, InstantiationException, IllegalAccessException{
List<T> list=new ArrayList<T>();
Connection con = DBAccess.getConnection();
PreparedStatement ps=null;
ResultSet rs=null;
//查询符合条件的总记录数
if(pageBean !=null && pageBean.isPagination()) {
//分页 --列表需求
String countSql=getCountSql(sql);
ps=con.prepareStatement(countSql);
rs=ps.executeQuery();
if(rs.next()) {
//赋值总记录数
pageBean.setTotal(rs.getObject(1).toString());
}
//展示想要看到的数据
String pageSql=getPageSql(sql,pageBean);
ps=con.prepareStatement(pageSql);
rs=ps.executeQuery();
}else {//不分页 --下拉框需求
ps=con.prepareStatement(sql);
rs=ps.executeQuery();
}
while(rs.next()) {
//list.add(new Book(rs.getInt("bid"), rs.getString("bname"), rs.getFloat("price")));
//反射实例化对象
T t=(T) clz.newInstance();
Field[] declaredFields = clz.getDeclaredFields();
for (Field f : declaredFields) {
f.setAccessible(true);
f.set(t, rs.getObject(f.getName()));
}
list.add(t);
}
DBAccess.close(con, ps, rs);
return list;
}
//将普通sql转成查总记录数的sql
private String getCountSql(String sql) {
return "select count(1) from ("+sql+") t";
}
//
private String getPageSql(String sql,PageBean pageBean) {
// TODO Auto-generated method stub
return sql+" limit "+pageBean.getStartIndex()+","+pageBean.getRows();
}
//通用增删改
/**
*
* @param sql
* @param t book
* @param atters bid,bname,price
* @return
* @throws SQLException
* @throws SecurityException
* @throws NoSuchFieldException
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
public int executeUpdate(String sql,T t,String[] atters) throws SQLException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
Connection con = DBAccess.getConnection();
PreparedStatement ps=con.prepareStatement(sql);
int loop=1;
Field f=null;
//atter={"bid","bname","price"}
for (String atter : atters) {
f = t.getClass().getDeclaredField(atter);
f.setAccessible(true);
ps.setObject(loop++, f.get(t));
}
int code=ps.executeUpdate();
DBAccess.close(con, ps, null);
return code;
}
}
3.3web层
对dao方法进行调用
package com.tanle.web;
import java.sql.SQLException;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.tanle.dao.JobDao;
import com.tanle.entity.Job;
import com.tanle.framework.ActionSupport;
import com.tanle.framework.ModelDriven;
import com.tanle.util.PageBean;
public class JobServlet extends ActionSupport implements ModelDriven<Job>{
private JobDao jobDao=new JobDao();
private Job job=new Job();
public String add(HttpServletRequest req,HttpServletResponse resp){
try {
this.jobDao.add(job);
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "toList";
}
public String del(HttpServletRequest req,HttpServletResponse resp){
try {
this.jobDao.del(job);
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "toList";
}
public String toEdit(HttpServletRequest req,HttpServletResponse resp){
try {
List<Job> list = this.jobDao.list(job, null);
req.setAttribute("b", list);
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "toEdit";
}
public String Edit(HttpServletRequest req,HttpServletResponse resp){
try {
this.jobDao.Edit(job);
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "toList";
}
public String list(HttpServletRequest req,HttpServletResponse resp){
Job job=new Job();
job.setCompany(req.getParameter("company"));
PageBean pageBean=new PageBean();
pageBean.setRequest(req);;
try {
List<Job> list = this.jobDao.list(job, pageBean);
req.setAttribute("jobList", list);
req.setAttribute("pageBean", pageBean);
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "list";
}
@Override
public Job getModel() {
// TODO Auto-generated method stub
return job;
}
}
3.4核心部分
通过xml建模与反射实例化对象赋值获取属性
Action
package com.tanle.framework;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface Action {
String execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException;
}
ActionModel
package com.tanle.framework;
import java.util.HashMap;
import java.util.Map;
public class ActionModel {
private String path;
private String type;
private Map<String, ForwardModel> foMap=new HashMap<String, ForwardModel>();
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;
}
//两个行为
/**
* 将指定的forwardmodel压入当前actionModel对象中
*/
public void push(ForwardModel forwardmodel) {
foMap.put(forwardmodel.getName(),forwardmodel);
}
public ForwardModel pop(String name) {
return foMap.get(name);
}
}
ActionSupport
package com.tanle.framework;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ActionSupport implements Action{
/**
* 处理if分支问题
* 动态调用当前类的其他方法
* @throws SecurityException
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
@Override
public String execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
String methodName=req.getParameter("methodName");
//获取当前类
//this指的是bookAction
Method m = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
m.setAccessible(true);
//相当于动态调用del(req,resp)
return (String) m.invoke(this,req,resp);
}
}
ConfigModel
package com.tanle.framework;
import java.util.HashMap;
import java.util.Map;
public class ConfigModel {
private Map<String, ActionModel> acMap=new HashMap<String, ActionModel>();
/**
* 将指定的ActionModel压入当前ConfigModel对象中
* <action />放入config</config>
*/
public void push(ActionModel actionmodel) {
acMap.put(actionmodel.getPath(),actionmodel);
}
public ActionModel pop(String path) {
return acMap.get(path);
}
}
ConfigModelFactory
package com.tanle.framework;
import java.io.InputStream;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
* 23种设计模式之工厂模式
*
* 工厂模式解决的问题 ,将代码封装,提高代码的复用性
* 类比汉堡的获取方式(肯德基直接购买,原材料自己制作)
*
* 一般工厂类一定会有一个方法,就是生产指定模型对象的方法
*
* 拥抱变化
*
* 注意:
* 在工厂类中会有两个以上的构建方法:一个是默认框架路径的模型对象构建方法,
* 还有一个是动态读取 任意位置的框架配置文件
* build
* newInstance
* @author tanle
*
* http://www.javaxl.com
*/
public class ConfigModelFactory {
/**
* 通过资源文件构建对应的模型对象
* @param path 具体的资源文件
* @return
* @throws DocumentException
*/
public static ConfigModel build(String path) throws Exception {
//path="/config.xml"
//获取流对象
InputStream in = ConfigModelFactory.class.getResourceAsStream(path);
SAXReader reader=new SAXReader();
//config.xml里的内容
Document doc = reader.read(in);
//接下来把内容填充到configModel对象中(doc.asXML)
ConfigModel configModel=new ConfigModel();
ActionModel actionModel=null;
ForwardModel forwardModel=null;
List<Element> actionEles = doc.selectNodes("/config/action");
for (Element actionEle : actionEles) {
actionModel=new ActionModel();
actionModel.setPath(actionEle.attributeValue("path"));
actionModel.setType(actionEle.attributeValue("type"));
//给actionModel中放入forwardModel对象
//拿到forward标签内容
List<Element> forwardEles = actionEle.selectNodes("forward");
for (Element forwardEle : forwardEles) {
forwardModel=new ForwardModel();
forwardModel.setName(forwardEle.attributeValue("name"));
forwardModel.setPath(forwardEle.attributeValue("path"));
//redirect属性是boolean类型的
//需求只有config.xml中redirect属性值填写了false才代表转发
//forwardEle.attributeValue("redirect")获取到config中的redirect属性值
forwardModel.setRedis(!"false".equals(forwardEle.attributeValue("redirect")));
actionModel.push(forwardModel);
}
configModel.push(actionModel);
}
return configModel;
}
public static ConfigModel build() throws Exception {
return build("/mvc.xml");
}
public static void main(String[] args) throws Exception {
ConfigModel model = ConfigModelFactory.build();
/*ActionModel actionModel = model.pop("/regAction");
System.out.println(actionModel.getType());*/
//获取/regAction下的success结果码对应页面/login.jsp
System.out.println("asdasd");
/* ActionModel actionModel = model.pop("/loginAction");
System.out.println(actionModel.getType());
ForwardModel forwardModel = actionModel.pop("success");
System.out.println(forwardModel.getPath());*/
}
}
DispatcherServlet(中央控制器)
package com.tanle.framework;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
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;
@WebServlet(name="dispatcherServlet",urlPatterns="*.action")
public class DispatcherServlet extends HttpServlet{
/**
* 中央控制器
*/
private static final long serialVersionUID = 1L;
private ConfigModel configModel;
@Override
public void init() throws ServletException {
// TODO Auto-generated method stub
try {
//建模
configModel=ConfigModelFactory.build();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
//1.拿到请求路径
String uri = req.getRequestURI();
//截取
String path = uri.substring(uri.lastIndexOf("/"),uri.lastIndexOf("."));//book
//获取全路径名
ActionModel actionModel = configModel.pop(path);
if(actionModel == null) {
throw new RuntimeException(path+" action 标签没有配置");
}
//实例化处理网络请求的URL的类
try {
//action 相当于bookAction
Action action=(Action) Class.forName(actionModel.getType()).newInstance();
//动态封装参数
if(action instanceof ModelDriven) {
ModelDriven md=(ModelDriven) action;
//将前端jsp参数传递到后端的所有值封装到业务类模型中
BeanUtils.populate(md.getModel(), req.getParameterMap());
}
//动态调用方法
String code = action.execute(req, resp);
ForwardModel forwardModel= actionModel.pop(code);
//拿到path
String jspPath=forwardModel.getPath();
if(forwardModel.isRedis()) {
resp.sendRedirect(req.getServletContext()+jspPath);
}else {
req.getRequestDispatcher(jspPath).forward(req, resp);
}
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
ForwardModel
package com.tanle.framework;
public class ForwardModel {
private String name;
private String path;
private boolean redis;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public boolean isRedis() {
return redis;
}
public void setRedis(boolean redis) {
this.redis = redis;
}
public ForwardModel() {
}
public ForwardModel(String name, String path, boolean redis) {
this.name = name;
this.path = path;
this.redis = redis;
}
}
ModelDriven
package com.tanle.framework;
public interface ModelDriven<T> {
T getModel();
}
mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<config>
<action path="/job" type="com.tanle.web.JobServlet">
<forward name="list" path="/jobList.jsp" redirect="false" />
<forward name="toAdd" path="/jobAdd.jsp" redirect="" />
<forward name="toEdit" path="/jobEdit.jsp" redirect="false" />
<forward name="toList" path="/job.action?methodName=list" redirect="" />
</action>
</config>
4效果图
5总结
主控制器:查看是否有对应的子控制器来处理用户请求,如果就调用子控制器来处理请求
没有就报错,就处理不了请求。子控制器:就是处理用户请求用的