How to configure spring boot for using klaxon library - json

There is a klaxon library - JSON parser for kotlin
How to configure Spring Boot for using it to make a REST API in this way:
#RestController
class SampleController {
#RequestMapping("/test", method = [RequestMethod.POST])
fun test(#RequestBody body:JsonObject): JsonObject {
//work with body val (KLAXON object)
//return KLAXON object
}
}
#RequestBody body:JsonObject - is a Klaxon object, so we do not want to use standard Jackson2ObjectMapperBuilder for RequestBody. For simplicity we do not want to use it for Response body too.
Post body is some kind of dynamic data, so I want to use a Low level API in lib, not a Object binding API.

No, at the moment it's not possible.
Reference

Related

Extract and unmarshal JSON payload from response

I'm trying to write Citrus tests for a RESTful endpoint producing and consuming application/json content, and I'm not sure how to get my responses unmarshalled to a Java POJO (using Jackson or whatever (un)marshaller Citrus supports).
E.g. in REST-assured, I can simply write
UploadResponse response = when().post("/file").as(UploadResponse.class);
Is there an equivalent in Citrus?
I can only find examples using validate() or extractFromPayload(), which don't really cover my use case, since I don't want to operate on scalar members but embed the entire response object in the request object for the subsequent test step.
You can do something like this:
http().server(testServer)
.post("/file")
.validationCallback(new JsonMappingValidationCallback<UploadResponse>(UploadResponse.class) {
#Override
public void validate(UploadResponse payload, Map<String, Object> headers, TestContext context) {
// do something with payload object
}
});
The JsonMappingValidationCallback automatically searches for a JSON ObjectMapper in Spring bean application context. You can also provide an ObjectMapper instance as constructor arg to the JsonMappingValidationCallback.

Expose a Springboot rest endpoint to read json object

I am new to Springboot and Webservices.Using springboot i need to expose a rest endpoint. Some data provider will call the rest endpoint to post the data. Then i need to start processing the posted json and convert it into a java object. So using spring boot I need to expose a rest webservice to accept and process the json posted to the webservice created. How should I do it. Any example would help
Its so simple.
We need to have a Springboot restcontroller to expose rest endpoint. And then using #Requestbody we need to get the Objects directly from the json message passed .
#RestController
public class JsonObjectRestController {
#RequestMapping(value="/rest/pushjson",method = RequestMethod.POST)
public ResponseEntity<PushedJsonObject> getJsonObject(#RequestBody PushedJsonObject jsonObject)
{
if(jsonObject != null)
{
//process the json object
}
return new ResponseEntity<PushedJsonObject >(jsonObject, HttpStatus.OK);
}
}
Explanation:
We need to have a model class representing the json sent(Here its PushedJsonObject). Have your controller annotated with the new Spring4 #RestController.
The #RequestBody method parameter annotation should bind the json value in the HTTP request body to the java object by using a HttpMessageConverter. Make sure Jackson is in the classpath so that spring boot configures it automatically to use the MappingJackson2MessageConverter.

JSON respones from Jersey 1.x (1.17) with JAXB cannot be deserialized by Jackson

I have a jersey webservice running 1.17 and supports returning responses via both XML and JSON via the #Produces annotation. I am assuming it uses JAXB by default when returning JSON responses but I have no way to confirm it. As of now, my existing clients also use the same JAXB serializer/deserializer. I want to create a new client that uses Jackson without impacting the existing clients.
The JAXB JSON response is incompatible for Jackson for Maps. the JSON for a map using JAXB is of the form
"mapName":{"entry":[{"key":"key1","value":"value1"},{"key":"key2","value":"value2"}]}
and Jackson fails to parse this. Is there any way to make jackson parse this JSON?
Another Attempt: Switching Jersey to use Jackson
This isn't the preferred option but I tried setting "com.sun.jersey.api.json.POJOMappingFeature" to true to allow it to use Jackson for JSON Serialization/Deserialization however the service ends up returning 500s on response without logging any exceptions. the log4j logger level is set to TRACE. I enabled the ContainerRepsonseFilter to confirm 500s in the response and to my surprise, it logs the successful 2xx response. My guess is the problem occurs somewhere further down the stack but I don't know where.
I ended up with using MOXy which is able to parse the above json format.
#Provider
public class JsonMoxyConfigurationContextResolver implements ContextResolver {
private final MoxyJsonConfig config;
public JsonMoxyConfigurationContextResolver() {
final Map<String, String> namespacePrefixMapper = new HashMap<String, String>();
namespacePrefixMapper.put("http://www.w3.org/2001/XMLSchema-instance", "xsi");
config = new MoxyJsonConfig()
.setNamespacePrefixMapper(namespacePrefixMapper)
.setNamespaceSeparator(':');
}
#Override
public MoxyJsonConfig getContext(Class<?> objectType) {
return config;
}
}
and enabled it Jersey 2.x client using
cc.register(JsonMoxyConfigurationContextResolver.class);

JSONObject Alternative in Spring and Jackson

I need to pass a map back to the web application.
I'm used to encapsulating the map in a JSONObject
http://json.org/java/
But since I am using Spring and Jackson Haus.
is there an easier way to maintain the pojo? May I can just annotate the MAP ?
Jackson has com.fasterxml.jackson.core.JsonNode, and specific subtypes like ObjectNode.
These form so-called Tree Model, which is one of 3 ways to handle JSON with Jackson -- some other libraries (like org.json) only offer this way.
So you should be able to just use JsonNode instead; there is little point in using org.json library; it is slow, and has outdated API.
Alternatively you can just use java.util.Map, and return that. Jackson can handle standard Lists, Maps and other JDK types just fine.
If you need to manipulate the output, ie, you don't want to provide all the fields of the object you can use JSonArray:
#RequestMapping(value = "/api/users", method = RequestMethod.GET)
public
#ResponseBody
String listUsersJson(ModelMap model) throws JSONException {
JSONArray userArray = new JSONArray();
for (User user : userRepository.findAll()) {
JSONObject userJSON = new JSONObject();
userJSON.put("id", user.getId());
userJSON.put("firstName", user.getFirstName());
userJSON.put("lastName", user.getLastName());
userJSON.put("email", user.getEmail());
userArray.put(userJSON);
}
return userArray.toString();
}
Use the example from here
Otherwise if you add jackson to your dependencies and set the controller method anotatted with #ResponseBody the response will automatically mapped to JSON. Check here for a simple example.

How should I set a Feature on a Spring Message Converter's Object Mapper?

I'm using a 3rd party REST API which is returning 'NaN' in it's JSON response :( I can't change the response.
I'm using Spring MVC with RestTemplate and the built in Message Converters to deserialize the JSON to an Object.
I was wondering, if there is a smart way of setting the JsonParser.Feature.ALLOW_NON_NUMERIC_NUMBERS property to allow for the NaN in the response.
Because I have other message converters which I do not need to configure myself I'm currently doing the following:
List<HttpMessageConverter<?>> converters = restTemplate.getMessageConverters();
for (HttpMessageConverter converter : converters) {
if (converter instanceof MappingJacksonHttpMessageConverter) {
ObjectMapper objectMapper = ((MappingJacksonHttpMessageConverter) converter).getObjectMapper();
objectMapper.configure(JsonParser.Feature.ALLOW_NON_NUMERIC_NUMBERS, true);
}
}
This works but I don't like the fact that I'm a) iterating and b) doing the instanceof comparison just to set this property.
What would be a smarter/nicer way to do this?
Here are your options:
Instantiate and configure MappingJacksonHttpMessageConverter then set the message converters of your resttemplate to that instance. See RestTemplate.html#setMessageConverters(java.util.List). Note that this will remove all default message converters that are automatically instantiated when you instantiate a RestTemplate.
Use #JsonDeserialize. See http://dev.sghill.net/2012/04/how-do-i-write-jackson-json-serializer.html