表示层(视图层,显示层)
业务逻辑层
数据访问层(持久层)
是一种架构思想,其核心思想将项目划分成三种不同模块,分别是模型,视图,控制器
View : JSP 负责显示
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) //设置这个注解是给方法使用的 @Retention(RetentionPolicy.RUNTIME) //设置注解的存在时间为运行时 public @interface RequestMapping { //设置传入的参数 public String value(); //设置一个参数 ,必须传入参数 如果添加 default "" ,那么默认的参数就是空字符串 //public String method() default "get"; //设置method参数,默认的是get方法 }
import java.lang.reflect.Method; public class Handler{ private Method method; // 方法 private Object object; // Object对象,用于反射调用方法method public Handler(Method method, Object object){ super(); this.method = method; this.object = object; } public Method getMethod(){ return method; } public void setMethod(Method method){ this.method = method; } public Object getObject(){ return object; } public void setObject(Object object){ this.object = object; } @Override public String toString(){ return "Handler [method=" + method + ", object=" + object + "]"; } }
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean class="cn.controller.UserController"></bean> <bean class="cn.controller.DeptController"></bean> </beans>
解析config.xml的文件,使用的是Dom4j
在pom.xml中导入依赖
<!-- 读取xml文件的jar包 --> <dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> <version>1.6.1</version> </dependency>
解析xml文件的工具类
import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; import cn.reflect.ReflectDemo; /** * 读取XML文件的工具类 * @author chenjiabing * */ public class XMLUtils{ /** * 读取xml文件中的内容,使用的jar包是dom4j * @return xml配置文件中的所有bean的对象 */ public static List<Object> getBeans()throws Exception{ SAXReader reader=new SAXReader(); InputStream inputStream=ReflectDemo.class.getClassLoader().getResourceAsStream("config.xml"); //获取输入流 Document document=reader.read(inputStream); //得到根节点 Element beansEle=document.getRootElement(); //得到根节点下面的所有子节点 List<Element> elements=beansEle.elements(); List<Object> beans=new ArrayList<Object>(); //保存bean中的class属性创建的对象 //遍历子节点 for (Element element : elements) { //得到class属性的值 String className=element.attributeValue("class"); //直接使用遍历的className创建对象并且保存在集合中 Class cls=Class.forName(className); Object bean=cls.newInstance(); beans.add(bean); //将创建的对象添加到集合中 } return beans; } }
package cn.reflect; import java.io.InputStream; import java.lang.reflect.Method; import java.util.HashMap; import java.util.List; import java.util.Map; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; import cn.annoation.RequestMapping; public class HandlerMapping{ private Map<String, Handler> map = new HashMap<String, Handler>(); // 创建一个Map存储path和Handler /** * 初始化方法,将指定类的带有注解的方法放入Map中 * @param beans 对象集合 */ public void init(List<Object> beans){ for (Object bean : beans) { Class cls=bean.getClass(); //获取所有方法 Method[] methods=cls.getDeclaredMethods(); for (Method method : methods) { RequestMapping requestMapping=method.getAnnotation(RequestMapping.class); //如果方法上面存在RequestMapping注解 if (requestMapping!=null) { String path=requestMapping.value(); //获取注解上的地址 Handler handler=new Handler(method, bean); //创建handler对象 map.put(path, handler); //存放键值对 } } } } /** * 根据给定的path返回一个Handler对象 * * @param path * 指定的路径,map中的key * @return Handler 对象 */ public Handler getHandler(String path){ return map.get(path); } }
redirect:add.do
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ViewResolver{ /** * 视图解析器 * @param returnValue controller方法的返回值 */ public void process(Object returnValue, HttpServletRequest request, HttpServletResponse response) { String path=(String)returnValue; try { //判断是转发还是重定向 if (path.startsWith("redirect:")) { //重定向 response.sendRedirect(request.getContextPath()+"/"+path.split(":")[1]); }else { //转发 request.getRequestDispatcher("/WEB-INF/"+path+".jsp").forward(request, response); } } catch (Exception e) { e.printStackTrace(); } } }
import java.io.IOException; import java.lang.reflect.Method; import java.util.List; import java.util.Scanner; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import cn.reflect.Handler; import cn.reflect.HandlerMapping; import cn.reflect.ViewResolver; import cn.utils.XMLUtils; /** * Servlet implementation class DispatcherServlet */ public class DispatcherServletextends HttpServlet{ @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List<Object> beans; try { beans = XMLUtils.getBeans();// 获取xml配置文件中所有bean的对象 HandlerMapping handlerMapping = new HandlerMapping(); String uri = request.getRequestURI(); // 请求地址 String appName = request.getContextPath(); // 工程名 String path = uri.replace(appName, ""); // 获取注解的path handlerMapping.init(beans); // 初始化 Handler handler = handlerMapping.getHandler(path); // 获取指定的Handler Method method = handler.getMethod(); Object object = handler.getObject(); Class[] paramTypes = method.getParameterTypes(); // 获取方法中的参数类型 Object returnValue=null; //申明目标方法的返回值 // 如果调用的方法有参数 if (paramTypes.length > 0) { Object[] args = new Object[paramTypes.length]; //创建参数列表 for (int i = 0; i < args.length; i++) { Class cls = paramTypes[i]; // 判断类型是request或者response if (cls == HttpServletRequest.class) { args[i] = request; } else if (cls == HttpServletResponse.class) { args[i] = response; } } returnValue=method.invoke(object, args); } else { returnValue=method.invoke(handler.getObject()); // 调用方法执行 } //有返回值,要么转发,要么重定向 if (returnValue!=null) { //通过视图解析器对象,处理转发或者重定向 ViewResolver viewResolver=new ViewResolver(); viewResolver.process(returnValue,request,response); } } catch (Exception e) { e.printStackTrace(); } } }