이 글은 Struts1의 간단한 MVC 예제 관련 내용을 주로 소개하고 있으니 필요하신 분들은 참고하시면 됩니다.
먼저 MVC 패턴 흐름도를 살펴보세요. (실제로 MVC 디자인 패턴은 Java에서 model2입니다.)
마찬가지로 그림에서 확인된 C 레이어는 주로 페이지 점프를 제어하는 서블릿 레이어이고, M 레이어는 특정 비즈니스 처리 로직이며, JSP는 소위 V 레이어입니다. MVC는 우리가 일반적으로 부르는 세 가지 레이어가 UI 레이어, BLL 레이어, DAL 레이어와 다릅니다.
보시다시피. 그림에서 보면 JSP와 Servlet은 UI 계층을 형성하고, Model 계층은 BLL 계층과 DAL 계층(즉, 비즈니스 로직과 데이터 지속성 계층)으로 구분됩니다.了 이론적으로 MVC 디자인 모드를 인식한 후 아래 MVC 디자인 모드 예제 코드를 시작합니다.
JSP 인덱스 페이지 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>
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; } }
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); }
<?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>
출력 결과:
위의 예는 이미 MVC 디자인 모드에 대한 사전 이해가 있었습니다. 실제로 이 예는 Struts 프레임워크를 학습하기 위한 기초입니다. Struts 프레임워크의 구현 원리와 Struts 프레임워크의 사용을 명확히 합니다.
그렇다면 이 예제를 통해 Struts 프레임워크를 어떻게 소개할 수 있을까요? 이 문제는 IF-Eles에서 시작됩니다. E 우선, TestServlet에 if-ogse 문장이 많이 나타나는 것을 보았습니다. 이는 매우 불안정합니다. 향후 변경 사항이 있으면 유지 관리가 매우 열악합니다. else에는 문자열이 많아 코딩 시 쓰기 오류가 발생하고, 이로 인해 디버깅에 문제가 발생하게 됩니다. 따라서 if-else를 제거하는 것이 재구성의 첫 번째 단계이자 Struts 프레임워크 학습의 첫 번째 단계가 되었습니다. If-Else 문 블록이 TestServlet에 나타나기 때문에 요구 사항 변경에 응답할 때 프로그램의 유연성이 떨어지고 서투르게 됩니다. 그래서 나는 TestServlet 코드를 재구성하기 위해 이전 기사를 계속할 것이며, 주로 상속 다형성을 사용하여 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 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); } }
먼저 각 명령문 블록에 Forward에 대한 값이 있음을 확인했습니다. 실제로는 페이지 점프 경로에 대한 값이었습니다. 또한 각 IF-Else 문 블록에는 비즈니스 프로세스가 있으며, 이러한 비즈니스 프로세스를 클래스에 넣어 책임을 보다 통합해야 하며 이는 객체 지향 아이디어에 더 부합합니다.
코드는 다음과 같습니다.
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; }
사용자 구현 클래스 추가:
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"; } }
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); 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框架的雏形,
위 내용은 struts1 간단한 mvc 그래픽 코드 예제에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!