Spring MVC,从请求中生成一个表单支持对象? [英] Spring MVC, generating a form backing object from a request?

查看:74
本文介绍了Spring MVC,从请求中生成一个表单支持对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是Spring MVC 2.5,我试图从GET请求中获取一个JSTL表单对象来加载。我有Hibernate POJO作为我的支持对象。



有一个页面指向请求中带有类id(行主键)的另一个页面。该请求看起来像newpage.htm?name = RowId。这将进入带有窗体支持对象的页面,



上面的新页面将对象的字段加载到可编辑字段中,并填充行的现有值。这个想法是,你应该能够编辑这些字段,然后将它们保存到数据库中。



这个页面的视图看起来像这样

 < form:form commandName =thingie> 
< span>名称:< / span>
< span>< form:input path =name/>< / span>
< br />
< span>计划:< / span>
< span>< form:input path =scheme/>< / span>
< br />
< span>网址:< / span>
< span>< form:input path =url/>< / span>
< br />
< span>已启用:< / span>
< span>< form:checkbox path =enabled/>< / span>
< br />

< input type =submitvalue =保存更改/>
< / form:form>

控制器有这个功能,



<$公共类thingieDetailController扩展SimpleFormController {

public thingieDetailController(){
setCommandClass(Thingie.class);
setCommandName(thingie);
}

@Override
protected Object formBackingObject(HttpServletRequest request)throws Exception {
Thingie thingieForm =(Thingie)super.formBackingObject(request);

//这个输出总是为空,因为ID没有被正确设置
logger.debug(thingieForm.getName():[+ thingieForm.getName()+] );
//thingieForm.setName(request.getParameter(\"name));
SimpleDAO.loadThingie(thingieForm);

返回thingieForm;
}

@Override
保护void doSubmitAction(Object command)抛出Exception {
Thingie thingie =(Thingie)命令;
SimpleDAO.saveThingie(thingie);


code


$ b

正如你从注释代码中看到的那样,已经尝试从请求中手动设置对象ID(名称是这种情况)。然而,当我尝试并持久化表单中的数据时,Hibernate抱怨被拒绝的对象。

  org.hibernate.StaleObjectStateException:Row被另一个事务更新或删除(或未保存的值映射不正确)

这个错误似乎是如果有人熟悉Spring MVC可以帮助我的话,那么可以在整个会话中停止工作,从而停止为我的整个Web应用程序工作,并不断抛出上面看到的Stale Object State Exception。

这或建议一种解决方法,我真的很感激。



编辑:

会话工厂代码 p>

  private static final SessionFactory sessionFactory; 
private static final Configuration configuration = new Configuration()。configure();

static {
try {
//从标准(hibernate.cfg.xml)
// config文件创建SessionFactory。
sessionFactory = new AnnotationConfiguration()。configure()。buildSessionFactory();
} catch(Throwable ex){
//记录异常。
System.err.println(Initial SessionFactory creation failed。+ ex);
抛出新的ExceptionInInitializerError(ex);



public static SessionFactory getSessionFactory(){
return sessionFactory;
}


解决方案

使用Spring MVC + hibernate是自然的方法是使用hibernate域对象作为表单的后台对象。 Spring会根据DEFAULT的名字在请求中绑定任何东西。这无意中包含诸如ID或名称(通常是主键)或其他hibernate托管属性的设置。这也使得你容易受到注入。



为了在这种情况下保持安全,你必须使用类似于:

  protected void initBinder(HttpServletRequest请求,ServletRequestDataBinder绑定)
抛出异常{
String [] allowedFields = {name,birthday}
binder.setAllowedFields(allowedFields);
}

并明确地将ALLOWED字段设置为仅限于表单中的字段,主键或者你最终会陷入混乱!!!


I am using Spring MVC 2.5, and I am trying to get a JSTL form object to load from a GET request. I have Hibernate POJOs as my backing objects.

There is one page directing to another page with a class id (row primary key) in the request. The request looks like "newpage.htm?name=RowId". This is going into a page with a form backing object,

The newpage above, loads the fields of the object into editable fields, populated with the existing values of the row. The idea is, that you should be able to edit these fields and then persist them back into the database.

The view of this page looks something like this

<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>

The controller has this in it,

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

As you can see from the commented code, I've tried manually setting the object id (name is this case) from the request. However Hibernate complains about the object being desynched when I try and persist the data in the form.

org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)

This error seems to do something to the entire session, which stops working for my entire web application, continually throwing the Stale Object State Exception seen above.

If anyone familiar with Spring MVC can help me with this or suggest a workaround, I would really appreciate it.

EDIT:
Session factory code.

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

解决方案

One of the major flaws with using Spring MVC + hibernate is that the natural approach is to use the hibernate domain object as the backing object for the form. Spring will bind anything in the request based on name by DEFAULT. This inadvertently includes things like ID or name (usually the primary key) or other hibernate managed properties being set. This also makes you vulnerable to form injection.

In order to be secure under this scenario you must use something like:

protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) 
throws Exception {
 String[] allowedFields = {"name", "birthday"}
 binder.setAllowedFields(allowedFields);
}

and EXPLICITLY set the ALLOWED fields to only those in your form, and exclude the primary key or you will end up with a mess!!!

这篇关于Spring MVC,从请求中生成一个表单支持对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆