写一个通用控制器,在开发的时候只用写模型和视图。
注:请求路径和模型的对应关系
step1.添加一个注解@RequestMapping
/**
自定义注解:用于配置请求路径和处理器的对应关系。
*/
@Retention(RetentionPolicy.RUNTIME) //保留至运行时。所以我们可以通过反射去获取注解信息。 public @interface RequestMapping( ){//自定义注解 public String value( ); }
step2:写一个java类(HelloController),即处理器。
/* 处理器:负责处理业务逻辑。 */ public class HelloController{ @RequestMapping(“/hello.do”) public String hello(){ System.out.println(“HelloController的方法”); /*返回视图名:viewResolver会将视图名映射成对应的jsp。*/ return “hello”; }
step3:添加smartmvc.xml
<?xml version="1.0" encoding="UTF-8"?> <beans> <!-- 配置处理器: class属性用于指定处理器的类名。 --> <bean class="demo.HelloController"/> </beans>
step4.写DispatcherServlet
public class DispatcherServlet extends HttpServlet { //读取Http请求的内容? private static final long serialVersionUID = 1L; private HandlerMapping handlerMapping; @Override /** * 读取配置文件(smartmvc.xml),将处理器实例化, * 然后将这些处理器交给HandlerMapping(映射处理器) * 来处理。 * 注: * HandlerMapping读取处理器中的路径信息,建立 * 请求路径与处理器的对应关系。 */ public void init() throws ServletException{ //利用dom4j解析配置文件 SAXReader sax=new SAXReader(); InputStream in=getClass().getClassLoader(). getResourceAsStream(“smartmvc.xml”); try{ //解析配置文件 Document doc=sax.read(in); //获取根元素下面的所有子元素 List<Element> elements=root.elements( );//?? List beans=new ArrayList( ); for(Element ele:elements){ //获得处理器类名 String className=ele.attribute(“class”); System.out.println(“className:”+className); //将处理器实例化 Object bean=Class.forName( ).newInstance( ); //将处理器实例添加到集合里面 bean.add(bean); } System.out.println(“beans:”+beans); }catch(Exception e){ e.printStackTrace(); throw new ServletException(e); //由于重写,所以重写的方法的异常不可以大于父类的异常,但这样就可以了 //吗?这是什么处理?异常的该如何抛出来?这种用法何时用怎么用? //为什么这样用? } } }
step5.写HandlerMapping
/** * 映射处理器: * 负责提供请求路径与处理器的对应关系。 */ public class HandlerMapping { //存放请求路径与处理器的对应关系 private Map<String,Handler> handlerMap = new HashMap<String,Handler>(); /** * 依据请求路径,返回对应的Handler对象 */ public Handler getHandler(String path){ return handlerMap.get(path); } /** * 负责建立请求路径与处理器的对应关系: * 利用java反射获得处理器实例上的@RequestMapping * 注解,然后读取该注解的属性值获得路径信息, * 接下来,以该路径信息作为key,以处理器实例及方法 * 对象(Method对象)的封装(Handler)作为value, * 将请求路径与处理器的对应关系存放到Map里面。 */ 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(); System.out.println("path:" + path); /* * 以请求路径作为key,以Handler对象 * 作为value,将请求路径与处理器的对应 * 关系存放到Map对象里面 */ handlerMap.put(path, new Handler(mh,bean)); } } System.out.println("handlerMap:" + handlerMap); } }
==============================================================================================================
灵感来自代码,多敲,有时看得费力时候,就多敲几次,并画图,
并把细节了解清楚直到能默写。首先,看看思路,再把注释留着
代码删掉,再写一次,不会写了再看备份的代码。
(画上面的思维图,另外还有细节的思路图)
(5)如何使用SmartMVC?
step1.创建一个maven工程。
step2.导包。
在pom.xml文件中,添加如下所标配置:
<dependencies> <dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> <version>1.6.1</version> </dependency> </dependencies>
step3.拷贝base包
注: base包包含了SmartMVC的核心源代码。
step4.配置DispatcherServlet
<servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>base.web.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
step5.添加处理器类
注:在方法前添加@RequestMapping注解:
@RequestMapping("/toBmi.do")
public String toBmi(){
return "bmi";
}
step6.添加jsp
注:
jsp的名称要与视图名一致。
step7.配置smartmvc.xml
注: 添加处理器的配置信息:
<beans> <!-- 配置处理器: class属性用于指定处理器的类名。 --> <bean class="controller.BmiController"/> </beans>
---------------------------------------------------------------------------------------------------------------------------
思路总结:
1.@interface RequestMapping() 通过反射获得注解信息 其实是一个路径的一个值
2.HelloController.java 处理器,解析并返回一个视图名
3.smartmvc.xml 指定处理器的类名
4.写一个DispatcherServlet 该servlet用dom4j解析smartmvc.xml,并用反射读取HelloController的全限定名和方法 绑定一个类 dom4j(配置文件)和反射(类和方法)
5.映射处理器 负责提供请求路径和处理器的对应的关系,过程:用Map集合
存储请求路径和处理器的对应的关系,用反射获取注解的路径信息。 并用反射从类中获得注解的所对应的路径请求的信息
6.将以上文件打包到一个文件夹,并写视图文件 ,开始测试。