views:

36

answers:

4

I'm learning SpringMVC 2 and i have a form that i need to bind to an object (the command). But what if i need this command object to be an interface so i can use different implementations for the object (of course all the implementations will have the same fields).

For binding a form that represents an Account i have this controller. Is it possible that i could bind the form to the Account Interface, so i can use it like a business bean after that ?

Or just tell me what are the best spring practices for a flow like: FORM -> do Business Logic -> Save to DB

public  class OpenAccountControllerSpring2
extends SimpleFormController {

private ClientDao clientDao;
private Account account;

public OpenAccountControllerSpring2() {
    setCommandClass( // dont know what to write here);
    setCommandName("newAccount");


}


protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response,
        Object command, BindException bindExp)
    throws Exception {
    try {
                    //here i just want to create a new Account, add it to a Client (Interface), then transform the Client into a database-bean and save it.

        int client_id = Integer.parseInt(request.getParameter("clientId"));
        Account account = (Account) command;
        Client client = Transformer.toBusinessHeavy(clientDao.getClient(client_id));
        client.addAccount(account);
        clientDao.updateClient(Transformer.toEntity(client));
    } catch (Exception err) {
        return new ModelAndView(this.getFormView());
    }

    return new ModelAndView(this.getSuccessView());
}

public void setClientDao(ClientDao dao) {
    this.clientDao = dao;
}


public void setAccount(Account account) {
    this.account = account;
}

}

A: 

I'm not really sure what your question is, but

  1. Sure, you can specify a form-backing object by its interface. The interface needs to include setter and getter methods for any properties you need to bind to form elements, that's all.
  2. Your command class is Account.
  3. In my opinion, it's better to configure things such as command class and command name within your application context, rather than programmatically.
  4. I'm not sure why you have an instance variable for Account within your controller, but you almost certainly don't want to do that. Your controller absolutely should not maintain state. Instead, what you want to do is override the formBackingObject method and create a new Account object (or retrieve the correct Account object for the current client) there; this will be called for each request.
JacobM
You tell Spring to bind the form to the command/account by specifying the commandClass(). But if i write: setCommandClass(Account.class) then Spring will tell me it cannot instantiate an interface. How do i do point 3. ?
Blitzkr1eg
On 4: i have a variable for Account withing my controller so i can inject the implementation into it. If i would't have it there i could not inject the implementation unless i had in my code (in formBackingObject() perhaps) a call to springContext.getBean(AccountImplementation) which i read it's not good practice.
Blitzkr1eg
Dependency injection is awesome, but it isn't appropriate for every case. If you're creating a new instance for every transaction (which you need to do for your command class, or you will have concurrency issues), that strikes me as the time to use "new". If you really don't want to use "new" in this situation, then inject a factory class, and call the factory class in formBackingObject to create the new Account.If you create your command instance in formBackingObject, then Spring shouldn't ever have to instantiate an instance itself, so it won't care that you've specified it by interface.
JacobM
A: 

Why are you learning Spring MVC 2 (much of which is now deprecated), rather than Spring MVC 3? The new annotation-driven controllers are much easier to work with, and allow a lot more flexibility in the way you write your controllers.

If you're interested in Spring MVC 3, here is a series of examples I wrote which might be helpful.

James Earl Douglas
i want to learn both 2 and 3. currently i think 2 is more used in production
Blitzkr1eg
+1  A: 

You should definitely skip Spring 2 MVC and go straight to Spring 3 MVC. It is a major evolutionary leap forward and will save you a lot of trouble. However, you will still run into the same problem trying to do what you want to do. Spring has to be able to instantiate the form command object, like it says in the exception you're getting. It cannot instantiate an interface, like it says. You'll have to try a different approach, which will likely involve more work on your part and less help from Spring MVC. You can just work with request parameter values directly and not use a command object. You will have to manually bind the parameters to your correct subclass instance. Or instead you could perhaps tru tp use a non-abstract base class for your subclasses. That way you could specify that class as the command object and Spring could instantiate it and bind values to it. You could do something similar by having a separate class that models your forms and is not in your existing class hierarchy. You'll have to translate that into your classes, though. You may also want to examine your object model and make sure you're really modeling things correctly. Generally if you are doing something funky that the standard tools don't support you are probably wandering off into bad territoy.

sdouglass
A: 

I have done it by using an interface, injecting it's implementation and implementing formBackingObject() where i get the information from the request and call the respective setters on the interface. This way i can keep the interface but i have to do just a little bit of binding work.

Blitzkr1eg