In my Spring Boot application I use a following DTO with #RestController:
public abstract class ComparableQuery extends BaseQuery {
private final Object value;
...
}
Everything works fine but when I use Spring RestTemplate and pass java.util.Date as ComparableQuery.value I see that Jackson serialize the date object into the following "magic" number:
"value":1009836000000
Right now I don't understand how the date object serialized into the 1009836000000 number representation and how to emulate it when I use for example AngularJS as a client of my back-end API. Please advise.
This is a very similar problem as described in this answer about null handling with jackson and spring boot.
The corresponding configuration for date formatting in application.properties should look like:
spring.jackson.write-dates-as-timestamps=false
Related
I am new in Spring MVC. My question is, why do we need jackson databind? Because We can receive the Request Params by #ModelAttribute and requests through http PUT or POST by #RequestBody. I can't find a reason why we need jackson databind to convert json/xml to POJO or vice versa.
Thanks.
Why do we need jackson databind?
Because representing structured data is much easier using XML (or JSON) than using simple name-value pairs.
Because it is more convenient to send and receive JSON from the client side when you are doing AJAX.
Because once you have to deal with sending and receiving JSON or XML in the server side Java app, it is more convenient to deal with structured data as POJOs.
None of the above points mean you have to use a binding. There are other ways of dealing with each of the above. But many Java developers think that data bindings the better way to go: more efficient in terms of developer time, and more reliable. Especially if you are implementing services with a complex APIs. That's why they are popular.
And as other answers/comments point out, if you are using #RequestBody, then that is using a binding library under the hood to give you the POJOs. In the case of Spring, it is Jackson that is being used.
By default, when an endpoint expects a JSON document as input and a given controller method argument is annotated with #RequestBody, Spring will use Jackson databind features to map the incoming JSON document to a Java object. You don't need to use the Jackson's ObjectMapper directly, as Spring does it for you.
For example purposes, consider the following HTTP request to create a comment:
POST /comments HTTP/1.1
Host: example.org
Content-Type: application/json
{
"content": "Lorem ipsum"
}
And the following class which represents a comment:
#Data
public class Comment {
private String content;
}
A #RestController to handle such request would be like:
#RestController
#RequestMapping("/comments")
public class CommentController {
#PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Foo> createComment(#RequestBody Comment comment) {
// By default, Spring will rely on Jackson databind to map the incoming
// JSON document to the comment argument annotated with #RequestBody
...
}
}
If you are interested in the Spring component that maps the incoming JSON document to a Java object, have a look at the MappingJackson2HttpMessageConverter class:
Implementation of HttpMessageConverter that can read and write JSON using Jackson 2.x's ObjectMapper.
This converter can be used to bind to typed beans, or untyped HashMap instances.
By default, this converter supports application/json and application/*+json with UTF-8 character set. [...]
If you are creating a HTTP API and exposing resources that can be manipulated with JSON representations, it's unlikely you'll use #ModelAtribute. Such annotation is particularly useful when you are dealing with web views.
When you get some request in some data types like json/xml, the Spring MVC platform will try to deserialize this request attributes in some model object of your project.
But the platform itself don't provide a des-serialize implementation out of the box. So it will try to use some des-serializer provider in the classpath like jackson, jersey, gson, etc.
As you said - is possible to use #ModelAttribute - but this annotation is a better option to a request from a form view in the front-end. In cases rest json/xml requests, the #ModelAttribute won't be able to convert correctly the received data to a business class of your program.
I would like to ues Pageable object in controller's method to eliminate the redundant page and size parameters. Just like the following:
#RequestMapping("/list")
public String list(Model model , Pageable pageable) {
logger.info("pageable = {}" , pageable);
// ... skipped
}
Instead of:
#RequestMapping("/list")
public String list(Model model , Integer page, Integer size) {
logger.info("page = {}, size = {}" , page, size);
// ... skipped
}
However, after adding the org.springframework.boot:spring-boot-starter-data-jpa dependency to my pom.xml, I've been always asked for setting up the 'entityManagerFactory' bean, which looks like something from the embedded hibernate dependency.
How can I use the Pageable obejct and get rid of the Spring Data things?
Pageable is part of the Spring Data Commons project -
and I've never seen it used outside of Spring Data.
That said... it may be possible, but you'd have to pull in the appropriate jar containing the Pageable class, without pulling in any of the Spring Boot Starter Data - * dependencies. If you add the starter, Spring boot is going to attempt to perform automatic datasource configuration, which it sounds like you do not want.
You could try to pull in the single dependency that contains that class (org.springframework.data:spring-data-commons i believe). You should then have access to the Pageable class without any autoconfiguration.
Try to use spring data JDBC. This would help you avoid the need to use JPA!
Here is a good source of information about jdbc: Github-Spring Data JDBC generic DAO implementation
We are using Jersey, Jackson and Spring service (#service) annotation to expose some REST based Web-Services. Request and response data are exchanged in JSON Format.
Below is the Service Request Object content:
public class ServiceRequest{
private RequestHeader requestHeader;
private List<BaseEntity> requestData;
}
All specific entities will extend from BaseEntity class. For example :
public class User extends BaseEntity{
private String userName;
}
For all service operation we accept only ServiceRequest Object by passing list of request data objects. Now when we try to call these operation from REST Client, these are failing with
userName is not found as part of BaseEntity.
This is because while converting, Jersey/Jackson tries to autodetect the incoming field names with the specified object's property.
I want to know is there any way, I can handle this in an intelligent way. We do not have an option to change the signature of the Service. Really appreciate your help on this.
The below link has the answer for my question. Thank you for the support.
Polymorphism in jackson annotations: #JsonTypeInfo usage
Did you tried to use generics? You can declare concrete class type at Resource's to inform Jackson to map to specific type
I am using MappingJacksonHttpMessageConverter in Spring MVC to automatically serialize objects like this:
#RequestMapping(value="/*/getAccount", method=RequestMethod.GET)
#ResponseBody
public Account getAccountAction() {
Account account = accountService.getAccount();
return account;
}
Is it possible to configure which properties of the object are serialized? In my example, Account has 3 collections as properties and serializing all these contents would result in a huge object tree. Here I only want to return the flat object.
Sincerely,
Erik
Did you already try to use the Jackson Annotations?
There is the Annotation #JsonIgnoreProperties that can be used to ignore a given list of properties for serialization on class level and there is #JsonIgnore to mark properties to ignore for serialization on field level.
I could figure it out: Configure Jackson with annotatons, it is described in detail in the Jackson configuration.
I would like to implement custom metric or statistics to my spring boot rest web service using actuator but i am not able to find simple tutorials.
For example:
how to show how many times a certain controller was called and what exact parameter field was filled?
how can i create a metric that when its URL is called, it runs certain query and shows back a json with some result
This seems like a good scenario for AOP (Aspect Oriented Programing) as this will allow you to separate this statistic logic from the business logic.
Have a look at Spring doc for more info about AOP and how to achieve that with Spring.
You can then define a pointcut on your controller and have a service for counting (and probably then storing) the data.
Refer below link
AOP Example
For point two the solution is to create an endpoint class (it can be or not a rest controller class). For example:
#Component
#RestControllerEndpoint(id = "pfm-statistics")
public class StatisticsEndpoint {
#GetMapping(value = "/", produces = "application/vnd.openxmlformats-
officedocument.spreadsheetml.sheet")
#ResponseBody
public byte[] generateStatisticsAsExcel() {
...
Note that the ID is the path to be called from URL. We can create a simple endpoint too and just return a string if we want. In this case instead of #RestControllerEndpoint annotation we can use #Endpoint, as a side note, the id should always contain dash