標籤:oca 介面 xml配置 final auth turn cte 靜態方法 welcome
1. 介紹
MVC全名是Model View Controller,是模型(model)-視圖(view)-控制器(controller)的縮寫,一種軟體設計典範,用一種商務邏輯、資料、介面顯示分離的方法組織代碼,將商務邏輯聚集到一個組件裡面,在改進和個人化定製介面及使用者互動的同時,不需要重新編寫商務邏輯。MVC被獨特的發展起來用於映射傳統的輸入、處理和輸出功能在一個邏輯的圖形化使用者介面的結構中。
我們今天就來搭建一個自己的從URL訪問到JAVA控制器的簡單架構。
2. 實現思路
- 首先,我們要將URL訪問請求和我們的後台JAVA方法形成一一對應關係。
- 然後,我們需要在tomcat容器啟動網站載入的時候擷取上一步驟中記錄的一一對應關係,並記錄下來。
- 最後,完成URL訪問到後台JAVA方法的跳轉。
3. 具體實現:(1)通過註解來標記出URL到後台JAVA方法的映射關係。 A. 定義註解:這個註解可以標註在類和方法上。
/** * @author WangWang */@Target({ElementType.METHOD, ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface UrlMapping { public String url() default "";} B. JAVA後台中針對URI的相應方法:
package mvc;/** * @author WangWang */@UrlMapping(url="/HelloController")public class HelloController { @UrlMapping(url="/Hello") public String SayHello(){ System.out.println("Hello_________________"); return "Hello"; } @UrlMapping(url="/Hi") public String SayHi(){ System.out.println("Hi_____________"); return "Hi"; } }
通過註解,我們可以看出我們擬定將來用SayController這個類來相應/Say/***的URL。其中SayHello方法相應的URL是/Say/Hello,SayHi方法相應的URL是/Say/Hi。
這樣,我們就定義好了URL和JAVA後台方法的對應關係。接下來我們要實現如果完成這種對應關係的跳轉
。
(2)實現URL到JAVA後台方法的跳轉 A. 定義我們用來儲存URL到JAVA後台方法對應關係的基礎資料類型:
package mvc;/** * @author WangWang */public class MVCBase { private String url;//訪問路徑 private String controller;//類名 private String method;//方法名 public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getController() { return controller; } public void setController(String controller) { this.controller = controller; } public String getMethod() { return method; } public void setMethod(String method) { this.method = method; } }B. 通過監聽器在tomcat啟動的時候收集URL到JAVA後台方法的對應關係並儲存起來:
package mvc;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.List;import javax.servlet.ServletContextEvent;import javax.servlet.ServletContextListener;/** * @author WangWang */public class UrlMappingCollection implements ServletContextListener { //被註解了URLMapper的類方法列表 private static List<MVCBase> mvcBases; //我們要掃描的Controller列表 private final String[] controllerList = {"mvc.HelloController"}; public void contextDestroyed(ServletContextEvent arg0) { } public void contextInitialized(ServletContextEvent arg0) { mvcBases = new ArrayList<MVCBase>(); try { //迴圈所有需要掃描的Controller for(String controllerName : controllerList) { String classUrl = ""; String methodUrl = ""; //擷取Controller類 Class<?> clas = Class.forName(controllerName); //class被標記了URLMapping註解 if(clas.isAnnotationPresent(UrlMapping.class)) { classUrl = clas.getAnnotation(UrlMapping.class).url(); //擷取method列表 Method[] methods = clas.getMethods(); for(Method method : methods) { if(method.isAnnotationPresent(UrlMapping.class)) { methodUrl = method.getAnnotation(UrlMapping.class).url(); MVCBase mvc = new MVCBase(); mvc.setUrl(classUrl + methodUrl); mvc.setController(controllerName); mvc.setMethod(method.getName()); mvcBases.add(mvc); } } } } } catch (Exception e) { } } public static List<MVCBase> getMvcBases() { return mvcBases; } }
- mvcBases就是將來我們要將URL到JAVA後台方法對應關係儲存到的地方。我們將他定義為靜態方法,以便後續我們直接存取擷取。
- controllerList是用來告訴監聽器,我們要從哪些類中擷取URL到JAVA後台方法的對應關係。因為在程式設計期我們就已經知道了,所以定義為final屬性。
- 然後在監聽器初始化的時候,迴圈controllerList中的class,根據註解的資訊來收集URL到JAVA後台方法的對應關係並儲存到mvcBases中。
C. 配置Servlet訪問:
首先我們要準備我們的Servlet類,將來所有的URL請求都要跳轉到這個Servlet中。
package mvc;import java.io.IOException;import java.lang.reflect.Method;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * @author WangWang */public class ServletCenter extends HttpServlet { /** * */ private static final long serialVersionUID = 1L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { doTransfer(req, resp); } catch (Exception e) { } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { doTransfer(req, resp); } catch (Exception e) { } } //通過url執行對應的方法 private void doTransfer(HttpServletRequest req, HttpServletResponse resp) throws Exception{ //遍曆url容器 for(MVCBase mvcBase : UrlMappingCollection.getMvcBases()) { //判斷註解路徑 if(req.getRequestURI().equals(req.getContextPath() + mvcBase.getUrl())) { //反射擷取class Class<?> clas = Class.forName(mvcBase.getController()); //擷取方法 Method method = clas.getMethod(mvcBase.getMethod()); //執行方法 method.invoke(clas.newInstance()); } } }}
可以看到,doGet和doPost裡面都執行的是doTransfer方法。相應的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> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <!-- 配置監聽器 --> <listener> <listener-class>mvc.UrlMappingCollection</listener-class> </listener> <servlet> <servlet-name>hello</servlet-name> <servlet-class>mvc.ServletCenter</servlet-class> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>
在web.xml中,我們將所有的請求都跳轉到com.mvc.servlet.ServletCenter中。
5. 測試
將MyMVC部署到tomcat容器中,啟動tomcat,輸入http://127.0.0.1:8080/MyMVC/HelloController/Hello 以及 http://127.0.0.1:8080/MyMVC/HelloController/Hi 就可以看到後台輸出的Hello和Hi了
java寫個自己的mvc架構學習筆記