DTO in spring mvc - spring

I'm using spring mvc.
I have created the controller, view, pojo, dao.
Now I have the need to create an object composted from multiple objects pojo, is the case of creating a DTO?

If you're looking to build a composite kind of Object for view purposes only, then there is a good argument for a DTO. If the composite is just an aggregation of the POJOs you can use org.springframework.ui.Model and just add attributes inside your Controller. If there is logic and business rules that need to be applied, it is probably best to do this in a Service layer that sits between your Controller and your DAO.

If you mean that you need to access properties of few POJOs on the client side and you want to reduce amount of calls from
client to server then yes. It is better to create a DTO object where place only necessary properties from POJOs that you will
use on client side. And return this DTO as a result of a single call from client to server.

Related

Spring Data REST - do not allow to return entities but only views (projections)

My objective is to make sure that a client can't access (retrieve) directly an entity through the Spring Data REST auto-exposed APIs, but rather only to the views (JPA's projections) of those entities.
So far I've managed to achieve it only for the APIs that return a collection of entities (such as findAll() ) by using the #RepositoryRestResource(excerptProjection = CustomerView.class) annotation on the repository.
How to configure Spring Data REST so that it does the same also for endpoints that retrieve a specific entity? such as /api/v1/customers/1
See Why is an excerpt projection not applied automatically for a Spring Data REST item resource?
If you want to apply projection to a specific entity (that is, item resource),
set the uri template variable projection to construct a url path /api/v1/customers/1?projection=customerView. The name customerView is what is set in the annotation #Projection. see the doc https://docs.spring.io/spring-data/rest/docs/current/reference/html/#projections-excerpts.projections
Edit after clarify with Macro:
Macro wants to hide some sentitive fields such as password. Then the jackson annotation #JsonIgnore should be added to the sentitive fields to hide them from response json.

How naming objects returned by Controllers, Service and Repositories?

In Spring MVC we have 3 main categories of objects: Controllers, Services and Repositories.
I'm not able to "categorize" the objects returned by these three categories.
For example, the repositories return Entitys, but how could I name the objects returned by services and controllers?
In a real project I'm developing I have a repository returns an extraction from a table, so I get Entities objects. Into the service, where the logic is, I need only to return some fields, so I need to map the entities to another object-model. Later into the controller maybe I will need some layer specific presentation, for example between "standard-computer" and mobile, so I need another type of object to map the result of the service.
Each layer has its postfix in the name of the class to keep the codebase clean and readable. In most of the projects I have worked on, the naming convention is:
Controller layer
The POJO exposed outside of the application, for example, thought a REST API is DTO (Data Transfer Object), so it is usually under the dto package, and the name is like UserDto
Service layer
The POJO that handles the application's business logic is called domain object, so it is usually under the domain package, and the name is like User without any postfix in the name.
Repository layer
The POJO that holds the data in the persistence layer is called entity, so it is usually under the jpa package, and the name is like UserJpa

What is the proper way to create DTO in a reactive manner?

I use SpringBoot and I have some Reactive APIs (Controller call a service which call a repository based on MongoReactiveRepositories)
As I don't want the user to directly see my models objects, I would like to have DTOs.
One DTO can be based on the information of several models.
Ex: Given two Model Items
ItemA:
infoA:String
ItemB:
infoB:String
I want to create a single DTO item
ObjectDTO:
infoA: String
infoB: List<ItemB>
What is the proper way to reactively map data between my objects model and a DTO?
Just use Mono.zip(https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html#zip-reactor.core.publisher.Mono-reactor.core.publisher.Mono-java.util.function.BiFunction-) to combine 2 results into one.
return Mono.zip(repo1.getItemA(), repo2.getItemB(),
(itemA, itemB) -> new ObjectDTO(itemA.getInfoA(), itemB.getInfoB())
);
The methods returning itemA and itemB should ofcourse return a Mono.

How to avoid the vulnerability created by using entities at a requestMapping method?

I have a controller with a method like
#PostMapping(value="/{reader}")
public String addToReadingList(#PathVariable("reader") String reader, Book book) {
book.setReader(reader);
readingListRepository.save(book);
return "redirect:/readingList/{reader}";
}
When I run a static code analysis with Sonarqube I get a vulnerability report stating that
Replace this persistent entity with a simple POJO or DTO object
But if I use a DTO (which has exactly the same fields as the entity class, then I get another error:
1 duplicated blocks of code must be removed
What should be the right solution?
Thanks in advance.
Enric
You should build a new separate class which represents your Entity ("Book" ) as Plain Old Java Object (POJO) or Data Transfer Object (DTO). If you use JSF or other stateful technology this rule is important. If your entity is stateful there might be open JPA sessions etc. which may modify your database (e.g. if you call a setter in JSF on a stateful bean).
For my projects I ignore this Sonar rule because of two reasons:
I alway you REST and REST will map my Java Class into JSON which can be seen as a DTO.
REST is stateless (no server session) so no database transaction will be open after the transformation to JSON
Information obtained from sonarsource official documentation.
On one side, Spring MVC automatically bind request parameters to beans
declared as arguments of methods annotated with #RequestMapping.
Because of this automatic binding feature, it’s possible to feed some
unexpected fields on the arguments of the #RequestMapping annotated
methods.
On the other end, persistent objects (#Entity or #Document) are linked
to the underlying database and updated automatically by a persistence
framework, such as Hibernate, JPA or Spring Data MongoDB.
These two facts combined together can lead to malicious attack: if a
persistent object is used as an argument of a method annotated with
#RequestMapping, it’s possible from a specially crafted user input, to
change the content of unexpected fields into the database.
For this reason, using #Entity or #Document objects as arguments of
methods annotated with #RequestMapping should be avoided.
In addition to #RequestMapping, this rule also considers the
annotations introduced in Spring Framework 4.3: #GetMapping,
#PostMapping, #PutMapping, #DeleteMapping, #PatchMapping.
See More Here

struts2 spring jpa layers best practice

I have an app written with Struts2 Spring3 JPA2 and hibernate. In this app i have the following levels :
- struts2 actions
- spring services
- spring DAO
So, one struts action call for a service which can contain calls to one or many dao objects.
In order to display the info on the screen i have created some "mirror" objects for entities; ie: EmailMessage entity has a EmailMessageForm bean that is used to display/gather data from webforms (i don`t know if this is the best practice), and hence my problem.
In EmailMessageServiceImpl i have a method called:
public List < EmailMessage > getEmailMessages(){
//code here
}
and, if i call this from struts action i cannot get dependencies because session has expired (i have TRANSACTION entity manager). So, one solution would be to create another method
List<EmailMessageForm> getEmailMessagesForDisplay()
{
//....
}
and here to call for getEmailMessages() and convert this to form objects.
What do you recommend me ?
What is the best practice for this kind of problem ?
If by "dependencies" you mean "lazy-loaded objects", IMO it's best to get all the required data before hitting the view layer. In your current architecture it looks like that would mean a service method that retrieves the DTOs ("form beans"; I hesitate to use the term since it's easy to confuse with Struts 1).
Some say using an Open Session in View filter/interceptor is better. It's easier, but can lead to unintended consequences if the view developer isn't paying attention, including multiple N+1 queries etc.

Resources