How to do the model part in a Spring MVC?
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 t开发者_运维百科he 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.
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
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.
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?
精彩评论