While unit testing REST endpoint, LocalDateTime is sent truncated - java

I'd like to unit test my REST endpoint. I'm very new to this, but I was able to write the following code:
HttpPost request = new HttpPost("http://localhost:8080/myrest");
ObjectMapper mapper = new ObjectMapper();
String empJson = mapper.writeValueAsString(clientDto);
StringEntity input = new StringEntity(empJson);
input.setContentType("application/json");
request.setEntity(input);
org.apache.http.HttpResponse httpResponse =
HttpClientBuilder.create().build().execute(request);
clientDto is an instance of a simple POJO with a field of type LocalDateTime. The thing is that my deserializer always gets that date as the following string { (one char only). How do I fix this? If you think that unit testing can be done in a better way, please let me know. I've used Apache dependency but this is not a must.

Using RestAssured library it is very easy to test REST API. Please have a look at this code. One of its pros is that it is self-explanatory.
CreditClass dto = new CreditClass();
dto.setCreditGranted(false);
given()
.contentType(MediaType.APPLICATION_JSON)
.body(dto)
.when().post("localhost:8080/rest-api").then()
.statusCode(200)
.body("creditGranted", equalTo(true));

Related

Combine multiple object mapper strings in java

I want to use the object mapper class in java to pick certain parts of an api request object to use in another request.
Request: {"access_instrument":{"id":"12345","additional_attributes":[1123],"instrument_lifecycle_reasons":[4423],"associated_instruments":[123],"links":[]},"types":[],"states":[],"metadata":[]}
I currently have:
ObjectMapper obMapper = new ObjectMapper();
obMapper.registerModule(new JavaTimeModule());
String requestStr1 = obMapper.writeValueAsString(searchCriteria.getAccessInstrument().getId());
String requestStr2 = obMapper.writeValueAsString(searchCriteria.getAccessInstrument().getInstrumentLifecycleReasons());
String requestStr3 = obMapper.writeValueAsString(searchCriteria.getAccessInstrument().getAssociatedInstruments());
Entity<String> requestEntity = Entity.entity(requestStr1+requestStr2+requestStr3, MediaType.APPLICATION_JSON_TYPE);
However I feel this will run into issues with the api validations due to formatting, and adding spacing manually, doesn't seem efficient. Is there a way I can pick apart the data I want from the request body to then send it in the new request?
Note: the requestEntity variable is the request payload that is used in the api call

API Response JSON to Class Object in Java

I am getting a service response from Azure API in JSON format, but I need to transform it into Java class object format. Please suggest the simplest way to transform
There is website on which you can put json response and select the language in which you want to create classes.
This is simplest way to transform -
https://app.quicktype.io/
You can use com.fasterxml.jackson.databind.ObjectMapper
Exemple :
ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
UserType user= mapper.readValue("your_Json", UserType.class);

How to use RestTemplate with different ResponseEntities?

What if a XML webservice can respond with different xml structures? Eg an <OkResponse> and an <ErrorResponse>, having completely different fields?
ResponseEntity<Response> rsp = restTemplate
.postForEntity(url, new HttpEntity<>(xml, HEADERS), OkResponse.class);
Before sending the request, I don't know which type of response will come back. If I'm using OkResponse.class, I will get a ClassCastException if an ErrorResponse is returned.
How could I handle this?
The autogenerated beans are as follows:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlSeeAlso({
OkResponse.class,
ErrorResponse.class
})
public class AbstractResponse {
}
Use String.class
ResponseEntity<String> rsp = restTemplate
.postForEntity(url, new HttpEntity<>(xml, HEADERS), String.class);
String responseBody = (String)rsp.getBody();
Object response=mapper.readValue(responseBody, Class.forName(responseClass))
Once response body is obtained. make use of service class that you want to map and convert it using jackson mapper .Made use of reflection since the entity passed can be different/dynamic
RestTemplate uses Jackson for JSON serialization, and it supports inherited types though the #JsonTypeInfo annotation. But it requires that all responses have a common 'type' property. If there is no common property that all responses share, then I think you need to use the String approach, and use String.contains() to find a unique property to determine which response type it is.

Consuming PagedResources in abstract class

I have a server that exposes data with the spring-data-rest project and now I am writing services to consume those data and I started with a generic service that will suit all the common needs, one of which is getting the Page object.
I configured my RestTemplate to use the Jackson2HalModule as suggested here.
I've tried a lot of combinations and I was only able to use consume it properly in a non-generic way like this:
PagedResources<Resource<Company>> response2 = restTemplate.exchange(getUrl(), HttpMethod.GET, HttpEntity.EMPTY, new ParameterizedTypeReference<PagedResources<Resource<Company>>>(){}).getBody();
But trying the same code with T didn't work (Resource links were deserialized but content of Resource object was null)
PagedResources<Resource<T>> response3 = restTemplate.exchange(getUrl(), HttpMethod.GET, HttpEntity.EMPTY, new ParameterizedTypeReference<PagedResources<Resource<T>>>(){}).getBody();
Generically I am only able to deserialize the Company data using the following code:
PagedResources<T> response1 = restTemplate.exchange(getUrl(), HttpMethod.GET, HttpEntity.EMPTY, PagedResources.class).getBody();
But this one doesn't deserialize the Resource object so the Company&Links data of what should be the Resource object are stored in a LinkedHashMap instead.
I also tried using the object mapper on the LinkedHashMap with data but I was unsuccessful. It's been a long day so I might be too close to see the correct way of doing this. I'll appreciate any help with this. Thank you.
The question: Is there a way of getting proper generics working in this case?

Java Jackson org.codehaus.jackson.map.exc.UnrecognizedPropertyException

I am binding a JSON response to my class using Jackson. Everything works great except when there are more fields in my JSON response than my class defines. I want Jackson to ignore the fields that do not exist in my JSON response. This is due to compatability for future versions. If I add a new field I do not want previous versions of my client to crash.
Ideas?
ObjectMapper mapper = new ObjectMapper(); // can reuse, share globally
PromoResponse promoResponse = mapper.readValue(r, PromoResponse.class);
You can put the #JsonIgnoreProperties(ignoreUnknown=true) annotation on your PromoResponse class.
I believe you would want to do something like this after you declare your mapper object:
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
-Dan

Categories