- 创建一个maven工程(smartmvc-exec)
2.导包(dom4j)
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
3.添加一个jsp(/WEB-INF/hello.jsp)
<%@ page pageEncoding="utf-8"
contentType="text/html; charset=utf-8" %>
<html>
<head>/head>
<body style="font-size:30px;">
Hello SmartMVC!
</body>
</html>
4.在base.annotation包下添加一个java注解(@RequestMapping)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestMapping {
public String value();
}
5.在demo包下添加HelloController类(处理器)
该类方法前添加@RequestMapping注解(指定请求路径)
方法返回值是一个字符串(即视图名)
public class HelloController {
@RequestMapping("/hello.do")
public String hello(){
System.out.println(
"HelloController的hello方法");
return "hello";
}
}
6…添加smart-mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<!-- 配置处理器:
class属性用于指定处理器类名。
-->
<bean class="demo.HelloController"/>
</beans>
7.在base.web包下添加DispatcherServlet
在初始化方法里,读取配置文件中的处理器类名,将处理器实例化,
然后将处理器实例交给HandlerMapping来处理。
public class DispatcherServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private HandlerMapping handlerMapping;
@Override
/**
* 读取配置文件(smartmvc.xml)的内容,将所有
* 处理器实例化,然后将这些处理器实例交给
* HandlerMapping来处理。
* 注:
* HandlerMapping负责建立请求路径与处理器的
* 对应关系。
*/
public void init() throws ServletException {
//读取配置文件位置及文件名
String configLocation =
getServletConfig()
.getInitParameter("configLocation");
SAXReader sax =
new SAXReader();
InputStream in =
getClass().getClassLoader()
.getResourceAsStream(configLocation);
try {
/*
* 利用dom4j读取配置文件的内容,
* SAXReader的read方法的返回值可以
* 想像一棵树,我们可以从根节点开始,
* 一层一层遍历。
*/
Document doc = sax.read(in);
//找到根节点
Element root =
doc.getRootElement();
//找出根节点的所有子节点
List<Element> elements =
root.elements();
List beans =
new ArrayList();
//遍历子节点,读取处理器类名
for(Element ele : elements){
String className =
ele.attributeValue("class");
System.out.println("className:"
+ className);
//将处理器实例化
Object bean =
Class.forName(className)
.newInstance();
beans.add(bean);
}
System.out.println("beans:" + beans);
//将处理器实例交给HandlerMapping来处理
handlerMapping = new HandlerMapping();
handlerMapping.process(beans);
} catch (Exception e) {
e.printStackTrace();
throw new ServletException(e);
}
}
/*************web-xml配置文件/
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>base.web.DispatcherServlet</servlet-class>
<!--
指定配置文件的位置及文件名
-->
<init-param>
<param-name>configLocation</param-name>
<param-value>smart-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
8.在base.common包下添加Handler类
public class Handler {
private Method method;
private Object obj;
public Handler(Method method, Object obj) {
this.method = method;
this.obj = obj;
}
public Method getMethod() {
return method;
}
public void setMethod(Method method) {
this.method = method;
}
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
}
9.在base.common包下添加HandlerMapping类(映射处理器)
public class HandlerMapping {
//mappings用于存放请求路径与处理器的对应关系
private Map<String,Handler> mappings =
new HashMap<String,Handler>();
/**
* 依据请求路径返回Handler对象。
* 注:
* Handler对象封装了处理器对象及方法对象,
* 方便利用java反射来调用处理器的方法。
*/
public Handler getHandler(String path){
return mappings.get(path);
}
public void process(List beans) {
for(Object bean: beans){
//获得Class对象
Class clazz = bean.getClass();
//获得所有方法
Method[] methods =
clazz.getDeclaredMethods();
//遍历所有方法
for(Method mh : methods){
//获得@RequestMapping注解
RequestMapping rm =
mh.getDeclaredAnnotation(
RequestMapping.class);
//获得请求路径
String path = rm.value();
//存放请求路径与处理器的对应关系
mappings.put(path,
new Handler(mh,bean));
}
}
System.out.println("mappings:" + mappings);
}
}