| « | November 2025 | » | | 日 | 一 | 二 | 三 | 四 | 五 | 六 | | | | | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | | | | | | | |
| 公告 |
戒除浮躁,读好书,交益友 |
| Blog信息 |
|
blog名称:邢红瑞的blog 日志总数:523 评论数量:1142 留言数量:0 访问次数:9731794 建立时间:2004年12月20日 |

| |
|
[j2ee]spring对于web编辑页面中POJO保持和传递的做法带来的问题 原创空间, 软件技术
邢红瑞 发表于 2005/4/25 13:08:48 |
| 这是个老问题,不光是spring,所有mvc都必须处理这个问题.一般的做法是构造一个的commandObject记录需要修改的属性,并且记录主键id。大致流程是,先load POJO,copy属性到commandObject,页面修改了后,根据主键id再load一次POJO,然后copy属性一次,再update,所以在update之前必须select一次.通用的解决办法是把POJO放到httpSession中,页面里直接对httpSession里的POJO操作,当进行save操作的时候 从httpSession里拿到的POJO,就能直接用hibernateSession.update回数据库 ,因为hibernate的PO可以脱离hibernateSession然后再次进入,不用构造commandObject,让POJO直接传递到View再回到Controller。spring mvc已经实现了相应的功能,我们可以直接把hibernate的PO作为commandObject类传递.
在spring的AbstractFormController.java中把commandObject放进httpSession的代码 protected final ModelAndView showForm(HttpServletRequest request, BindException errors, String viewName, Map controlModel) throws Exception { if (isSessionForm()) { request.getSession().setAttribute(getFormSessionAttributeName(), errors.getTarget()); } Map model = errors.getModel(); Map referenceData = referenceData(request, errors.getTarget(), errors); if (referenceData != null) { model.putAll(referenceData); } if (controlModel != null) { model.putAll(controlModel); } return new ModelAndView(viewName, model); }
从httpSession里得到commandObject的代码 protected final Object getCommand(HttpServletRequest request) throws Exception { if (!isSessionForm()) { return formBackingObject(request); } HttpSession session = request.getSession(false); if (session == null) { throw new ServletException("Must have session when trying to bind"); } Object formObject = session.getAttribute(getFormSessionAttributeName()); session.removeAttribute(getFormSessionAttributeName()); if (formObject == null) { throw new ServletException("Form object not found in session"); } return formObject; } spring里带的petclinic可以说明这个问题
public class EditOwnerForm extends AbstractClinicForm {
public EditOwnerForm() { // need a session to hold the formBackingObject setSessionForm(true); // initialize the form from the formBackingObject setBindOnNewForm(true); }
/** Method forms a copy of an existing Owner for editing */ protected Object formBackingObject(HttpServletRequest request) throws ServletException { // get the Owner referred to by id in the request return getClinic().loadOwner(RequestUtils.getRequiredIntParameter(request, "ownerId")); }
/** Method updates an existing Owner. */ protected ModelAndView onSubmit(Object command) throws ServletException { Owner owner = (Owner) command; // delegate the update to the Business layer getClinic().storeOwner(owner);
return new ModelAndView(getSuccessView(), "ownerId", owner.getId()); }
}有几个要说明的地方1.setSessionForm(true);//申明为一个sessionForm,spring的mvc就是用session来记录需要传递的对象的 2.formBackingObject方法,用于返回原始数据,返回的Object会成为commandObejct,spring的mvc里会把commandObject放在session里,页面里可以用command变量获得该object 3.Owner owner = (Owner) command;//如果把form设置为session范围时,在提交的时候是从session取出PO的action调用的时候就会自动把commandObject传回来,不是从数据库中! 在petclinic同时编辑两个owner时会出错.使用session方式,必须在页面设计时限制用户无法同时打开多个编辑窗口(就是不能同时编辑多个PO).否则就要用select&update,虽然在效率上有一定的损失.只用于编辑页面,可以省去很多麻烦.
|
|
|