本类是同一个问题的,但是在我另外的一个帖子中没有很好的表达出来,真是失败啊。
进入正题:
众所周知,Servlet 和 Struts中的Action是属于MVC中的C(Controler),只是一个控制器,
按说在两者之中是不应该出现业务代码的,它们只是一个控制器,只负责将视图(JSP页面)
取得的数据转发到业务层来处理,然后根据业务层的处理结果来选择相应的视图来显示,
那么在Servlet或者Action中该不该出现判断数据的代码,又如何讲数据传递到业务层呢?
光说太抽象,来点代码://假设这是Servlet中的一个方法,来处理用户注册请求的
public void register(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
String repeatPass = request.getParameter("repeatPass");

//主要下面这段代码该在什么地方
if( password == null || password.length() < 6 ){
//密码长度小于6位,不能注册
response.sendRedirect("some page");
return;
}
if( !password.equals(repeatPass)){
//两次密码不相同,不能注册
response.sendRedirect("some page");
return;
}
//还有一些验证,比如判断用户名是否已存在,等等
//这些代码写在什么地方?这里?还是BO?

UserBo bo = new UserBo();
//是这传递
bo.addUser(new User(username,password));
//还是这样传递?
bo.addUser(username,password);
//forward or redirect
}

解决方案 »

  1.   

    1、数据验证可以放在validate,该过程在xxform.java里
    2、如果是简单的业务逻辑放在action也挺方便,复杂的业务逻辑就要写些类来操作,然后在action里调用,再根据处理情况给用户显示相应的view
      

  2.   

    还有,如果不用Struts的话,数据正确性验证要放在哪里?
    Servlet还是BO?
      

  3.   

    可以通过请求request啊
    也可以同ActionForm获得啊
      

  4.   

    是不是简单的逻辑可以放到控制器里,复杂的逻辑一定要在业务层完成了啊?
    业务层属于MVC中的哪一层?是Controler还是Model?
      

  5.   

    业务是在model里,一般是用bean,太简单没有复用价值的放在control里也就行了,我是这样认为的
      

  6.   

    Controler是完成Model与View之间交互的
    可以具体去看看MVC那个图
      

  7.   


    我觉得又有点 形而上学 了。MVC解决不了所有问题,如果一个系统没有界面,又哪来MVC?现在的J2EE,分层是它的第一架构特征,
    业务层和WEB层完全是独立的,在WEB可以考虑MVC模式,业务层有其自身适用的模式,
    仔细看看这张图:
    追问下去,你是不是应该问问DataBase属于什么,Model?我觉得学习要能钻进去,还要能跳出来,
    当遇到问题的时候,要反思问题本身是不是伪问题。
    另外,再怎么样的设计模式,也不可能将所有的逻辑100%分离开,
    在前台界面还要用JS做数据验证,你觉得这该怎么算呢?应用设计模式,更多的是套用一种思路,在这种已经成熟的解决问题的框架下,
    要考虑自己的业务特性、代码的可读性、流畅性等各种因素。
    以上想法可能有些不太“正规”,但我觉得比较“实际”,
    仅供参考。
      

  8.   

    可以通过请求request啊 
    也可以同ActionForm获得啊
      

  9.   

    servlet属于控制器,而控制器的作用就是接收客户端请求,调用相应的模型处理逻辑和数据,再由控制器根据处理的结果,选择相应的JSP或HTML文件响应客户端。所以,我认为,servlet无非就是两个作用,一个是接收用户请求数据,再一个就是完成页面的跳转,而关于如上的if判断语句我觉得应该交给bo,servlet调用bo,返回一个字符串,即目标地址。
      

  10.   

    两次输入的密码是否一致,可以放在页面校验。不必到servlet校验。
      

  11.   

                   Entity
      Database  <----------> DAO层 <------> 业务层 <------> (业务门面) <------> 控制器 <------> 视图 <------> 客户端浏览器
    |           |                                                                                    |
    | DB 服务器 | <-------------------------------- 应用服务器 ------------------------------------->|
    |           |                                                                                    |
      

  12.   

    servlet作用只有两个:就是接收客户端的请求数据,再一个就是完成页面的跳转!
    像你上面的例子中的那些判断,完全可以在bo中写个方法public String getUrl(String password,String repeatPass)返回要跳转的url字符串!
    后面得那个方法的参数当然是userName和password,封装进User应该在bo中进行!
      

  13.   

    就是一个原则,servlet只是控制转向的,业务逻辑最好能封装进bo!
      

  14.   

    花开如梦,风过无痕http://www.ok1616.com/ 只为心中的思念…… 遥寄一份浓浓的祝福给你
    悄悄问苍穹:别来可无恙 http://www.hao1234.org/寄语白云间:祝你永平安 
      

  15.   


    说实话,分层只是为了更清晰程序设计过程,更明白整个开发和维护的成本和程序性能,所说的控制,视图,模型等等,都是为了将之功能模块化,细分化,当时软件工程的确有些白学了,呵呵,虽然毕业还近一年吧。这里给你一个实实在在的例子,跟你的上面的代码十分的接近,不过没有用到struts,原因是用了servlet够了,用Flex做页面开发的,和JSP差不都,没有区别,都是前后台沟通问题,servlet也就当做控制层,然后通过业务层提交到bs,最后由bs转向到DAO层,所有与数据有关的,都在DAO层处理,代码如下,都是模块化的,呵呵,主要是我作B/S系统的,所以模块化比较强,控制层,servletmport java.io.IOException;import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;import project.syscfg.business.AreaCfgBs;
    import supports.ToyServlet;@SuppressWarnings("serial")
    public class AreaCfgServlet extends ToyServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException { foreachRequest(request);
    String handle = getString(request, "handle"); if (handle == null)
    return; } public void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException { foreachRequest(request); // 取得来自页面的参数
    String handle = getString(request, "handle"); // 判断一下而已,是否有参数传回来,如果没有就不要动作.
    if (handle == null)
    return; // 注入业务层实例
    AreaCfgBs areaCfgBs = (AreaCfgBs) getObj("areaCfgBs"); if (handle.equalsIgnoreCase("page")) { areaCfgBs.pageAreaCfg(request, response);
    }else if (handle.equalsIgnoreCase("add")) { areaCfgBs.addAreaCfg(request, response);
    } else if (handle.equalsIgnoreCase("edit")) { areaCfgBs.updateAreaCfg(request, response);
    } else if (handle.equalsIgnoreCase("remove")) { areaCfgBs.deleteAreaCfg(request, response);
    } else if (handle.equalsIgnoreCase("query")) { areaCfgBs.queryAreaCfg(request, response);
    } else if (handle.equalsIgnoreCase("view")) { areaCfgBs.viewAreaCfg(request, response);
    } }
    }
    业务层package project.syscfg.business;import java.util.List;
    import java.util.Map;import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;import project.syscfg.dao.AreaCfgDao;
    import project.user.po.User;
    import supports.ToyBusiness;
    import supports.ToyPage;
    import supports.ToyXML;public class AreaCfgBs extends ToyBusiness implements IAreaCfgBs { private AreaCfgDao areaCfgDao; // Getter and Setter
    public AreaCfgDao getAreaCfgDao() {
    return areaCfgDao;
    } public void setAreaCfgDao(AreaCfgDao areaCfgDao) {
    this.areaCfgDao = areaCfgDao;
    } // end Getter and Setter @Override
    public void addAreaCfg(HttpServletRequest request,
    HttpServletResponse response) { String xml = ""; try { Integer areaNo = getInteger(request, "areaNo");
    // areaLevel
    Integer vestAreaNo = getInteger(request, "vestAreaNo");
    String areaName = getString(request, "areaName");
    Integer xaxis = getInteger(request, "xaxis");
    Integer yaxis = getInteger(request, "yaxis"); Integer areaLevel = 0; // 这里初始化为0,要根据他的父节点来,没有就是0
    if (vestAreaNo != 0) { areaLevel = vestAreaNo;
    } xml = ToyXML.writeAlert(areaCfgDao.addAreaCfg(areaNo, areaLevel,
    vestAreaNo, areaName, xaxis, yaxis), "添加地区配置资料成功"); // 取得当前的登录用户
    User me = (User) getLogin(request, "ME");
    areaCfgDao.writeLog(me, "AREACFGTBL", "添加地区配置资料", 1); } catch (Exception e) {
    e.printStackTrace();
    xml = ToyXML.writeAlert(false, "添加地区配置资料失败:\n" + e.getMessage()); } finally {
    // 回应页面
    s(xml);
    writeXML(response, xml);
    } } @Override
    public void deleteAreaCfg(HttpServletRequest request,
    HttpServletResponse response) {
    String xml = ""; try {
    String selectedIDs = getString(request, "selectedIDs"); s("---------" + selectedIDs); xml = ToyXML.writeAlert(areaCfgDao.deleteAreaCfg(selectedIDs),
    "删除地区配置资料成功"); // 取得当前的登录用户
    User me = (User) getLogin(request, "ME");
    areaCfgDao.writeLog(me, "AREACFGTBL", "删除地区配置资料", 0); } catch (Exception e) {
    e.printStackTrace();
    xml = ToyXML.writeAlert(false, "删除地区配置资料失败:\n" + e.getMessage()); } finally {
    // 回应页面
    writeXML(response, xml);
    }
    } @Override
    public void pageAreaCfg(HttpServletRequest request,
    HttpServletResponse response) {
    String xml = ""; try { // 统计记录
    Integer totalRow = getCount(request, response);
    // 预置每页显示的记录条数
    Integer pageSize = 10;
    // 预置翻页动作
    String pageHandle = "goFirst"; // 取得分页信息
    ToyPage p = getPage(request, "AREACFG");
    s("当前页码--------->>>" + p.getCurrentPage());
    // 如果页面请求设置每页显示的记录条数才设置
    if (getInteger(request, "pageSize") != null)
    pageSize = getInteger(request, "pageSize"); // 如果页面请求设置翻页动作才设置
    if (request.getParameter("pageHandle") != null)
    pageHandle = getString(request, "pageHandle"); // 分页
    p.run(totalRow, pageSize, pageHandle); setPage(request, "AREACFG", p); xml = ToyXML.bean2xml(getPage(request, "AREACFG")); s(xml);
    } catch (Exception e) { e.printStackTrace();
    xml = ToyXML.writeAlert(false, "分页失败:\n" + e.getMessage());
    } finally { writeXML(response, xml);
    }
    } private Integer getCount(HttpServletRequest request,
    HttpServletResponse response) { String areaName = getString(request, "areaName");
    Integer vestAreaNo = getInteger(request, "vestAreaNo");
    return areaCfgDao.getCount(vestAreaNo, areaName);
    } @Override
    public void queryAreaCfg(HttpServletRequest request,
    HttpServletResponse response) {
    String xml = ""; try {
    // 取得分页信息,加入查询条件
    ToyPage p = getPage(request, "AREACFG"); String areaName = getString(request, "areaName");
    Integer vestAreaNo = getInteger(request, "vestAreaNo"); List<Map<String, Object>> dataList = areaCfgDao.queryAreaCfg(
    vestAreaNo, areaName, p.getStartRow(), p.getEndRow()); Map<String, Object> areaMap = areaCfgDao.getAreaMap(); for (Map<String, Object> dataMap : dataList) { String s = ""; s = getString(dataMap, "VESTAREANO");
    String vestName = getString(areaMap, s);
    dataMap.put("VESTAREANAME", vestName);
    } xml = ToyXML.util2xml(dataList); s(xml); } catch (Exception e) {
    e.printStackTrace();
    xml = ToyXML.writeAlert(false, "查询失败:\n" + e.getMessage()); } finally {
    writeXML(response, xml);
    } } @Override
    public void updateAreaCfg(HttpServletRequest request,
    HttpServletResponse response) { String xml = ""; try {
    Integer areaNo = getInteger(request, "areaNo");
    // areaLevel
    Integer vestAreaNo = getInteger(request, "vestAreaNo");
    String areaName = getString(request, "areaName");
    Integer xaxis = getInteger(request, "xaxis");
    Integer yaxis = getInteger(request, "yaxis"); Integer areaLevel = 0; // 这里初始化为0,要根据他的父节点来,没有就是0
    if (vestAreaNo != 0) { areaLevel = vestAreaNo;
    } xml = ToyXML.writeAlert(areaCfgDao.updateAreaCfg(areaNo, areaLevel,
    vestAreaNo, areaName, xaxis, yaxis), "编辑地区配置资料成功"); // 取得当前的登录用户
    User me = (User) getLogin(request, "ME");
    areaCfgDao.writeLog(me, "AREACFGTBL", "编辑地区配置资料", 1); } catch (Exception e) {
    e.printStackTrace();
    xml = ToyXML.writeAlert(false, "编辑地区配置资料失败:\n" + e.getMessage()); } finally {
    // 回应页面
    writeXML(response, xml);
    }
    } @Override
    public void viewAreaCfg(HttpServletRequest request,
    HttpServletResponse response) { }}
    呵呵,处理的数据层由于字数限制就不发出来了,还有POJO,当然都是十分简单的东西,希望楼主能够了解。
      

  16.   

    呵呵,回复很多啊,慢慢看了。
    看来我太形式化了,仔细想想三层模式和MVC倒是没有什么必然的牵连关系
    我只是想写出的代码更符合规范而已,难道是太在意模式了?...
      

  17.   

    我也说两句,一般只有验证的话Struts1和Struts2都有专门用来进行页面提交数据验证的类,如果是复杂的数据库处理的话,一般写个方法封装起来,servlet只是从方法的返回值进行,判断和操作。
      

  18.   

    校验用actionForm,写个validate方法,
    xml中设置validate属性=true
      

  19.   

    [color=#FF0000][/高手,高高手,顶![color]
      

  20.   

    你可以这样理解,除了显示层(jsp文件和一些页面相关文件)和控制层(Action类)外其它的都可以说是Model层,而Model层又可以分成业务逻辑层和持久层,感觉这些只要了解就可以了,不需要深追
      

  21.   

    JSP页面直接进行验证(非空与长度等),不必要放入SERVLET中
      

  22.   

    应该交给业务层处理   然后业务层里面的 数据 交给dao层
      

  23.   

    QQ群 38692105 诚招中国IT精英 进群需笔试!~~
      

  24.   

    何不换一个想法想想。MVC有时谁也说不清
      

  25.   

    控制层和业务层确实比较难划分界线,其实也没必要太在意他俩之间的界线,划分三层又不是死的,有的在开发当中又是分四层,有的在控制层和业务层之间加一个抽象层(接口,业务层实现这些接口),跟spring整合的时候,有可以用spring容器来管理所有的Action等等,应该在具体的开发当中,选择合适的办法,但不管选择什么方法,本人认为应该遵循:高内聚,弱耦合(很多java书中和java设计模式都提倡的的思路),这样若需要修改程序、扩张程序功能都是比较方便的