jackson - root element read Tree vs pojo - spring

Hi I want to parse a json that i retrieve by hitting an legacy system, and build a response json. We are using Spring Boot having a jackson dependency. The problem i have is almost 75% of fields from legacy can be mapped directly or on basis of simple rules (0: false, 1:true). But, there are some complex rules as well like based on certain conditions and data present in some fields, we can map them to a nested object etc. To cater to this requirement which approach should we consider -
POJO approach to fetch the data from legacy target. Use bean util. copyproperties to populate the response bean (75% of properties), and then apply the business transformations on this POJO to tranform based on business logic. (Would we need two pojos here a. to copy from beanutil.copyproperties and then b. create final response dto ??)
Do not use pojo directly parse the JSON apply the transformations and then create a new POJO or response DTO. (But, this may not be generic solution and would need to be done on case by case basis).
Main considerations are approach should be fast, and generic to be applied like a framework. Thanks aakash

The considerations should be like below:
- Are the POJOs reusable?
- Is the JSON multilevel and very large?
If the answer is yes for both, then better to choose POJOs for cleaner implementation. Otherwise JsonObject parsing.
Hope this will help.

Related

Can we Document Model/entity with using Spring rest docs

Writing all fields with the snippets description is not reliable solution
is there any way to implement Model/Entity as a table with the fields and description, constraints, Type seprately.
fieldWithPath("id").description("Id of Student."),
fieldWithPath("name").description("Name of the Student."),
fieldWithPath("contact").description("Contact of the Student."),
fieldWithPath("marks").description("Marks of the Student."));
Documenting an entity directly is exactly what Spring REST Docs is designed to avoid. If that's the approach that you want to take then Spring REST Docs isn't the right tool for the job.
Spring REST Docs is built around the belief that, when documenting a REST API, it's the HTTP requests and responses that should be used to generate that documentation. This ensures that the documentation accurately describes the requests that the service expects to receive and the responses that it will send.
If you try to use an entity to document your API, you are ignoring the transformations that could be applied to that entity when serialising it to JSON. This can result in documentation that's inaccurate as serialization may omit some of an entity's properties, change the name of some of those properties, or even change the structure entirely.

Implement complex search feature using Spring BOOT REST and Spring Data JPA using Criteria API

I need to implement complex search feature using Spring Boot REST and Spring Data JPA using Criteria API. I need to provide RPIs like below
/college?select=*&where=name:DemoCollege and location:LA and staff{firstName:foo, lastName:boo, workExp>10} and type in [1,2,3]
Collage object has name, location, type fields and staff list.
It has onetomany relationship with Staff so College can have one or many Staff members.
based on the uri I need to build query using criteria api.
I am finding it very complex to implement the toPredicate() method of org.springframework.data.jpa.domain.Specification. Is there any such example handing such complex search filters?
Thanks in advance.
I think the best choice, in your case, is the specification-arg-resolver lib that provide convenient way to build specification declaratively. For example, this code:
#RequestMapping("/customers")
public Object findByName(
#And({
#Spec(path="registrationDate", params="registeredBefore", spec=DateBefore.class),
#Spec(path="lastName", spec=Like.class)}) Specification<Customer> customerSpec) {
return customerRepo.findAll(customerSpec);
}
is corresponding to this request:
GET http://myhost/customers?registeredBefore=2015-01-18&lastName=Simpson
It supports the following specifications: Like, LikeIgnoreCase, Equal, EqualIgnoreCase, In, Null, NotNull, GreaterThan, GreaterThanOrEqual, LessThan, LessThanOrEqual, DateBetween, Join, Join fetch, and it allows you to combine them, composing complex expressions.
Another option is Querydsl and Web support Spring Data extensions. It also allows you to build a 'REST query language' but has fewer possibilities. You can read in my answer how to use it: https://stackoverflow.com/a/48596145

Can i access request parameter in jackson BeanSerializerModifier?

I am using Jersey to implement rest api and Jackson to provide JSON support. I am trying to remove certain properties before serialization by overriding BeanSerializerModifier.changeProperties method.
But removing properties will be based on query parameter. Is there any way to access the query parameter in my implementation?
Use of BeanSerializerModifier itself would get complicated as the method is only called once when construction necessarily JsonSerializer for the first time. As to passing query parameters, you could pass them using contextual attributes and ObjectWriter (constructed from ObjectMapper), but that means taking over quite a bit of serialization automation from Jersey.
There is one mechanism that could be helpful in modifying serialization aspects without taking over the whole process: registering ObjectWriterModifier, using ObjectWriterInjector. These are part of Jackson JAX-RS provider, added in Jackson 2.3. Without knowing more details I don't know how easy this would be; part of the issue is that query parameters are more of an input side things, so there is no direct access to them from output processing side.

DTO in spring mvc

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.

Spring MVC Rest: How to implement partial response in Json and XML?

I need to the ignore the serialization (JSon/Jackson and XML/XStream) of some attributes from my object response based on user input/or Spring security roles (like you don't have permission to see the content of this field, but all others are ok etc). How is the best approach to do this in Spring MVC Rest?
Other approach is show only the attributes that are relevant for the api user, like described here http://googlecode.blogspot.com.br/2010/03/making-apis-faster-introducing-partial.html
If you are using Jackson, here are some possible options to modify the Json serialization:
Use the #JsonIgnore annotation - However, this is static filtering, and will not allow you to implement rule-based filtering as you appear to need
Use #JsonFilter - This will allow you to implement an interface in which you can provide your serialization filtering logic. You may find this to be too heavyweight of a solution.
The way I often solve this is to return a Map from my Controller methods instead of the underlying object. You can write processing code that puts the relevant fields from the object into the Map, therefore giving you complete control over what is serialized. You could include a method on the Object to do the conversion. The method could look something like this:
// RequestObj is whatever 'input' object that indicates what should be filtered
public Map<String,Object> convertToMapForRequest(RequestObj request){
// Build return map based on 'this' and request
}

Resources