我正在使用 Spring MVC 2.5,我正在尝试获取一个 JSTL 表单对象以从 GET 请求加载。我将 Hibernate POJO 作为我的支持对象。
请求中有一个页面指向另一个页面,其中有一个class id(行主键)。该请求看起来像“newpage.htm?name=RowId”。这将进入一个带有表单支持对象的页面,
上面的新页面,将对象的字段加载到可编辑字段中,并填充行的现有值。这个想法是,您应该能够编辑这些字段,然后将它们保存回数据库中。
这个页面的 View 看起来像这样
<form:form commandName="thingie">
<span>Name:</span>
<span><form:input path="name" /></span>
<br/>
<span>Scheme:</span>
<span><form:input path="scheme" /></span>
<br/>
<span>Url:</span>
<span><form:input path="url" /></span>
<br/>
<span>Enabled:</span>
<span><form:checkbox path="enabled"/></span>
<br/>
<input type="submit" value="Save Changes" />
</form:form>
Controller 里面有这个,
public class thingieDetailController extends SimpleFormController {
public thingieDetailController() {
setCommandClass(Thingie.class);
setCommandName("thingie");
}
@Override
protected Object formBackingObject(HttpServletRequest request) throws Exception {
Thingie thingieForm = (Thingie) super.formBackingObject(request);
//This output is always null, as the ID is not being set properly
logger.debug("thingieForm.getName(): [" + thingieForm.getName() + "]");
//thingieForm.setName(request.getParameter("name"));
SimpleDAO.loadThingie(thingieForm);
return thingieForm;
}
@Override
protected void doSubmitAction(Object command) throws Exception {
Thingie thingie = (Thingie) command;
SimpleDAO.saveThingie(thingie);
}
}
正如您从注释代码中看到的那样,我已经尝试从请求中手动设置对象 ID(名称是这种情况)。但是,当我尝试将数据保存在表单中时,Hibernate 提示对象被取消同步。
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)
这个错误似乎对整个 session 有影响,它停止为我的整个 Web 应用程序工作,不断抛出上面看到的陈旧对象状态异常。
如果任何熟悉 Spring MVC 的人可以帮助我解决这个问题或提出解决方法,我将不胜感激。
编辑:
session 工厂代码。
private static final SessionFactory sessionFactory;
private static final Configuration configuration = new Configuration().configure();
static {
try {
// Create the SessionFactory from standard (hibernate.cfg.xml)
// config file.
sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
} catch (Throwable ex) {
// Log the exception.
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
最佳答案
使用 Spring MVC + hibernate 的主要缺陷之一是自然的方法是使用 hibernate 域对象作为表单的支持对象。默认情况下,Spring 将根据名称绑定(bind)请求中的任何内容。这无意中包含了 ID 或名称(通常是主键)或其他正在设置的 hibernate 管理属性。这也使您容易受到表单注入(inject)的攻击。</p>
为了在这种情况下安全,您必须使用类似的东西:
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder)
throws Exception {
String[] allowedFields = {"name", "birthday"}
binder.setAllowedFields(allowedFields);
}
并明确地将允许的字段设置为仅在您的表单中的字段,并排除主键,否则您将一团糟!!!
关于java - Spring MVC,从请求生成表单支持对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/697778/