I have a Spring form which is called AddNewItemForm and contains the validation annotations.
This form is the parameter of my Spring RestController addNewItem() method and it will be validated, the results being stored in BindingResults.
From my controller I need to call the service. Here is my question. Is it ok to have a method inside my service with this signature
public Item add(AddNewItemForm form)
or is it better to have it like
public Item add(Item item)
I am thinking that the form is only needed for the controller validation but the service doesn't need to know about it. It just needs to know how to operate with entities.
I suppose that I should construct my Item in the controller, with all the data I have and then pass this item to the service add(item) method.
Am I right?
Think of it in terms of dependencies: your web layer always needs to know about your service module and by passing the AddNewItemForm (which I assume exists in your web module/package) back to your service you now have a circular dependency.
Dependencies should only flow downwards:
Repository > Service > Web
From my point of view the service should not know about your command object (AddNewItemForm) since they are totally independent.
I agree with your last suggestion, you have to construct your model object before calling your service. Basically in your controller or with the help of an utility class.
Related
Newbie question...
I'm building my first Spring Boot restful service and want to support a GET call that returns a collection of entities. like:
/api/customers/
However, for certain consumers -like a list page in a web UI - they would only need a subset of the customer entity properties.
I'm thinking that I could add request parameters to my GET call to set the consumers specific field requirements, like
/api/customers/?fields=id,name,address
But what's the best way of implementing this inside the Java restful controller?
Currently in my rest controller the 'GET' is request mapped to a Java method, like
#RequestMapping(value="/", method= RequestMethod.GET)
public Customer[] getList() {
Customer[] anArray = new Customer[];
....
return anArray;
}
Is it possible to somehow intervene with the default Java to Json response body translation so that only the required properties are included?
TIA
Adding fields parameter is a good idea, best practice according to http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api#limiting-fields
How to leave fields out?
1) Set them to null, possibly in a dedicated output class annotated with #JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
Or
2) Use SimpleBeanPropertyFilter See a good step by step tutorial here 5. Ignore Fields Using Filters
I understand the MVC Pattern and also how Spring MVC implements it.
However, how do the Rest controller, Data Access Layer and Service Layer fit into this pattern?
Is it:
Model = Database (e.g. Oracle/MySQL) and Repositories classes
Controller = Service (buisness logic) and Rest Controller classes
View = JSP / FreeMarker?
Model - is not a Database, is not a Repositories, is not an Entity. Model is abstraction, that contains all data, that is needed to be displayed. And every View has it's own model. You can consider Model as container for data between Controller and View.
In Spring model is ModelMap parameter of method of controller.
Controller - prepares Model, to pass it to View. If model is quite simple, Controller can do it by itself.
But most of models contains a lot of data. This can be multiple Entities from database, data from configuration etc. In this case Controller use lower level tier: Service, Repository. They all help the Сontroller to build model for View.
upd: It is a purpose of Controller to connect View and Model. Controller creates and fills the Model, then chooses View and pass this created Model to the View. That's how Model and View get connection.
In Spring controllers are Controller and RestController.
View - is final point where data from Model (passed by Controller) will be displayed to user. But another role of View is get commands from user, and pass it to Controller.
In Spring this may be view of any view-engine: JSP,Freemaker,Thymeleaf.
Note: usually, Controller does not use Repository directly. Traditionally, Controller works with Service, and Service uses Repository to get data from database. So relations are following: View<-Controller->Service->Repository
A controller accepts HTTP requests and often loads or save some data (from a service or DAO), and return an HTTP response. This response could be a redirect, or a view, or some JSON or a binary file.
A controller can use services, but should avoid having much logic of its own. It can also directly use data access objects, if there's no service logic required.
The model is whatever info a view needs to do its job. It is not necessarily related to a database. For example, you could have a model in a registration form, with email address and confirmEmailAddress fields. You don't store a confirmEmailAddress field in your db, so they there is not a 1-to-1 relationship between db tables and models. Also, your model could be data for a simple calculation that is not persisted.
So let me make sure I understand ...
The user interacts with an interface to view or submit data. The user calls on the interface to view some data. That call (an HTTP Request) goes to the Dispatcher Servlet (DS).
The DS then consults the handler mapping to help it decide which Controller to use.
Once chosen, the DS passes the request onto the Controller which calls the appropriate service methods, based on GET or POST. The Service method may need to interact with a Repository, which can interact with non-volatile storage (database, XML file, text file, etc), to construct a model based on defined business logic. Once complete, the model data is returned to the DS.
The DS then consults the View Resolver on which view should be used. The View Resolver picks a defined view for the request.
The DS then forwards the request onto the View, which is presented to the user.
I want to know the use of service classes in J2EE.
I have 2 projects.
One is in spring hibernate integration.That project contain DAO,MODEL,SERVICE and CONTROLLER.Within that The request is access by the controller and send to the values to the dao class through the service class.
2nd project contain only BEAN,CONTROLLER and DERIVED classes.Within that the request is access by the controller and send the values directly to the derived class.Query is written in this derived class.
I want to know the difference between these two projects. Why we use service class ?
in my experience, service class contains all business , calculate, logic
for example in login module :
base on MVC pattern
Model class (DAO,MODEL is call model) : User, UserDAO
Controller : UserController
View : LoginPage
That's doesn't mean we cannot create another class like Service
we can have UserBusinessthis class contain all method, logic realted to User like validateUserLogin ... etc
application may work like :
User access LoginPageinput value and submit => UserController=> UserBusiness=> UserDAO
we need divide to easy handle and maintain
In spring we have some annotation like
#Business
#Repository
#Controller
that is a maker spring will create a object , we no need to using "new" keyword.
Controllers: are used to just delegating the calls, meaning once the request arrive on controller it will forward it to relative service
Services: Service are develop to write the business logic in general.
Dao: Data transfer object, which intend to deal with the DTO's
So, Briefly, when Spring MVC receive a call. I will lend to controller, controller than redirects it to respective service. Service performs business login if any on the api call and than delegated data updation to DAO layer.
On the surface, a bit of a strange question! but I am creating a web app that uses both webflow and traditional Spring MVC controllers.
From one of the webflow views, a http request (ajax) is made from the client to a spring controller. When this was originally coded it didnt have much of a logical connection to the webflow, but now things have moved on and the controller could really do with knowing what screen (view-state) the request has come from.
My controller method signature looks like this:
#RequestMapping(value="/AjaxStuff", method=RequestMethod.POST)
public String ajaxStuff(#ModelAttribute("quote") QB2MotorQuote p_quote, BindingResult p_bindingResult,
HttpServletRequest p_req, Model p_model, DefaultMessageContext p_messages) {
I know from some of my webflow action classes that I can get the current state from the RequestContext object:
public Event checkDeclines(RequestContext p_ctx) throws Exception {
// get the current state
StateDefinition state = p_ctx.getCurrentState();
I've never really understood the 'voodoo' :) that Spring does where it can automagically inject parameters just by specifying them on the method signature (surely it can only inject things it knows about ??). I've tried simply changing the method signature of my controller method to inject in the RequestContext (in the vain hope that it will get injected), but it doesn't. It complains that RequestContext is an interface.
So, does anyone know how I can make my controller know about the current webflow state - either through injecting something into the controller method signature, or perhaps I can get it from the http request somehow (or session, which I can get from the request).
Any help with this very much appreciated.
inside your webflow view, you should have access to a variable ${flowRequestContext} that you can use in your ajax call.
you can just get the piece of information ${flowRequestContext.currentState} you want from it and add it as a parameter.
you cannot have the requestContext directly injected as your are not in a webflow environment. If you were, you could directly use RequestContext.getRequestContext(). Try calling it from your MVC controller and you will get null. Try from within a flow and you will get it.
Lets assume a simple Spring MVC Controller that receives the ID of a domain object. The Controller should call a service that should do something with that domain object.
Where do you "convert" the ID of the domain object into the domain object by loading it from the database? This should not be done by the Controller. So the service method interface has to use accept the ID of the domain object instead of the domain object itself. But the interface of the service would be nicer if it takes the domain object as a parameter.
What are your thoughts about this common use case? How do you solve this?
The controller should pass the id down into the service layer and then get back whatever is needed to render the rest of the HTTP response.
So -
Map<String,Object> doGet (#RequestParam("id") int id) {
return serviceLayer.getStuffByDomainObjectId(id);
}
Anything else is just going to be polluting the web layer, which shouldn't care at all about persistence. The entire purpose of the service layer is to get domain objects and tell them to perform their business logic. So, a database call should reside in the service layer as such -
public Map<String,Object> getStuffByDomainObjectId(int id) {
DomainObject domainObject = dao.getDomainObjectById(id);
domainObject.businessLogicMethod();
return domainObject.map();
}
in a project of mine I used the service layer:
class ProductService {
void removeById(long id);
}
I think this would depend on whether the service is remote or local. As a rule I try to pass IDs where possible to remote services but prefer objects for local ones.
The reasoning behind this is that it reduces network traffic by only sending what is absolutely necessary to remote services and prevents multiple calls to DAOs for local services (although with Hibernate caching this might be a mute point for local services).