J2EE
目录
J2EE
1、什么是mvc
2、mvc组成部分
3、搭建mvc(代码)
1、中央控制器:DispathServlet
2、模型驱动:ModelDriver
3、子控制器接口:Action
4、增强子控制器:ActionSupport
5、具体子控制器案例BookServlet
6、Dao层
7、XML配置文件
8、web.xml
4、界面效果图
5、mvc的执行流程
1、简单流程,首先大致感受一下他的流程
2、详细流程,建议按照这个流程图来理解每个类之间的关系和作用,是如何构成mvc的。
6、总结:
1、什么是mvc
全名 :Model View Controller,模型视图控制器,是一种软件设计的典范。
用业务逻辑、数据和界面显示分离的方法来组织代码,在需要程序进行改动时不需要重新修改代
码,达到减少代码的作用。
我的理解 :不适用mvc我们会创建很多个servlet分别来实现增加,删除...操作,各司其职。mvc就
像是一个通用的servlet,其中组成有一个中央控制器,根据我们的请求不同来实现不同的业务逻
辑。前端的请求进入mvc进过一系列处理(取数据并不和中央控制器产生联系)之后将结果反馈给
界面。很明显的诠释了业务逻辑,数据和显示界面分离这句话。
2、mvc组成部分
①XML模型ConfigModelFactory :面对对象的思想操作我们的XML文件,修改XML来实现不同的逻辑。
②中央控制器DispathServlet :处理所有请求,分配给具体的子控制器实现业务。
③子控制器Action (接口):对子控制器的一种约束。
④增强子控制器ActionSupport :所有具体子控制器的父类,实现Action接口。
⑤模型驱动ModelDriver (泛型接口):具体的子控制器实现后实现返回子控制指定类型的对象,在中央控制器
中使用BeanUtils类对具体的子控制器类中定义的对象通过请求对象req进行初始化。
3、搭建mvc(代码)
1、中央控制器:DispathServlet
package com.zwf.mvc;
import java.io.IOException;
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;
/**
* 中央控制器
* 作用:可以解决所有类型的请求,和浏览器直接关联
* @author zjjt 隔壁程序员老张
*
*/
@WebServlet("*.action")
public class DispathServlet extends HttpServlet{
/**
* XML配置文件模型
*/
private ConfigModel configModel=null;
/**
* XML配置文件模型的初始化
* ②
*/
@Override
public void init() throws ServletException {
String configurationlocation = this.getInitParameter("configurationlocation");
try {
if(configurationlocation != null && !configurationlocation.equals("")) {
configModel = ConfigModelFactory.build(configurationlocation);
}else {
configModel = ConfigModelFactory.build();
}
} 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 {
//①
String URL = req.getRequestURI();//获取请求路径
URL = URL.substring(URL.lastIndexOf("/"),URL.lastIndexOf("."));//截取子控制器名称
ActionModel actionModel = configModel.pop(URL);//模型中获取子控制器模型
String type = actionModel.getType();//获得子控制器全路径名
ActionSupport action = null;//定义子控制器父类
try {
//③
action = (ActionSupport) Class.forName(type).newInstance();//强转
if(action instanceof ModelDriver) {//如果该子控制器实现了模型驱动接口
ModelDriver m = (ModelDriver) action;//强转
Object bean = m.getModel();//获得子控制器传入的对象
//请求的所有参数对对象进行初始化
BeanUtils.populate(bean, req.getParameterMap());
}
//④
String res = action.execute(req, resp);//执行方法并且获得ForwardModel名称
//⑤
ForwardModel forwardModel = actionModel.pop(res);//获取ForwardModel
String path = forwardModel.getPath();//获得跳转路径
boolean isRedirect = forwardModel.isRedirect();
//⑥
if(isRedirect) {//重定向
resp.sendRedirect(req.getContextPath()+path);
}else {//转发
req.getRequestDispatcher(path).forward(req, resp);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
2、模型驱动:ModelDriver
package com.zwf.mvc;
/**
* 模型驱动,由具体的子控制器实现,在中央控制器中来对具体的子控制器中的对象初始化。
* @author zjjt 隔壁程序员老张
*
* @param <T>
*/
public interface ModelDriver <T> {
T getModel();
}
3、子控制器接口:Action
package com.zwf.mvc;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 子控制器接口,对子控制器的行为约束。也是属于mvc中的一个规范
* @author zjjt 隔壁程序员老张
*
*/
public interface Action {
String execute(HttpServletRequest req,HttpServletResponse res);
}
4、增强子控制器:ActionSupport
package com.zwf.mvc;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 所有子控制器的父类
* 实现子控制器接口Action,表示所有的子控制器必须具备execute方法,是对子控制器的行为约束
* 具体子控制器与Dao层相关
* @author zjjt 隔壁程序员老张
*
*/
public class ActionSupport implements Action{
/**
* 获得请求参数方法名称methodName,然后反射动态调用具体子类的methodName方法
*/
@Override
public String execute(HttpServletRequest req, HttpServletResponse resp) {
String methodName = req.getParameter("methodName");
String res = null;
try {
Method m = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
m.setAccessible(true);
res =(String) m.invoke(this, req, resp);
} catch (Exception e) {
e.printStackTrace();
}
return res;
}
中央控制器中通过反射实例化具体子对象,由于不知道会是哪一个子控制器,所以创建一个父类接收,事实上是子控制器本身。因此在Actionsupport类中反射调用方法是调用反射调用具体子控制器的方法。XML模型类就不列出来了,在XML建模有相关的模型类。
5、具体子控制器案例BookServlet
package com.servlet.zwf;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.dao.zwf.BookDao;
import com.entity.zwf.Book;
import com.util.zwf.PageBean;
import com.zwf.mvc.ActionSupport;
import com.zwf.mvc.ModelDriver;
/**
* 书籍控制器
* @author zjjt 隔壁程序员老张
*
*/
public class BookServlet extends ActionSupport implements ModelDriver<Book>{
/**
* 需要通过请求进行初始化的书籍对象,一下的业务逻辑都将使用该对象进行处理。因为是来自用户请求进行初始化的对象。
*/
private Book b=new Book();
/**
* 书籍Dao层对象
*/
BookDao bd=new BookDao();
/**
* 实现模型驱动接口重写的方法,返回对象b在中央控制器中有请求进行初始化
*/
@Override
public Book getModel() {
return b;
}
/**
* 增加书籍方法
* @param req 前端请求对象
* @param resp 前端响应对象
* @return XML文件中forward标签名,决定后续的转发或者重定向的地址
*/
public String add(HttpServletRequest req, HttpServletResponse resp) {
try {
bd.add(b);
} catch (Exception e) {
e.printStackTrace();
}
return "toList";
}
/**
* 修改书籍方法,调用单个查询方法
* @param req
* @param resp
* @return
*/
public String toEdit(HttpServletRequest req, HttpServletResponse resp){
try {
b = bd.getOne(b);
} catch (Exception e) {
e.printStackTrace();
}
req.setAttribute("b", b);
return "toEdit";
}
/**
* 查询方法,将数据都放入请求中再根据XML决定跳转地址然后进行数据显示
* @param req
* @param resp
* @return
*/
public String list(HttpServletRequest req, HttpServletResponse resp){
PageBean p=new PageBean();//创建PageBean对象
p.init(req);//初始化PageBean
List<Book> all=null;//数据容器
try {
all = bd.getAll(Book.class, p, b);//调用方法
} catch (Exception e) {
e.printStackTrace();
}
req.setAttribute("books", all);//将数据放入请求中
req.setAttribute("pageBean", p);
return "list";
}
/**
* 修改方法
* @param req
* @param resp
* @return
*/
public String edit(HttpServletRequest req, HttpServletResponse resp) {
try {
bd.edit(b);
} catch (Exception e) {
e.printStackTrace();
}
return "toList";
}
/**
* 删除方法
* @param req
* @param resp
* @return
*/
public String del(HttpServletRequest req, HttpServletResponse resp) {
try {
bd.del(b);
} catch (Exception e) {
e.printStackTrace();
}
return "toList";
}
}
6、Dao层
package com.dao.zwf;
import java.util.List;
import com.entity.zwf.Book;
import com.util.zwf.PageBean;
/**
* 书籍Dao层
* @author zjjt 隔壁程序员老张
*
*/
public class BookDao extends BookBase<Book>{
public List<Book> getAll(Class<Book> clz, PageBean p ,Book b) throws Exception {
String sql="select * from t_mvc_book";
String key = "";
String bname=b.getBname();
if(bname != null) {
sql+=" where bname like ?";
key=bname;
}
return super.getAll(sql, clz, p, key);
}
public void add(Book b) throws Exception {
String sql="insert into t_mvc_book values(?,?,?)";
String attr[]= {"bid","bname","price"};
super.executeUpdate(sql, b, attr);
}
public void del(Book b) throws Exception {
String sql="delete from t_mvc_book where bid="+b.getBid();
System.out.println(sql);
super.executeUpdate(sql, b, null);
}
public Book getOne(Book b) throws Exception {
String sql="select * from t_mvc_book where bid="+b.getBid();
return super.getAll(sql, Book.class, null, "").get(0);
}
public void edit(Book b) throws Exception {
String sql="update t_mvc_book set bname=?,price=? where bid="+b.getBid();
String attr[]= {"bname","price"};
super.executeUpdate(sql, b, attr);
}
}
7、XML配置文件
<?xml version="1.0" encoding="UTF-8"?>
<config>
<!--
在这里每加一个配置,就相当于actions.put("/goods", new GoodsAction());
这样就解决了代码灵活性的问题
-->
<action path="/book" type="com.servlet.zwf.BookServlet">
<forward name="list" path="/index.jsp" redirect="false" />
<forward name="toEdit" path="/bookEdit.jsp" redirect="false" />
<forward name="toList" path="/book.action?methodName=list" redirect="true" />
</action>
<action path="/goods" type="com.zking.web.GoodsAction">
<forward name="failed" path="/login.jsp" redirect="false" />
<forward name="success" path="/main.jsp" redirect="true" />
</action>
<action path="/order" type="com.zking.web.OrderAction">
<forward name="failed" path="/login.jsp" redirect="false" />
<forward name="success" path="/main.jsp" redirect="true" />
</action>
</config>
8、web.xml
<?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>MVC</display-name>
<servlet>
<servlet-name>DispathServlet</servlet-name>
<servlet-class>com.zwf.mvc.DispathServlet</servlet-class>
<init-param>
<param-name>configurationlocation</param-name>
<param-value>/mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DispathServlet</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>
4、界面效果图
具体的操作和之前的增删改查无异,但是底层发生了变化,mvc版本。
5、mvc的执行流程
1、简单流程,首先大致感受一下他的流程
2、详细流程,建议按照这个流程图来理解每个类之间的关系和作用,是如何构成mvc的。
强烈推荐图和代码结合学习,跟着这个流程来理解学习上面的代码。
流程讲解 :
首先是用户进入主界面需要看到所有的数据,用户请求会被中央控制器拦截然后进行处理。
首先截取请求路径中的 /book ,拿到对应的action模型,得到对应的子控制器的全路径名,反
射实例,使用增强子控制器说明实例化。调用execute()方法,子控制器调用Dao层进行数据
操作。如果BookServlet执行的是list(),返回“list”,然后通过该字符串得到对应的forward模
型,拿到path,和redirect的值,再进行转发或者重定向处理。
6、总结:
再反过来想,以前每需要一个add或者del操作等都需要定义一个servlet,而且每一个servlet中都有
获取请求参数然后实例化成对象再进入Dao层进行处理数据,还要定义转发或者重定向。学习了
mvc之后,之前每写一个servlet都需要写一次获得请求参数然后构建具体对象(mvc由模型确定进
行一次性赋值创建,该对象在子控制器中已经定义好),然后用该对象进行Dao层方面的操作
(mvc由子控制器进行方法调用,由增强子控制器截取请求参数决定反射调用哪个方法),再将需
要的数据设置在请求对象中(mvc中由具体的子控制器完成),最后转发或者重定向到要跳转的对
象(mvc由中央控制器通过xml文件配置判断转发还是重定向)。如果有100个servlet,就要编写
100次上述操作,但是拥有mvc之后,我们仅仅只需要编写我们的xml文件来完成不同的业务逻辑。
通用分页是PageBean为核心点,从头到尾都有它在,自定义mvc则是req请求对象全程都在。
|