学习目标:
1、掌握并理解自定义的三层架构
学习过程:
要实现上面这个MVC框架,我们需要新建立一个项目,在这个项目里,我们已经实现了dao层的框架,数据库自己根据jdbc.properties建立一个。项目源码下载:
一、建立中转站——核心的servlet类。现在我们建立一个包com.mvc,在这个包下面建立一个ActionServlet。
public class ActionServlet extends HttpServlet {
// 初始化方法
public void init() throws ServletException {
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);// 调用doget方法
}
}
由于这个servlet将会拦截所有需要进入后台控制器(我们现在成为Action类),这里我们约定所有的Action的url访问路径的后缀名是do,当然你也可以约定其他的。所以在web.xml的配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name></display-name>
<servlet>
<servlet-name>ActionServlet</servlet-name>
<servlet-class>com.mvc.ActionServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ActionServlet</servlet-name>
<!-- 凡是以.do后缀名才拦截 -->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
二、设计配置文件。我们需要一个配置文件沟通url、action控制类和执行方法的文件,一般配置文件我们会使用xml进行配置,我们在src目录下建立一个actions.xml文件。文件的内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<actions>
<action url="listtypes" clz="com.action.GoodsTypesAction" method="listGoodsTypes"></action>
</actions>
三、解析xml。接下来我们需要解析这个xml并把信息保存在服务器的内容中,为了保证运行效率,这个xml只会解析一次,所以我们在核心类ActionServlet的初始化方法中解析。为了解析后能保存,我们在com.mvc包中设计一个Action类与xml对应。
public class Action {
private String url;
private String clz;
private String method;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getClz() {
return clz;
}
public void setClz(String clz) {
this.clz = clz;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
}
在类ActionServlet中解析actions.xml,解析xml我们之前讲过有多种方式,这里我们使用dom4j,所以首先,我们需要先导入dom4j包。然后修改ActionServlet代码如下:
public class ActionServlet extends HttpServlet {
Map<String, Action> actions = new HashMap<String, Action>();//记录配置文件信息
public void init() throws ServletException {
// 读取所有的配置信息
SAXReader saxReader = new SAXReader();
try {
Document document = saxReader.read(this.getClass().getClassLoader()
.getResourceAsStream("actions.xml"));
Element rootElement = document.getRootElement();
List<Element> actionElements = rootElement.elements("action");
for (Element actionElement : actionElements) {
Action action = new Action();
String url = actionElement.attributeValue("url");
String clz = actionElement.attributeValue("clz");
String method = actionElement.attributeValue("method");
action.setUrl(url);
action.setClz(clz);
action.setMethod(method);
actions.put(url, action);
}
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);// 调用doget方法
}
}
四、反射执行action的方法。接下来我们可以使用反射的技术调用Action的方法就行了。因为所有Action都必须有request和response这个两个变量,所以这里我们就在com.mvc包下设计一个BaseAction类。代码如下:
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public abstract class BaseAction {
protected HttpServletRequest request;
protected HttpServletResponse response;
public void setRequest(HttpServletRequest request) {
this.request = request;
}
public void setResponse(HttpServletResponse response) {
this.response = response;
}
}
同时修改ActionServlet的goGet方法,代码如下:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 1、获得用户的url
String url = request.getServletPath();
url = url.substring(1, url.lastIndexOf("."));
// 2、根据url从配置文件获得对应Action和method
Action action = actions.get(url);
// 3、执行Action和method
try {
Class clazz = Class.forName(action.getClz());
BaseAction baseAction = (BaseAction) clazz.newInstance();
baseAction.setRequest(request);
baseAction.setResponse(response);
Method method = clazz.getDeclaredMethod(action.getMethod());
// 4、根据返回值跳去其他页面
method.invoke(baseAction);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
五、完成跳转。下面我们还差跳转这一步。我们在com.mvc包中专门设计一个跳转类ActionForward。同时约定所有的Action类的所有的方法都必须要返回ActionForward类型。代码如下:
/**
* 跳转
*/
public class ActionForward {
//true 重定向 false 转发
private boolean isRedirect;//
private String path;
public ActionForward(boolean isRedirect,String path){
this.isRedirect=isRedirect;
this.path=path;
}
public boolean getRedirect() {
return isRedirect;
}
public String getPath() {
return path;
}
}
再次修改ActionServlet的doGet方法。
//4、根据返回值跳去其他页面
ActionForward actionForward = (ActionForward) method
.invoke(baseAction);
if (actionForward.getRedirect()) {
// 重定向
response.sendRedirect(actionForward.getPath());
} else {
// 转发
request.getRequestDispatcher(actionForward.getPath()).forward(request, response);
}
六、建立action类。好,大功告成了,现在我们可以测试一下我们这个mvc框架了。新建一个GoodsTypesAction类,必须继承BaseAction类。然后写一个listGoodsTypes方法,这个方法返回值必须是ActionForward。GoodsTypesAction的信息应该和上面的actions.xml的文件信息相对应。代码如下:
/**
* 控制层
*
* @author Administrator
*
*/
public class GoodsTypesAction extends BaseAction{
private GoodsTypesDao goodsTypesDao=new GoodsTypesDao();
// 遍历商品类别
public ActionForward listGoodsTypes() {
// 1、获得页面的输入
String abc=request.getParameter("abc");
System.out.println(abc);
// 2、调用业务逻辑
List<GoodsTypes> types=goodsTypesDao.getAllTypes();
request.setAttribute("goodsTypeses", types);
// 3、返回数据
ActionForward actionForward=new ActionForward(false, "goodstypeslist.jsp");
return actionForward;
}
}
在index.jsp中添加一个超链接<a href="listtypes.do?abc=liu">商品的类别</a>,代码如下:
!-- 这个url对应actions.xml的url -->
<a href="listtypes.do?abc=liu">商品的类别</a>
七、部署和测试项目。在主页上面点击这个超链接,查看后台能否打印abc的信息,同时转发到goodstypeslist.jsp页面。如果没有意外应该可以跳转成功。