mapper.readValue() return null value (Jackson API) - java

I have one JSON object which I am trying to read from Jackson API Object Mapper.
{
"ddt_id":"605",
"ddt_batch_code":"5769005b-e8f0-4ae8-8971-1c59ac1f02fd",
"keyword":"ADP",
"keyword_operation":"and",
"keyword_extract_match":"F",
"search_in":"name",
"filter_type":"entity,others",
"category":"2,3,5",
"gender":"",
"date_year":"",
"date_month":"",
"date_day":"",
"country":"",
"search_filter_uuid":"570bd722-315c-40b3-b2d6-4522ac1f02fd",
"ddt_qsk_question":"0",
"search_for":"all",
"search_category":"2,3,5",
"search_includes_name":"T",
"search_includes_profile_notes":"F",
"search_for_person":"F",
"search_for_entity":"T",
"search_for_others":"T",
"search_from_module":"DDMT.V.2.20",
"client_id":667,
"ip_address":"52.23.94.13",
"search_requester_id":false,
"search_requester_name":false,
"batch_id":"5769005b-e8f0-4ae8-8971-1c59ac1f02fd",
"person_query_index":4,
"company_query_index":4,
"is_ongoing":1
}
The Class I used to read this JSON in Object is :
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.UUID;
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonIgnoreProperties(ignoreUnknown = true)
public class SswltSearchParams {
#JsonProperty("batch_id")
private UUID batchId;
#JsonProperty("country")
private String country;
#JsonProperty("criteria_id")
private String id;
#JsonProperty("date_day")
private Integer day;
#JsonProperty("date_month")
private Integer month;
#JsonProperty("date_year")
private Integer year;
#JsonProperty("gender")
private String gender;
#JsonProperty("keyword")
private String keyword;
#JsonProperty("keyword_exact_match")
private String keywordExactMatch;
#JsonProperty("keyword_operation")
private String keywordOperation;
#JsonProperty("search_category")
private String searchCategory;
#JsonProperty("search_for")
private String searchFor;
#JsonProperty("search_for_anti_corruption")
private String searchForAntiCorruption;
#JsonProperty("search_for_entity")
private String searchForEntity;
#JsonProperty("search_for_others")
private String searchForOthers;
#JsonProperty("search_for_person")
private String searchForPerson;
#JsonProperty("search_for_watchlist")
private String searchForWatchlist;
#JsonProperty("search_includes_name")
private String searchIncludesName;
#JsonProperty("search_includes_profile_notes")
private String searchIncludesProfileNotes;
#JsonProperty("update_only")
private String updateOnly;
// getters and setters
}
When I am trying to place this JSON in Onject, I am not getting any error but I am getting NULL value.
try {
SswltMigrationCollection sswltSearchParams = mapper.readValue(searchCriteria.getScrCriteria(), SswltSearchParams.class);
} catch (IOException e) {
return null;
}
Why I am getting this sswltSearchParams as null? Please Help.

Your JSON can be parsed into a SswltSearchParams instance without any problems. The following code works fine:
String json = "{\"ddt_id\":\"605\",\"ddt_batch_code\":\"5769005b-e8f0-4ae8-8971-1c59ac1f02fd\",\"keyword\":\"ADP\",\"keyword_operation\":\"and\",\"keyword_extract_match\":\"F\",\"search_in\":\"name\",\"filter_type\":\"entity,others\",\"category\":\"2,3,5\",\"gender\":\"\",\"date_year\":\"\",\"date_month\":\"\",\"date_day\":\"\",\"country\":\"\",\"search_filter_uuid\":\"570bd722-315c-40b3-b2d6-4522ac1f02fd\",\"ddt_qsk_question\":\"0\",\"search_for\":\"all\",\"search_category\":\"2,3,5\",\"search_includes_name\":\"T\",\"search_includes_profile_notes\":\"F\",\"search_for_person\":\"F\",\"search_for_entity\":\"T\",\"search_for_others\":\"T\",\"search_from_module\":\"DDMT.V.2.20\",\"client_id\":667,\"ip_address\":\"52.23.94.13\",\"search_requester_id\":false,\"search_requester_name\":false,\"batch_id\":\"5769005b-e8f0-4ae8-8971-1c59ac1f02fd\",\"person_query_index\":4,\"company_query_index\":4,\"is_ongoing\":1}";
ObjectMapper mapper = new ObjectMapper();
SswltSearchParams sswltSearchParams = mapper.readValue(json, SswltSearchParams.class);
Not sure why the SswltMigrationCollection class came into play.

Related

I'm recieving "Error while extracting response for type" when I try to return the JSON as an Object. How can I solve this?

I'm doing an API that consumes an external API (https://swapi.dev/), but I'm receving this error when I try to return the JSON converted to Object.
I'm trying to solve this for almost 12 hours without any success x_x
Error while extracting response for type [class [Lcom.starwarsapi.filmsapi.model.FilmModel;] and content type [application/json]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `[Lcom.starwarsapi.filmsapi.model.FilmModel;` from Object value (token `JsonToken.START_OBJECT`);
FilmController:
#RestController
#RequestMapping("/films")
public class FilmController {
#Autowired
private FilmService filmService;
#GetMapping
public List<FilmModel> getAllFilms() {
List<FilmModel> response = filmService.getAllFilms();
return response;
}
FilmModel:
#Data
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonIgnoreProperties(ignoreUnknown = true)
public class FilmModel {
private FilmResultModel[] results;
}
FilmResultModel
#Data
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonIgnoreProperties(ignoreUnknown = true)
public class FilmResultModel {
private String title;
#JsonProperty("episode_id")
private Integer episodeId;
#JsonProperty("opening_crawl")
private String description;
private String director;
private String producer;
#JsonProperty("release_date")
private String releaseData;
private String[] characters;
private String[] planets;
private String[] starships;
private String[] vehicles;
private String[] species;
private String created;
private String edited;
private String url;
FilmService:
public interface FilmService {
public List<FilmModel> getAllFilms();
}
FilmServiceImpl:
#Service
public class FilmServiceImpl implements FilmService {
#Value("${external.api.url}")
private String filmBaseUrl;
#Autowired
private RestTemplate restTemplate;
#Override
public List<FilmModel> getAllFilms() {
FilmModel[] result = restTemplate.getForObject(filmBaseUrl, FilmModel[].class);
List<FilmModel> films = Arrays.asList(result);
System.out.println(films);
return films;
}
PS¹: external.api.url = https://swapi.dev/api/films/?format=json
PS²: When I return getAllFilms as String, the program works:
#Override
public String getAllFilms() {
String result = restTemplate.getForObject(filmBaseUrl, String.class);
System.out.println(result);
return result;
}
But I need it to return as an object because later I'll try to create a PUT method to change the description of the movie.
try using FilmModel result = restTemplate.getForObject(filmBaseUrl, FilmModel.class);
FilmModel is just the outer wrapper object and contains the list of films.

Serializing Enum to JSON in Java

I have a Java enum where I store different statuses:
public enum BusinessCustomersStatus {
A("active", "Active"),
O("onboarding", "Onboarding"),
NV("not_verified", "Not Verified"),
V("verified", "Verified"),
S("suspended", "Suspended"),
I("inactive", "Inactive");
#Getter
private String shortName;
#JsonValue
#Getter
private String fullName;
BusinessCustomersStatus(String shortName, String fullName) {
this.shortName = shortName;
this.fullName = fullName;
}
// Use the fromStatus method as #JsonCreator
#JsonCreator
public static BusinessCustomersStatus fromStatus(String statusText) {
for (BusinessCustomersStatus status : values()) {
if (status.getShortName().equalsIgnoreCase(statusText)) {
return status;
}
}
throw new UnsupportedOperationException(String.format("Unknown status: '%s'", statusText));
}
}
Full code: https://github.com/rcbandit111/Search_specification_POC/blob/main/src/main/java/org/merchant/database/service/businesscustomers/BusinessCustomersStatus.java
The code works well when I want to get the list of items into pages for the value fullName because I use #JsonValue annotation.
I have a case where I need to get the shortValue for this code:
return businessCustomersService.findById(id).map( businessCustomers -> businessCustomersMapper.toFullDTO(businessCustomers));
Source: https://github.com/rcbandit111/Search_specification_POC/blob/316c97aa5dc34488771ee11fb0dcf6dc1e4303da/src/main/java/org/merchant/service/businesscustomers/BusinessCustomersRestServiceImpl.java#L77
But I get fullValue. Do you know for a single row how I can map the shortValue?
I'd recommend serializing it as an object. This can be done via the #JsonFormat annotation at the class level:
#JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum BusinessCustomersStatus {
A("active", "Active"),
O("onboarding", "Onboarding"),
//...
#Getter
private String shortName;
#Getter
private String fullName;
//...
This will lead to the following result when serializing this enum for BusinessCustomersStatus.A:
{"shortName":"active","fullName":"Active"}
Alternatively, you could define status field as String:
public class BusinessCustomersFullDTO {
private long id;
private String name;
private String businessType;
private String status;
}
and map its value like this:
businessCustomersFullDTO.status(businessCustomers.getStatus().getShortName());

Not able to convert Json String to Java objects

I am unable to convert the given Json String to java Object
Validated the Json format, it is correct.
#JsonIgnoreProperties(ignoreUnknown = true)
public class DevPol {
private String id;
private Header header;
//Setters and Getters
}
#JsonIgnoreProperties(ignoreUnknown = true)
public class Header {
private String name;
private String lastUpdate;
private int priority;
private boolean active;
//Setters and Getters
}
import com.fasterxml.jackson.databind.ObjectMapper;
public class ConvertJsonToJava {
static String apiResult = "[ {\"Id\":\"5899503ad06f7f0008817430\", \"Header\":{ \"name\":\"ClCol\"," +
" \"lastupdate\":\"2017-02-07T04:42:34.654Z\", \"priority\":1, \"active\":true } }," +
" { \"Id\":\"5899503ad06f7f0008817431\",\"Header\":{ \"name\":\"SysPol\"," +
" \"lastupdate\":\"2017-02-07T04:42:34.659Z\", \"priority\":2, \"active\":true } }]";
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
DevPol[] devPOlArr = mapper.readValue(apiResult, DevPol[].class);
for(DevPol devPol: devPOlArr) {
System.out.println(devPol.getId());
}
}
}
I expected the output to be Id values but,the result is
null
null
The issue is upper-case letters in json field names and java class fields.
If it is possible rename 'Id' -> 'id' in json and java. Otherwise you should add json property names to java fields:
public class DevPol {
#JsonProperty("Id")
private String Id;
#JsonProperty("Header")
private Header Header;
//Setters and Getters
}

How to pass different constructors as response in java

Response.java
public class Response{
private String mobileNo;
private String contractId;
private String sim;
private String imei;
public Response(String mobileNo, String contractId){
this.mobileNo = mobileNo;
this.contractId = contractId;
}
public Response(String mobileNo, String contractId, String sim,
String imei, String identificationType) {
this.mobileNo = mobileNo;
this.contractId = contractId;
this.sim = sim;
this.imei = imei;
this.identificationType = identificationType;
}
//Getter and Setter
}
MainEx.java
public class MainEx{
Response response = null;
public Response response(){
String mobileNo = null;
String contractId = null;
String sim = null;
String imei = null;
if(something){
response= new IVRAccountDetailsRs("777","4545");
}
else{
response= new IVRAccountDetailsRs("777","4545","sim","imei");
}
return response;
}
}
When if statement call return response as
{ "mobileNo" = "777";
"contractId" = "4545";
"sim"= null;
"imei" = null;
}
But I want to get the response as bellow,
When calling if statement
Need to remove other two values.
{ "mobileNo" = "777";
"contractId" = "4545";
}
If contractId and mobileNo null then output should be
{ "mobileNo" = null;
"contractId" = null;
}
When calling else statement
{ "mobileNo" = "777";
"contractId" = "4545";
"sim"= "sim";
"imei" = "imei";
}
if all values null
{ "mobileNo" = null;
"contractId" = null;
"sim"= null;
"imei" =null;
}
Used Jackson version is 2.4.1
What can I do about this?
If the version of SpringBoot is less than 1.3, it can only be handled programmatically
#JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
public class Response {
///~
}
Spring boot can be configured directly from 1.3 in the application.properties file
spring.jackson.default-property-inclusion=non_null
Official documentation for the jacksong configuration
you can use #JsonInclude(JsonInclude.Include.NON_NULL) on sim and imei, Not on the whole class
public class Response{
private String mobileNo;
private String contractId;
#JsonInclude(JsonInclude.Include.NON_NULL)
private String sim;
#JsonInclude(JsonInclude.Include.NON_NULL)
private String imei;
public Response(String mobileNo, String contractId){
this.mobileNo = mobileNo;
this.contractId = contractId;
}
public Response(String mobileNo, String contractId, String sim,
String imei, String identificationType) {
this.mobileNo = mobileNo;
this.contractId = contractId;
this.sim = sim;
this.imei = imei;
this.identificationType = identificationType;
}
What you ask it's not possible to manage just with serialization.
I suggest to edit Response class, removing the field that don't want send when they are null.
Then create another class that extends Response, that have the other 2 fields.
At this point you can instantiate which one you want based on your condition and return anyway as a Response object.
public class SimpleResponse {
String mobileNo;
String contractId;
.....getters setters
}
public class FullResponse extends SimpleResponse {
String sim;
String imei;
....getter and setters
}
If you use jackson then add this:
#JsonInclude(JsonInclude.Include.NON_NULL) before field.
public class Response{
private String mobileNo;
private String contractId;
#JsonInclude(JsonInclude.Include.NON_NULL)
private String sim;
#JsonInclude(JsonInclude.Include.NON_NULL)
private String imei;
}
For jackson serializers:
You can use annotation over your class, to skip serializing null values:
#JsonInclude(Include.NON_NULL)
public class Response{...}
Or add a parameter to your ObjectMapper configuration:
mapper.setSerializationInclusion(Include.NON_NULL);
This may be a duplicate.
UPDATE:
You can also annotate properties.
#JsonInclude(JsonInclude.Include.NON_NULL)
private String sim;
#JsonInclude(JsonInclude.Include.NON_NULL)
private String imei;
This way other properties will serialize null values, but those two will not be serialized with null value.
Add this annotation just above the getter of sim and imei
#JsonInclude(Include.NON_NULL)
With Jackson > 1.9.11 and < 2.x use
#JsonSerialize
annotation to do that:
#JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
For the version above 2:
#JsonInclude(JsonInclude.Include.NON_NULL)

Java object not populated from json request for inner class

Have searched in different sites but couldn't find correct answer, hence posting this request though it could possible duplicates.sorry for that.
I am sending the below json request to my back-end service and converting to java object for processing. I can see the request body passed to my service but when i convert from json to java object , values are not populating
{
"data":{
"username":"martin",
"customerId":1234567890,
"firstName":"john",
"lastName":"smith",
"password":"p#ssrr0rd##12",
"email":"john.smith#gmail.com",
"contactNumber":"0342323443",
"department":"sports",
"location":"texas",
"status":"unlocked",
"OrderConfigs":[
{
"vpnId":"N4234554R",
"serviceId":"connectNow",
"serviceType":"WRLIP",
"ipAddress":"10.101.10.3",
"fRoute":[
"10.255.253.0/30",
" 10.255.254.0/30"
],
"timeout":1800,
"mapId":"test_map"
}
]
}
}
My Parser class have something like,
JSONObject requestJSON = new JSONObject(requestBody).getJSONObject("data");
ObjectMapper mapper = new ObjectMapper();
final String jsonData = requestJSON.toString();
OrderDTO mappedObject= mapper.readValue(jsonData , OrderDTO .class);
// I can see value coming from front-end but not populating in the mappedObject
My OrderDTO.java
#JsonInclude(value = Include.NON_NULL)
#JsonIgnoreProperties(ignoreUnknown = true,value = {"hibernateLazyInitializer", "handler", "created"})
public class OrderDTO {
private String username;
private long customerId;
private String source;
private String firstName;
private String lastName;
private String email;
private String contactNumber;
private String password;
private String department;
private String location;
private String status;
private List<OrderConfig> OrderConfigs;
#JsonInclude(value = Include.NON_NULL)
public class OrderConfig {
private String vpnId;
private String serviceId;
private String serviceType;
private String ipAddress;
private String mapId;
private String[] fRoutes;
private Map<String, Object> attributes;
private SubConfig subConfig;
private String routeFlag;
getter/setters
.....
}
all setter/getter
}
Not sure what I'm missing here. Is this right way to do?
If your are trying to use inner class, correct way to use is to declare it static for Jackson to work with inner classes.
For reference check this
code changes made are
#JsonInclude(value = Include.NON_NULL)
#JsonIgnoreProperties(ignoreUnknown = true)
static class OrderConfig {
Make sure that your json tag names match with variable names of java object
Ex : "fRoute":[
"10.255.253.0/30",
" 10.255.254.0/30"
],
private String[] fRoutes;
OrderConfigs fields will not be initialized, just modify your bean as
#JsonProperty("OrderConfigs")
private List<OrderConfig> orderConfigs;
// setter and getter as setOrderConfigs / getOrderConfigs
See my answer here. (same issue)

Categories