Design question for using Business Objects as formBackingObjects in a Spring SimpleFormController.
Our controller's responsibility is to allow an End User to add a new Business Object to our web application.
So we are passing our Business Object though the formBackingObject(HttpServletRequest request) method. However, we've run into a conundrum.
The factory that we are using to create our new Business Object enforces the business rules that some of the attributes cannot be null. But since we don't know what the End User wants to enter we've been passing in "reasonable defaults" like "Please enter the name you want", but that seems hackie/icky at best.
What is a developer to do? I feel as though this is the classic chicken/egg problem.
All our Business Object are based off of Interfaces, should we create a Stub that represents the Business Object, pass the Stub as the formBackingObject, and then pass the Stub to the Factory on a Form submit? Or should we not pass anything in the formBackingObject and then manually gather the submitted information from the request?
Any other reasonable ideas/patterns?
Thank you for your time.
I definitely wouldn't choose the option of not using a formBackingObject and gathering the information manually -- that would eliminate a lot of the power that makes Spring MVC worthwhile in the first place.
If I were you, I would just make a new factory, or factory method, that is designed specifically to create an "uninitialized" business object, and use that as your formBackingObject.
Another approach that is widely used is not to use a business object as your formBackingObject at all, but create a separate transport object whose only purpose is to be the formBackingObject (and then add a factory method for your business object that lets you initialize it from the transport object). One of the big advantages of this is if your business object has a deep tree of other objects inside it, this can make it a pain to use as a formBackingObject. If you create a separate transport object just for use as a formBackingObject, you can give it a much flatter structure.
Use a command object (a dead simple POJO) to represent the user's input to your controller. Then you can use the validation built-in to Spring MVC to make sure that all of the required fields are supplied in the command object. If the command passes validation, then you can map it to a your "Business Object" programatically (or using a bean mapping library like Dozer).
This way you can handle validation, incomplete user submissions, etc., without touching or modifying any existing business logic / rules / service classes. This allows you to keep the web layer separate from these existing layers.
For reference, see the MVC tutorial, which touches on validation and command objects in Part 4.
Related
We got this design:
Rest Controller -> Calling Service -> Calling JPA DAOs
Let say we save employee. And we have a requirements to validate employee name.
IEmployeeService.saveEmployee(Employee emp)
EmployeeController.saveEmployee(Employee emp)
Option 1: I can inject JSR303 annotations on Employee and Let Rest Controller validate it as part of automatic validation.
Option 2: I validate in service method and raise exception and let controller to return proper JSON of that exception.
Seems like service should have validation anyways... but in presence of JSR303 annotations controller is doing everything, hence there seem to be duplication of logic if service does those checks as well.
How do you approach? Everybody's comments welcome and will be appreciated.
Thanks
Babar
IMHO, the standard way is to use both Opt 1 and Opt 2.
But, you have to define what's going to be validated in each layer.
This is my favorite approach:
Validate field constraints in Controller. This include: Date format, string length, min, max, null... validation
Validate business logic constraint in Service. Include: Unique, exist check, from date < to date, max items per group of entities...
One side note: Entity should never been exposed to outside world. We should have some kind of converter logic to convert entity to output JSON/model
Ideally your web facing part should have your validation logic implemented. The service layer should be purely for the business part of project. It is also security best practice before it reach to your service layer code. Nowadays people do mix-up layer and want to do everything in same layer. The jsr-303 annotation are bean level validation. So normally it is applied at a place where model comes into picture.
So you can do that at
controller layer: to validate your input and other min/max range and basic validation.
service layer: To have any specific validation at service layer by Autowiring javax.validation.Validator.
I would do both.
In your example you seem to have both methods refer to Employee, which might be possible in very simple scenarios, but in practical scenarios this is not.
It is more likely that you are going to have an EmployeeDTO which has JSON properties mapped to Java object fields. You might even have more specific DTOs to specific employee operations (for example change password), depending on what forms your UI is exposing. This will be received by your controller, and JSR303 can help do syntactic validations, like checking the string is not empty, that a name does not contain numbers etc.
The DTO should not bleed in to the service, but its data should be translated to whatever the service is expecting, which should be decoupled from the inputs of the controller.
Your Service will then receive an Employee. This could be a JPA Entity if it makes sense, or some other intermediate domain object related to the operation being performed. The creation of the Employee should ideally already enforce some simple checks (for example non null checks), to ensure that the object is consistent after construction. The service itself should then validate what it is receiving, independently of what the controller validates. The service could be used by other controllers, or invoked by other services in the future, so you should always program defensively. The service could also do more logical checks (for example does another employee with the same ID but different details exist? etc.) This will do business logic validation that will enforce further robustness.
If you see a lot of common code between the DTO and the Entity, or intermediate objects, there are also mapper utility libraries which can help you avoid repetition, like MapStruct.
I have looked up a lot of information about the DAO pattern and I get the point of it. But I feel like most explainations aren't telling the whole story and by that I mean where would you actually use your DAO. So for example if I have a User class and a corresponding UserDAO that is able to save and restore users for me, which is the correct way:
The controller creates the User object and passes it to the UserDAO to save it to the database
The controller creates the User object and in its constructor the user object makes a call to the userDAO in order to save itself into the database
This is a code smell and you are missing an extra class "UserManager" which the controller will ask to create the user. The UserManager is responsible for creating the user and asking the UserDAO to save it
I really feel like the third option is the best, because all that the controller is responsible for is delegating the request to the correct model object.
What is your favorite way? Am I missing something here ?
From my experience with DAOs, the first approach is the only correct one. The reason is that it has the clearest responsibilities and produces the least clutter (well, some very respectable programmers regard DAOs themselves as clutter. Adam Bien sees the original DAO pattern already implemented in the EntityManager and further DAOs to be mostly unnecessary "pipes")
Approach 2 binds the model to the DAO, creating an "upstream dependency". What I mean is that usually the models are distributed as separate packages and are (and should be) ignorant of the details of their persistence. A similar pattern to what you are describing is the Active Record pattern. It is widely used in Ruby on Rails but has not been implemented with equal elegance and simplicity in Java.
Approach 3 - what is supposed to be the point of the UserManager? In your example the Manager performs 2 tasks - it has the duties of a User factory and is a proxy for persistence requests. If it is a factory and you need one, you should name it UserFactory without imposing additional tasks on it. As for the proxy - why should you need it?
IMHO most classes named ...Manager have a smell. The name itself suggests that the class has no clear purpose. Whenever I have an urge to name a class ...Manager, it's a signal for me to find a better fitting name or to think hard about my architecture.
For the first approach; IMHO, controller calling a method on a DAO object is not a good design. Controllers must be asking "service" level objects about business. How these "services" persist the data is not a concern for the controller.
For the second approach; sometimes you may want to just create the object, so constructor duty and persisting duty must not be tightly coupled like this.
Lastly, the manager or the service objects is a good abstraction for the layered architecture. This way you can group the business flows in the appropriate classes and methods.
But for Play, companion objects of case classes are also a good candidate to use as DAO. The singleton nature of these objects make it a good candidate.
case class TicketResponse(appId: String, ticket: String, ts: String)
object TicketResponse{
implicit val ticketWrites = Json.writes[TicketResponse]
def save(response: TicketResponse) = {
val result = DB.withConnection {
implicit connection =>
SQL("insert into tickets(ticket, appid, ts)"
+ " values ({ticket},{appid},{ts})")
.on('ticket -> response.ticket, 'appid -> response.appId, 'ts -> response.ts).executeInsert()
}
}
}
The Data Access Object (DAO) should be used closer to the data access layer of your application.
The data access object actually does the data access activities. So it is part of data access layer.
The architecture layers before DAO could vary in projects.
Controllers are basically for controlling the request flow. So they are kind of close to UI.
Although, a Manager, Handler is a bad idea, we could still add a layer between controller and DAO. So controller will pre-process the data that is coming from a request or going out (data sanity, security, localization, i18n, transform to JSON, etc). It sends data to service in the form of domain objects (User in this case). The service will invoke some business logic on this user or use it for some business logic. And it would then pass it to DAO.
Having the business logic in controller layer is not good if you are supporting multiple clients like JSPs, WebServices, handheld devices, etc.
Assuming Controller means the "C" in MVC, your third option is the right approach. Generally speaking Controller code extends or follows the conventions of a framework. One of the ideals of MVC is swapping frameworks, which is really the Controller, should be relatively easy. Controllers should just move data back and forth between the model and view layers.
From a model perspective, Controllers should interact with a service layer - a contextual boundary - in sitting front of the domain model. The UserManager object would be an example of a piece that you would consider part of your service layer - that is the domain model's public API.
for typical webapp i will prefer play framework with play's JPA and database implementation. It much more productive way.
please take a look here http://www.playframework.org/documentation/1.2.5/jpa
and here
http://www.playframework.org/documentation/1.2.5/guide1 and http://www.playframework.org/documentation/1.2.5/guide2
That's it))
I'm developing spring MVC application and I used AirPortForm.java to get information in my airport.jsp. But I'm just wandering what is the standard method do I need to use AirPortDTO.java instead of AirPortForm.java kindly advice me.
Many thanks.
The Form suffix usually indicates that the object is meant to contain values coming from an HTML form (Spring calls these command objects).
The DTO suffix indicates that the object is a Data Transfer Object. A Data Transfer Object is an object, usually without much logic, which is used to carry information between the presentation layer and the service layer.
Use the appropriate suffix for you use-case, or use another one or not at all if your object is neither a form nor a DTO.
DTO use to transfer data between your database and application. Model View Controller (MVC) is one of the design pattern that separate your application with different layers. DTO is in model layer.In your application, you can use AirportFrom.java class only but it is not good practice.
In my Spring MVC application I am using DTO in the presentation layer in order to encapsulate the domain model in the service layer. The DTO's are being used as the spring form backing objects.
hence my services look something like this:
userService.storeUser(NewUserRequestDTO req);
The service layer will translate DTO -> Domain object and do the rest of the work.
Now my problem is that when I want to retrieve a DTO from the service to perform say an Update or Display I can't seem to find a better way to do it then to have multiple methods for the lookup that return different DTO's like...
EditUserRequestDTO userService.loadUserForEdit(int id);
DisplayUserDTO userService.loadUserForDisplay(int id);
but something does not feel right about this approach. Perhaps the service should not return things like EditUserRequestDTO and the controller should be responsible of assembling a requestDTO from a dedicated form object and vice versa.
The reason do have separate DTO's is that DisplayUserDTO is strongly typed to be read only and also there are many properties of user that are entities from a lookup table in the db (like city and state) so the DisplayUserDTO would have the string description of the properties while the EditUserRequestDTO will have the id's that will back the select drop down lists in the forms.
What do you think?
thanks
I like the stripped down display objects. It's more efficient than building the whole domain object just to display a few fields of it. I have used a similar pattern with one difference. Instead of using an edit version of a DTO, I just used the domain object in the view. It significantly reduced the work of copying data back and forth between objects. I haven't decided if I want to do that now, since I'm using the annotations for JPA and the Bean Validation Framework and mixing the annotations looks messy. But I'm not fond of using DTOs for the sole purpose of keeping domain objects out of the MVC layer. It seems like a lot of work for not much benefit. Also, it might be useful to read Fowler's take on anemic objects. It may not apply exactly, but it's worth thinking about.
1st Edit: reply to below comment.
Yes, I like to use the actual domain objects for all the pages that operate on a single object at a time: edit, view, create, etc.
You said you are taking an existing object and copying the fields you need into a DTO and then passing the DTO as part of the model to your templating engine for a view page (or vice-versa for a create). What does that buy you? The ref to the DTO doesn't weigh any less than the ref to the full domain object, and you have all the extra attribute copying to do. There's no rule that says your templating engine has to use every method on your object.
I would use a small partial domain object if it improves efficiency (no relationship graphs to build), especially for the results of a search. But if the object already exists don't worry about how big or complex it is when you are sticking it in the model to render a page. It doesn't move the object around in memory. It doesn't cause the templating engine stress. It just accesses the methods it needs and ignores the rest.
2nd edit:
Good point. There are situations where you would want a limited set of properties available to the view (ie. different front-end and back-end developers). I should read more carefully before replying. If I were going to do what you want I would probably put separate methods on User (or whatever class) of the form forEdit() and forDisplay(). That way you could just get User from the service layer and tell User to give you the use limited copies of itself. I think maybe that's what I was reaching for with the anemic objects comment.
You should use a DTO and never an ORM in the MVC layer! There are a number of really good questions already asked on this, such as the following: Why should I isolate my domain entities from my presentation layer?
But to add to that question, you should separate them to help prevent the ORM being bound on a post as the potential is there for someone to add an extra field and cause all kinds of mayhem requiring unnecessary extra validation.
Spring's form controller (such as SimpleFormController or BaseCommandController) uses commands to pass data between the HTML form and controller. My question is, is it common practice to use the backing model as the command itself? Or is it common to create a separate command with correspond attributes to those in the backing model.
My issue is that to use the backing model as the command, property editors are necessary for conversion of non-string attributes. Imagine a data model with many non-string strongly typed custom field types. On a form submission, property editor does the conversion before the validator is called. If the type conversion is not possible (user input error), then the validator never gets a chance to provide a detailed error message. All that's displayed on the HTML form is a generic error message. See my related Stackoverflow question.
The alternative is to create a separate command that duplicates each field in the backing model, but as a string. In this way the validator can validate the string representation of each field. The controller's onSubmit is then responsible for converting the text-based command to the backing model. From my research of Spring this appears to be intended usage. My hesitation to go down this path is the cumbersome manner in which a separate command needs to be created for each data model. Then there's the added work having to marshal between the command and the data model. It's so much more convenient to have the form directly edit the backing model and use property editors to do the conversion. The problem then is validation.
So I'm curious how others approach the issue of form-based editing of models that contain custom typed non-string fields.
I'd recommend that you look into the Spring binding and validation API. Bind the form elements into the objects that the service layer needs and have the controller pass them along.
My preference is to bind directly to business objects and not create DTOs just for the sake of the web tier. I don't like parallel hierarchies.
IMHO this boils down to how you want to design your domain classes. I prefer to design 'em qiute strict by not even allowing setting inapropriate values etc. This does not combine very well with the way Spring handles binding and validation.
As I want to avoid weakening my domain model I tend to use DTOs as command objects as typically the presentation gets a slightly different view on the domain objects anyway. The classic example is a User domain class that carries a password. In the presentation layer you typically would want to let the actual user the password twice and compare those values in validation step. Only if they match correctly the data would be bound to the domain class.
Might introduce a little overhead but allows to cleanly separate domain/application layer from the view.