Question

I have a Model class:

public class User{
    public String title;
    public String username;

    /* setter getter here */

    public String toString(){
        /* output title and username */
    }
}

Controller:

@RequestMapping("/dummy")
public class DummyController
{
    private log = Logger.getLogger(this.getClass().getName());

    @RequestMapping(value="binder")
    public String binderInput(Model model){ 
        UserLogin userInit=UserLogin.findUserLogin(1L);
        model.addAttribute("userLogin",userInit);               
        return "binderInput";   
    }

    @RequestMapping(value="binderResult")
    public String binderResult(@ModelAttribute("userLogin") UserLogin userLogin,BindingResult br){
        log.debug("userLogin:"+userLogin);
        return "binderResult";  
    }
}

And views (jspx) for binderInput:

<form:form action="dummy/binderResult" method="POST" modelAttribute="userLogin">
    title:<form:input path="title" />
    <input type="submit"/>
</form:form>

The DAO in UserLogin.findUserLogin(1L); will return user with title 'Mr' and username 'Smith'. I browse localhost:8080/myWeb/dummy and the views showed 'Mr' in title field, and then i update the title to 'Sir' and submit the form.

In binderResult i expect to see

title:Sir, username:Smith

but actually i got

title:Sir, username:null

Is there a way to keep the property value(s) from the DAO that not edited (for the field(s) not showed in the jspx view) ?

  1. I think of hidden field, but the username can be viewed when looking at html source and it can be manipulated so i think its cant be the solution.

  2. I have tried @SessionAttribute, i thought it is make sense the model is keeped in the session and then spring modelAttribute will only fill the properties that received from the views to the session model. But then it still the same, title change to Sir but the username is null.

  3. I read about @InitBinder and try
    dataBinder.setAllowedFields(new String[]{"title"});
    but its not help, it just filters the properties and not keep the value of the other not allowed fields

I start to think that i have to do it manually something like this:

    @RequestMapping(value="binderResult")
    public String binderResult(@ModelAttribute("userLogin") UserLogin userLogin,BindingResult br,HttpSession session){
        /* after put DAO model in session in binderInput */
        UserLogin userLoginSession = session.getAttribute("userLoginSession");
        userLoginSession.setUsername(userLogin.getUsername());
                    //further process or save userLoginSession
        log.debug("userLogin:"+userLoginSession);
        return "dummy/binderResult";    
    }


Is there a way to keep the not edited property in Spring like what i expect in the first place?

Thanks for any help!

=====================================================

Code for my 2nd point, asked by gouki:

@RequestMapping("/dummy")
@SessionAttributes({"userSession"})
public class Dummy2Controller
{
    private log = Logger.getLogger(this.getClass().getName());

    @RequestMapping(value="binder")
    public String binderInput(Model model,HttpSession session){ 
        UserLogin userInit=UserLogin.findUserLogin(1L);
        model.addAttribute("userSession",userInit);             
        return "binderInput";   
    }

    @RequestMapping(value="binderResult")
    public String binderResult(@ModelAttribute UserLogin userSession,BindingResult br,HttpSession session){
        log.debug("userSession:"+userSession);
        //further process or save userSession to DB
        return "binderResult";  
    }
}

and change modelAttribute to userSession in views:

<form:form action="dummy/binderResult" method="POST" modelAttribute="userSession">

=====================================================
PROBLEM SOLVED
Some link that i read related to accepted answer in this question:

  1. springsource docs
  2. stackoverflow explanation by @Christopher Yang
  3. Captain Debug's Blog
Était-ce utile?

La solution

You can add method, which will populate object before invocation of every controller method:

@ModelAttribute("userLogin")
public UserLogin getUserLogin() {
    return UserLogin.findUserLogin(1L);
}

After this loading changed fields from submitted form will override old values and in your controller you'll have refreshed object.

Autres conseils

Not directly related to your problem, and I would probably uses Max's approach first, but you can use Spring Webflow and it's conversation context to keep a copy of the object around:

http://static.springsource.org/spring-webflow/docs/2.0.x/reference/htmlsingle/spring-webflow-reference.html

Search for conversationScope, they don't provide a link directly to it.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top