Spring boot "CommandLineRunner" and json - json

I'm writing a command line app that needs to serialize/deserialize a json file but can't seem to find a non-web example. All the code I found is to do with Restful API and Web.
So the question is how to set up serializer/deserializer and map pojos to json in a Spring boot command line app. It'd be great if there is a sample unit test that shows how to set up its Spring content. I tried the code snippet in Spring boot docs using #JsonTest Auto-configured JSON tests but it complains of not finding matching implementation.
Many thanks

Take a look at the Jackson project, specifically the ObjectMapper.
https://github.com/FasterXML/jackson
https://fasterxml.github.io/jackson-databind/javadoc/2.7/com/fasterxml/jackson/databind/ObjectMapper.html
The simplest way would be to create an ObjectMapper as a bean, and use that throughout your project.
#Configuration
public class MyConfig() {
#Bean
public ObjectMapper objectMapper() {
return new ObjectMapper() ;
}
}

Related

JSON encoding using produces={"application/json; charset=UTF-8"} and ObjectMapper

I am trying to develop a microservice using Spring MVC and Spring Boot. In my service I am giving result back as JSON encoded format. Currently I added action like:
#RequestMapping("/checkUsers")
public String checkLogin() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
List<Users> useObj = (List<Users>) userRepo.findAll();
return(mapper.writeValueAsString(useObj));
}
And now I found the other options through the following method
produces={"application/json; charset=UTF-8"}
Here I am not sure which method is properly using for encoding the data into JSON format in Spring. How can I proceed?
Why don’t you just use
ResponseEntity
And return
new ResponseEntity<String>(“your message”, HttpStatus.OK);
#RequestMapping(method = GET, value = "my/random/uri", produces = "application/json;charset=UTF-8")
Here produces attribute inside my #RequestMapping annotation is the producible media types of the mapped request. The format is a single media type or a sequence of media types, with a request only mapped if mentioned one matches one of these media types. and here, my #RequestMapping annotation is already serving my purpose of encoding.
Now somewhere from Spring Boot documentation:
Spring Boot is a brand new framework designed to simplify the bootstrapping and development of a new Spring
application. The framework takes an opinionated approach to
configuration, freeing developers from the need to define boilerplate
configuration.
Please don't kill the purpose of Spring Boot. :)
Additionally, I would suggest you use org.springframework.http.MediaType class. It has got all encoding types you'll ever require. Happy coding.
Please let me know if you face any difficulty while going with suggested approach.
If you use #RestController on your controller, all request mappings will produce application/json by default.
Also, there is no need to to the object mapping yourself, just return the object without mapping and let Spring/Jackson do its thing.
#RestController
public class UsersController {
// #RequestMapping("/checkUsers")
// There is an even simpler and more concise
#GetMapping("/checkUsers")
public List<User> checkLogin() throws JsonProcessingException {
return userRepo.findAll();
}
}

How to configure Jackson for HTTP REST response body in Spring

I am trying to build a REST service using Spring 4.3.4 and Spring Boot 1.4.2. What I need to do is to configure the Jackson instance in such a way that I can access the actual configuration of the object mapper (e.g. use fields only, don't use getter/setter methods etc).
After a long session of debugging Spring code, I tried all of the following:
#Bean for Jackson2ObjectMapper
#Bean for Jackson2ObjectMapperBuilder
#Bean for Jackson2ObjectMapperFactoryBean
None of the above had any effect. Ultimately, I think I've figured out the root cause of it all. Here's how Spring really creates it's Jackson instances:
AllEncompassingFormHttpMessageConverter calls new MappingJackson2HttpMessageConverter()...
... which builds a new Jackson2ObjectMapperBuilder...
...via static method Jackson2ObjectMapperBuilder.json()
ALL of the above is static (!!) and completely neglects any kind of configuration, regardless whether it's XML, Java #Configuration classes or even application.properties.
The question is: do I need to implement my own converter that replaces the AllEncompassingFormHttpMessageConverter (is that even possible?), or is there any other solution to configure the Jackson instance?

how to create jackson based json rest service with Spring 2

Spring 3 has native json support for returning json response using #ResponseBody spring 3 annotation.
My app is based on spring 2 and need to create jackson based rest service which will return json when client make http rest request using browser.
I am exploring how to achieve this. Any body suggestions on this is appreciated.
Thanks
In Spring 3 we have default converter which converts any object (using Jackson) to JSON. We can override this default converter to define some specials settings. In Spring 2 we can implement View. You can implement this view using Jackson library to convert any object to JSON.
Your controller could look like that:
public ModelAndView generateJson(.....) {
//business logic
return new ModelAndView(new JsonView(objectToConvert);
}

REST API with JSON representations using Apache CXF without Spring

I want to support both XML and JSON representations of Resources in my REST API. I have no choice but to use CXF implementation of Jax-RS without using Spring. I am using JAXB to marshall and unmarshall objects. I have the following methods defined that return different representations of the same resource.
#GET
#Produces({MediaType.APPLICATION_XML, MediaType.WILDCARD})
#ElementClass(response = MyList.class)
public Response listXML(){
MyList list = getList();
return Response.status(
Response.Status.FOUND).
entity(list).type(MediaType.APPLICATION_XML).build();
}
#GET
#Produces({MediaType.APPLICATION_JSON})
#ElementClass(response = MyList.class)
public Response listJson(){
MyList list = getList();
return Response.status(
Response.Status.FOUND).
entity(list).type(MediaType.APPLICATION_JSON).build();
}
This works fine for the XML representation. But if I set the Accept header of my HTTP request to application/json I get the following message.
No message body writer has been found for response class MyList.
What am I missing here? The MyList class is generated by JAXB from XSDs and has all the necessary annotations Looks like I need to configure CXF to use a JSON provider. I haven't been able to find good documentation on configuring the JSON provider in the web.xml for a webapplication that doesn't use Spring. If anyone has got this work, please guide me.
I got it figured out. I needed to configure JSONProvider as one of initparams for NonSpringServlet in the deployment descriptor. This wasn't working for me before as I was missng the cxf extensions library and the jettison library. These dependencies don't get automatically pulled by maven or gradle if you only have a dependency on cxf front end jars.

How do I configure the date formatter through Genson/Jersey?

I'm using Jersey for my RESTful services and Genson to perform my JSON/POJO conversion. There's no setup for Genson, I just drop it into the classpath and it just works, except that it throws an error on date parsing because the format is unexpected.
Now, if I were to do this as a servlet, using Gson, I set the date format on a Gson instance that I maintain. That forces the parse of the POJO to use the correct format. I see that Genson has a similar interface, but I don't know how to get the instance from the Jersey servlet service or maybe the Spring context so that I cat set the format.
So, the short question is: how do I set a date format for Genson when started through Jersey?
To configure Genson instances you can use Genson.Builder class (it is similar to Gson on this point). Then you have to inject it with Jersey.
#Component
#Provider
public class GensonProvider implements ContextResolver<Genson> {
private final Genson genson = new Genson.Builder().setDateFormat(yourDateFormat).create();
#Override
public Genson getContext(Class<?> type) {
return genson;
}
}
You might also want to have a look at how Genson is integrated into Jersey here.