In diesem Artikel werden hauptsächlich die relevanten Informationen des einfachen MVC-Beispiels von struts1 vorgestellt. Freunde, die es benötigen, können darauf verweisen
Schauen Sie sich zunächst das MVC-Musterflussdiagramm an (tatsächlich ist das MVC-Entwurfsmuster Modell2). in Java.):
So wie die im Bild identifizierte C-Schicht hauptsächlich die Servlet-Schicht ist, die Seitensprünge steuert, ist die M-Schicht die spezifische Geschäftsverarbeitungslogik und JSP ist die sogenannte V-Schicht. MVC unterscheidet sich von den drei Schichten, die wir normalerweise als UI-Schicht, BLL-Schicht und DAL-Schicht bezeichnen. Die spezifischen Unterschiede sind wie folgt:
Wie aus der Abbildung ersichtlich ist, bilden JSP und Servlet die UI-Schicht, und die Modellschicht ist in die BLL-Schicht und die DAL-Schicht (dh die Geschäftslogik- und Datenpersistenzschicht) unterteilt.
Nachdem wir das MVC-Entwurfsmuster theoretisch verstanden haben, beginnen wir mit der Eingabe eines Beispielcodes des MVC-Entwurfsmusters:
JSP-Indexseite index.jsp:
<%@ page language="java" contentType="text/html; charset=GB18030" pageEncoding="GB18030"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=GB18030"> <title>Insert title here</title> </head> <body> <form action="servlet/addUser.action" method="post"> 姓名:<input type="text" name="username" > <input type="submit" value="提交"> </form> </body> </html>
Geschäftslogikcode UserManager:
package com.bjpowernode.servlet; import java.util.ArrayList; import java.util.List; public class UserManager { public void addUser(String username){ System.out.println("UserManager.addUsre()--->username:"+username); } public void delUser(String username){ System.out.println("UserManager.delUser()--->username:"+username); } public void modifyUser(String username){ System.out.println("UserManager.modifyUser()--->username"+username); } public List queryUser(String username){ System.out.println("UserManager.queryUser()--->username"+username); List userList=new ArrayList(); userList.add("a"); userList.add("b"); userList.add("c"); return userList; } }
Servlet-Steuercode:
package com.bjpowernode.servlet; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TestServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String requestURI=request.getRequestURI(); System.out.println("request="+requestURI); String path=requestURI.substring(requestURI.indexOf("/",1),requestURI.indexOf(".")); System.out.println("path="+path); String username=request.getParameter("username"); UserManager userManager=new UserManager(); //userManager.addUser(username); String forward=""; if("/servlet/delUser".equals(path)){ userManager.delUser(username); forward="/del_success.jsp"; }else if("/servlet/addUser".equals(path)){ userManager.addUser(username); forward="/add_success.jsp"; }else if("/servlet/modifyUser".equals(path)){ userManager.modifyUser(username); forward="/modify_success.jsp"; }else if("/servlet/queryUser".equals(path)){ List userList=userManager.queryUser(username); request.setAttribute("userList", userList); forward="/query_success.jsp"; }else{ throw new RuntimeException("请求失败"); } request.getRequestDispatcher(forward).forward(request, response); }
Die Hauptfunktion dieses Servlet-Codes besteht darin, zu bestimmen, welche Seite den Server auffordert, diese Vorgänge auszuführen, und dann die Geschäftslogik aufzurufen, um die entsprechenden Geschäftsvorgänge zu implementieren.
Servlet konfigurieren:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>test_Servlet</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>TestServlet</servlet-name> <servlet-class>com.cjq.servlet.TestServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>TestServlet</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping> </web-app>
Ausgabeergebnis:
Durch die Das obige Beispiel enthält ein vorläufiges Verständnis des MVC-Entwurfsmusters. Tatsächlich ist dieses Beispiel die Grundlage für das Erlernen des Struts-Frameworks. Nur wenn wir dieses Beispiel verstehen, können wir das Implementierungsprinzip des Struts-Frameworks verstehen.
Wie können wir also das Struts-Framework anhand dieses Beispiels vorstellen? Dieses Problem beginnt mit IF-Eles.
Zunächst haben wir gesehen, dass es in TestServlet viele if-else-Anweisungen gibt. Dies ist sehr instabil. Wenn es in Zukunft Änderungen gibt Sehr schlecht. Darüber hinaus haben wir eine große Anzahl von Zeichenfolgen in if-else, die beim Codieren zu Schreibfehlern führen, was zu Problemen beim Debuggen führt. Daher ist das Entfernen von if-else der erste Schritt in unserer Rekonstruktion und der erste Schritt in unserem Erlernen des Struts-Frameworks. Da der If-Else-Anweisungsblock in TestServlet erscheint, wird das Programm weniger flexibel und schwerfällig, wenn es auf Änderungen der Anforderungen reagiert. Daher werde ich mit dem vorherigen Artikel fortfahren, um den TestServlet-Code zu rekonstruieren, und dabei hauptsächlich Vererbungspolymorphismus verwenden, um das TestServlet weiter zu rekonstruieren.
Folgendes tritt in die Rekonstruktionsphase ein:
package com.bjpowernode.servlet; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TestServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String requestURI=request.getRequestURI(); System.out.println("request="+requestURI); String path=requestURI.substring(requestURI.indexOf("/",1),requestURI.indexOf(".")); System.out.println("path="+path); String username=request.getParameter("username"); UserManager userManager=new UserManager(); //userManager.addUser(username); String forward=""; if("/servlet/delUser".equals(path)){ userManager.delUser(username); forward="/del_success.jsp"; }else if("/servlet/addUser".equals(path)){ userManager.addUser(username); forward="/add_success.jsp"; }else if("/servlet/modifyUser".equals(path)){ userManager.modifyUser(username); forward="/modify_success.jsp"; }else if("/servlet/queryUser".equals(path)){ List userList=userManager.queryUser(username); request.setAttribute("userList", userList); forward="/query_success.jsp"; }else{ throw new RuntimeException("请求失败"); } request.getRequestDispatcher(forward).forward(request, response); } }
Zuerst sehen wir, dass in jedem Anweisungsblock die Zuweisung zur Weiterleitung erscheint, bei der es sich tatsächlich um einen Wert zuweisen handelt zum Seitensprungpfad und weisen Sie einen Sprungpfad basierend auf der Beurteilung jedes Anforderungspfads zu. Darüber hinaus gibt es in jedem IF-Else-Anweisungsblock Geschäftsprozesse. Wir müssen diese Geschäftsprozesse in Klassen einteilen, um die Verantwortlichkeiten stärker zu vereinheitlichen, was eher der objektorientierten Idee entspricht.
Von hier aus beginnen wir mit der Rekonstruktion, wir können diesen Sprungpfad und die Geschäftslogik kapseln.
Da es gekapselt ist, werden wir eine Ausrede abstrahieren und hauptsächlich eine Methode vervollständigen. Die Hauptfunktion dieser Methode besteht darin, die Kapselung der Geschäftslogik und die Rückkehr zum Pfadsprung abzuschließen. Anschließend werden vier Klassen eingerichtet, die hauptsächlich die entsprechende Geschäftsverarbeitung von Hinzufügungen, Löschungen, Änderungen und Abfragen sowie die Rückkehr des Sprungpfads nach der Verarbeitung implementieren.
Der Code lautet wie folgt:
Schnittstellenaktion:
package com.bjpowernode.servlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public interface Action { public String execute(HttpServletRequest request,HttpServletResponse response) throws Exception; }
Benutzerimplementierungsklasse hinzufügen:
package com.bjpowernode.servlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class AddUserAction implements Action { public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception { String username=request.getParameter("username"); UserManager userManager=new UserManager(); userManager.addUser(username); return "/add_success.jsp"; } }
package com.bjpowernode.servlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class DelUserAction implements Action { public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception { String username=request.getParameter("username"); UserManager userManager=new UserManager(); userManager.delUser(username); return "/del_success.jsp"; } }
package com.bjpowernode.servlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ModifyUserAction implements Action { @Override public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception { String username=request.getParameter("username"); UserManager userManager=new UserManager(); userManager.modifyUser(username); return "/modify_success.jsp"; } }
package com.bjpowernode.servlet; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class QueryUserAction implements Action { @Override public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception { String username=request.getParameter("username"); UserManager userManager=new UserManager(); List userList=userManager.queryUser(username); request.setAttribute("userList", userList); return "/query_success.jsp"; } }
package com.bjpowernode.servlet; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TestServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String requestURI=request.getRequestURI(); System.out.println("request="+requestURI); String path=requestURI.substring(requestURI.indexOf("/",1),requestURI.indexOf(".")); System.out.println("path="+path); Action action=null; if("/servlet/delUser".equals(path)){ action=new DelUserAction(); }else if("/servlet/addUser".equals(path)){ action=new AddUserAction(); }else if("/servlet/modifyUser".equals(path)){ action=new ModifyUserAction(); }else if("/servlet/queryUser".equals(path)){ action=new QueryUserAction(); }else{ throw new RuntimeException("请求失败"); } String forward=null; try{ forward=action.execute(request, response); }catch(Exception e){ e.printStackTrace(); } request.getRequestDispatcher(forward).forward(request, response); } }
这样TestServlet类虽然没有彻底去掉If-Else,但是这样的代码变得更加简练,利用多肽实现业务逻辑处理和路径跳转返回。职责更加清晰,让维护变得更加轻松。
package com.bjpowernode.servlet; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TestServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String requestURI=request.getRequestURI(); System.out.println("request="+requestURI); String path=requestURI.substring(requestURI.indexOf("/",1),requestURI.indexOf(".")); System.out.println("path="+path); Action action=null; if("/servlet/delUser".equals(path)){ action=new DelUserAction(); }else if("/servlet/addUser".equals(path)){ action=new AddUserAction(); }else if("/servlet/modifyUser".equals(path)){ action=new ModifyUserAction(); }else if("/servlet/queryUser".equals(path)){ action=new QueryUserAction(); }else{ throw new RuntimeException("请求失败"); } String forward=null; try{ forward=action.execute(request, response); }catch(Exception e){ e.printStackTrace(); } request.getRequestDispatcher(forward).forward(request, response); } }
解决字符串问题,当然就要用到配置文件了,用到配置文件就要有用来读取配置文件的相关的类和方法,这里就用dom4j中的类来读取配置文件,这里的配置文件的书写是有点逻辑上的难度的。
我们来看TestServlet中的代码,我们要在这个testservlet中实现读取配置文件和path比较,还有利用多肽实例化相应的实现类,最后通过实例化的实现类的方法来返回跳转路径,最终跳转到相应的页面。
所以我们的配置文件就要不仅配上testservlet中出现的字符串,还要配置相应的Action接口的实现类(我们可以利用反射来实例化该类的对象,进而使用这个类的所有属性和方法),另外还有跳转路径字符串。这样我们的配置文件就变成了如下代码所示:
<?xml version="1.0" encoding="UTF-8"?> <action-config> <action path="/servlet/delUser" type="com.cjq.servlet.DelUserAction"> <forward name="success">/del_success.jsp</forward> <forward name="error">/del_error.jsp</forward> </action> <action path="/servlet/addUser" type="com.cjq.servlet.AddUserAction"> <forward name="success">/add_success.jsp</forward> <forward name="error">/add_error.jsp</forward> </action> <action path="/servlet/modifyUser" type="com.cjq.servlet.ModifyUserAction"> <forward name="success">/modify_success.jsp</forward> <forward name="error">/modify_error.jsp</forward> </action> <action path="/servlet/queryUser" type="com.cjq.servlet.QueryUserAction"> <forward name="success">/query_success.jsp</forward> <forward name="error">/query_error.jsp</forward> </action> </action-config>
我们有了配置文件之后就要想法通过相关类读取,并且实现相应的功能。所以这里用dom4j来读取完成。其实如果能把这个逻辑捋顺之后就能发现,其实懂我们利用dom4j读取完配置文件的时候,我们是取得的是一个配套的匹配路径字符串、相应业务逻辑类还有处理业务逻辑之后跳转页面路径字符串。这样我们就能直截了当的去掉了if-else。(这里可能逻辑上会出现一些困难,但是看到下面的重构之后的testservlet中的代码和读取配置文件之后的代码就会一目了然)。
现在等待解决的问题就是我们要把从配置文件取得的一整套内容放到那里,当然这是毋庸置疑的要放到类中。所以我们就建立一个ActionMapping类来放我们的那一整套内容。
ActionMapping中的代码如下:
package com.bjpowernode.servlet; import java.util.Map; public class ActionMapping { private String path; private Object type; private Map forwardMap; public String getPath() { return path; } public void setPath(String path) { this.path = path; } public Object getType() { return type; } public void setType(Object type) { this.type = type; } public Map getForwardMap() { return forwardMap; } public void setForwardMap(Map forwardMap) { this.forwardMap = forwardMap; } }
现在ActionMapping类已经有了,剩下的工作就是要利用dom4j来读取配置文件类,具体代码如下:
package com.bjpowernode.servlet; import java.io.InputStream; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; public class XmlConfigReader { private static XmlConfigReader instance=new XmlConfigReader(); ActionMapping actionMapping=new ActionMapping(); private Document doc; private Map actionMap=new HashMap(); private XmlConfigReader(){ try { SAXReader reader=new SAXReader(); InputStream in=Thread.currentThread().getContextClassLoader().getResourceAsStream("action_config.xml"); doc=reader.read(in); } catch (DocumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public ActionMapping getActionMapping(String path){ synchronized(this){ Object type=null; /*if(action.containsKey(path)){ type=action.get(path); }*/ Element eltAction = (Element)doc.selectObject("//action[@path=\"" + path + "\"]"); try{ type=Class.forName(eltAction.attributeValue("type")).newInstance(); }catch(Exception e){ e.printStackTrace(); } Element eltForwards = eltAction.element("forward"); for (Iterator iter = eltForwards.elementIterator(); iter.hasNext();) { Element eltForward = (Element) iter.next(); actionMap.put( eltForward.attributeValue("name"),eltForward.getTextTrim()); } actionMapping.setPath(path); actionMapping.setType(type); actionMapping.setForwardMap(actionMap); return actionMapping; } } public static synchronized XmlConfigReader getInstance(){ return instance; } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub ActionMapping actionMapping=XmlConfigReader.getInstance().getActionMapping("/servlet/delUser"); System.out.println(actionMapping.getPath()); System.out.println(actionMapping.getType()); System.out.println(actionMapping.getForwardMap().toString()); } }
我们通过返回ActionMapping来动态创建出action相应的实现类,进而完成业务逻辑和页面跳转,重构之后的TestServlet代码如下:
package com.bjpowernode.servlet; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TestServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String requestURI=request.getRequestURI(); System.out.println("request="+requestURI); String path=requestURI.substring(requestURI.indexOf("/",1),requestURI.indexOf(".")); System.out.println("path="+path); String forward=""; ActionMapping actionMapping=XmlConfigReader.getInstance().getActionMapping(path); Action action=(Action)actionMapping.getType(); try { forward=action.execute(request, response); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } request.getRequestDispatcher(forward).forward(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } }
我们可以清晰的看到if-else已经没有了,字符串也已经没有了。通过这篇文章对if-else还有字符串问题的解决,又一次重构了testservlet代码,程序相对灵活许多。通过这一次的重构,我们已经看到了struts框架的雏形,
Das obige ist der detaillierte Inhalt vonAusführliche Erklärung des einfachen MVC-Grafikcodebeispiels für Struts1. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!