views:

60

answers:

3

Hi, I am working on a tutorial problem using Spring MVC, with another teammate for an internship. I'm not familiar with Spring (that's why I'm learning it)

We first wrote the code without any framework support, plain old hand-written MVC

We are using Spring 2.5, and integrated Hibernate, used the Autowire, Controller, Repository annotations etc.. I'm not interested in the view part yet. So we linked to the database, but the models remained the old models something like :

public class Client {

 private String name;
 private String bankAccount;

 public String getName() {
  return name;
 }

 public String getBankAccount() {
  return bankAccount;
 }

 public Client(String name, String bankAccount) {
  this.name = name;
  this.bankAccount = bankAccount;
 }
}

How is this model properly done as the 'M' part in the Spring 2.5 MVC? I'm thinking something among the lines of autowiring, and constructor injection and remaining immutable.

I just can't wrap my mind how this is properly done in the framework. Any help would be greatly appreciated, thanks.

+1  A: 

Your "old" models look POJO based, which is the core of Spring-MVC. In most cases what you can do is add your Model objects, or a view-specific rendition (DTO/Value-Object) to the Spring Model object (glorified hashmap) and access them in your view directly.

There's no special classes or other bits required.

In terms of immutability, injection, etc - that's a question of the design of your objects, if they represent objects/values that shouldn't change (e.g. Currency, Dates, etc) then normal immutability rules apply - typically one of your Spring service-classes would create them serving as either a factory or a repository.

Does that help clarify things?

jayshao
Yes, it does, thank you :), i was under the weird feeling that POJO is not right
theBlinker
+2  A: 

Basically your model is a way to communicate information to the view from the controller, so your model object is actually just fine the way it is, no changes neccessary. To use the framework with your model what you will do is something like this:

Your Controller:

@RequestMapping(value="/client/view")
public String viewClientPage(Model m) {

   Client c = new Client( "Jeffrey", "123456" );
   m.addAttribute( "client", c );
   return "[name of a client using view goes here]";

}

then you'll have a view that does something like this:

<h1>Name : ${client.name}</h1>
<h2>Account Number : ${client.account}</h2>

One thing to keep in mind for your models (yours do this already) is that you will need getters for properties that you wish to show through the expression language ${client.name} is mapped to client.getName(), you can't do something like ${client.getAccount(2)} to get the third account that they have

walnutmon
This is the way we eventually done it, thank you
theBlinker
+1  A: 

Configure your models to be persisted

If they indeed should be persisted there, you will most likely do this with JPA/Hibernate and some annotations:

@Entity @Table(name="person")
public class Person extends AbstractEntity {

  private long id;
  private String email;

  @Id
  @Column(name="id")
  public long getId() { return this.id; }

  @Column(name="email")  
  public String getEmail() { return this.email; }

  // also setters, but they don't need annotations
}

note that you can avoid some annotations by following conventions, but you might want to avoid that while you learn, as it can be hard to get working and comes with cryptic errors that are hard to track down; bet to start explicit with Spring

Non-persisted models

Design these similarly, except you don't need DB annotations. I would recommend putting them in another package to make it clear what your models are for. You might not have any of these, depending on the problem you are solving

Make the available to the view

The simplest way is to make your controller methods of this form:

@RequestMapping(value="/person/{id}")
public ModelAndView handleRequest(@PathVariable long personId) {
    Person p = findPerson(id);
    return new ModelAndView("view name goes here")
      .addAttribute(p); // bean is automatically named "person"
}

To make this work, you will have to configure a DefaultAnnotationHandlerMapping in your dispatcher-servlet.xml to make this work.

davetron5000
Thanks persisted models where no problem, we coded those like that, i had a weird feeling for the non-persisted ones. Thank you for the reply
theBlinker