0

0

关于struts1简单的mvc图文代码实例详解

黄舟

黄舟

发布时间:2017-09-05 10:37:08

|

1513人浏览过

|

来源于php中文网

原创

这篇文章主要介绍了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"%> 
 
 
 
 
Insert title here 
 
 
 
姓名:

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


 
 
 test_Servlet 
  
 index.html 
 index.htm 
 index.jsp 
 default.html 
 default.htm 
 default.jsp 
  
 
  
 TestServlet 
 com.cjq.servlet.TestServlet 
  
  
 TestServlet 
 *.action 
  
 
 

       输出结果:

              通过上面的示例已经对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语句块中都有业务处理,我们要把这些业务处理分别放到类里面,让职责更加单

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

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

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

aspx1财付通支付接口源码
aspx1财付通支付接口源码

本支付接口的特点,主要是用xml文件来记录订单详情和支付详情。代码比较简单,只要将里面的商户号、商户key换成你自己的,将回调url换成你的网站,就可以使用了。通过这个实例也可以很好的了解一般在线支付接口的基本工作原理。其中的pay.config文件记录的是支付详情,order.config是订单详情

下载

       代码如下:

       接口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接口的实现类(我们可以利用反射来实例化该类的对象,进而使用这个类的所有属性和方法),另外还有跳转路径字符串。这样我们的配置文件就变成了如下代码所示:


 
 
   
    /del_success.jsp 
    /del_error.jsp 
   
   
   
    /add_success.jsp 
    /add_error.jsp 
   
   
   
    /modify_success.jsp 
    /modify_error.jsp 
   
   
   
    /query_success.jsp 
    /query_error.jsp 
   
   

        我们有了配置文件之后就要想法通过相关类读取,并且实现相应的功能。所以这里用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框架的雏形,

相关专题

更多
c++ 根号
c++ 根号

本专题整合了c++根号相关教程,阅读专题下面的文章了解更多详细内容。

57

2026.01.23

c++空格相关教程合集
c++空格相关教程合集

本专题整合了c++空格相关教程,阅读专题下面的文章了解更多详细内容。

57

2026.01.23

yy漫画官方登录入口地址合集
yy漫画官方登录入口地址合集

本专题整合了yy漫画入口相关合集,阅读专题下面的文章了解更多详细内容。

237

2026.01.23

漫蛙最新入口地址汇总2026
漫蛙最新入口地址汇总2026

本专题整合了漫蛙最新入口地址大全,阅读专题下面的文章了解更多详细内容。

393

2026.01.23

C++ 高级模板编程与元编程
C++ 高级模板编程与元编程

本专题深入讲解 C++ 中的高级模板编程与元编程技术,涵盖模板特化、SFINAE、模板递归、类型萃取、编译时常量与计算、C++17 的折叠表达式与变长模板参数等。通过多个实际示例,帮助开发者掌握 如何利用 C++ 模板机制编写高效、可扩展的通用代码,并提升代码的灵活性与性能。

17

2026.01.23

php远程文件教程合集
php远程文件教程合集

本专题整合了php远程文件相关教程,阅读专题下面的文章了解更多详细内容。

103

2026.01.22

PHP后端开发相关内容汇总
PHP后端开发相关内容汇总

本专题整合了PHP后端开发相关内容,阅读专题下面的文章了解更多详细内容。

73

2026.01.22

php会话教程合集
php会话教程合集

本专题整合了php会话教程相关合集,阅读专题下面的文章了解更多详细内容。

81

2026.01.22

宝塔PHP8.4相关教程汇总
宝塔PHP8.4相关教程汇总

本专题整合了宝塔PHP8.4相关教程,阅读专题下面的文章了解更多详细内容。

70

2026.01.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Git 教程
Git 教程

共21课时 | 3万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.3万人学习

Kotlin 教程
Kotlin 教程

共23课时 | 2.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号