搜索
首页Javajava教程关于struts1简单的mvc图文代码实例详解

这篇文章主要介绍了struts1之简单mvc示例的相关资料,需要的朋友可以参考下

先看MVC模式流程图(其实MVC设计模式就是java中的model2。):

        就像图上所标识的C层主要是Servlet层控制页面跳转,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>

        业务逻辑代码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控制代码:


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); 
 
}

        这个servlet代码主要实现的功能判断是那个页面请求服务器做那些操作,之后调用业务逻辑实现相应业务操作。 

        配置Servlet:


<?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开始。 

       首先我们看到了TestServlet中出现了许多if-else语句,这样是非常不稳定的,这样的程序是非常不灵活的,以后如果有变化,那么维护是非常差的;而且我们在if-else中出现了大量的字符串,这样在coding的时候会出现写错,这样无形中给调试带来了麻烦。所以去掉if-else成了我们重构的第一步,也是我们进行Struts框架学习的第一步。因为在TestServlet中出现了If-Else语句块,所以让程序变得不再灵活,让应付需求变化时变得笨拙。所以就承接上篇文章来重构一下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语句块中都有业务处理,我们要把这些业务处理分别放到类里面,让职责更加单

一,这样更加符合面向对象的思路。

       就从这里我们开始重构,我们可以将这个跳转路径和业务逻辑封装起来。

       既然封装,那么我们就抽象出来一个借口,主要完成一个方法,这个方法主要的功能就是要完成业务逻辑封装和路径跳转的返回。随后建立四个类,主要实现相应的增删改查的业务处理和处理之后的跳转路径返回。 

       代码如下:

       接口Action:


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中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
如何将Maven或Gradle用于高级Java项目管理,构建自动化和依赖性解决方案?如何将Maven或Gradle用于高级Java项目管理,构建自动化和依赖性解决方案?Mar 17, 2025 pm 05:46 PM

本文讨论了使用Maven和Gradle进行Java项目管理,构建自动化和依赖性解决方案,以比较其方法和优化策略。

如何使用适当的版本控制和依赖项管理创建和使用自定义Java库(JAR文件)?如何使用适当的版本控制和依赖项管理创建和使用自定义Java库(JAR文件)?Mar 17, 2025 pm 05:45 PM

本文使用Maven和Gradle之类的工具讨论了具有适当的版本控制和依赖关系管理的自定义Java库(JAR文件)的创建和使用。

如何使用咖啡因或Guava Cache等库在Java应用程序中实现多层缓存?如何使用咖啡因或Guava Cache等库在Java应用程序中实现多层缓存?Mar 17, 2025 pm 05:44 PM

本文讨论了使用咖啡因和Guava缓存在Java中实施多层缓存以提高应用程序性能。它涵盖设置,集成和绩效优势,以及配置和驱逐政策管理最佳PRA

如何将JPA(Java持久性API)用于具有高级功能(例如缓存和懒惰加载)的对象相关映射?如何将JPA(Java持久性API)用于具有高级功能(例如缓存和懒惰加载)的对象相关映射?Mar 17, 2025 pm 05:43 PM

本文讨论了使用JPA进行对象相关映射,并具有高级功能,例如缓存和懒惰加载。它涵盖了设置,实体映射和优化性能的最佳实践,同时突出潜在的陷阱。[159个字符]

Java的类负载机制如何起作用,包括不同的类载荷及其委托模型?Java的类负载机制如何起作用,包括不同的类载荷及其委托模型?Mar 17, 2025 pm 05:35 PM

Java的类上载涉及使用带有引导,扩展程序和应用程序类负载器的分层系统加载,链接和初始化类。父代授权模型确保首先加载核心类别,从而影响自定义类LOA

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
4 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器