Java is a popular and general-purpose programming language that works on different systems like Mac, Windows, Linux, etc. It is used for different purposes, all for programming. When working with Java, you may encounter no string-argument constructor/factory method to deserialize from string value warning.
Today we are going to discuss this Java error. Let’s see how this occurs and how to fix this Java error
How To Fix no string-argument constructor/factory method to deserialize from string value
To fix the error, first we need to know how you may land up in this error when you code, then we shed light on all the possible solutions. Let’s take a look at how the error occurs
Issue
The error occurs when you are trying to use the ‘ObjectMapper’ class from the package ‘com.fasterxml.jackson.databind. It happens when there is a parsing issue. You will get an error:
com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.graybar.utilities.ups.beans.Location: no String-argument constructor…
It occurs when using the web application in Angular JS, spring MVC. Take a look at the bean to see the causes of error in detail
@JsonIgnoreProperties(ignoreUnknown = true)
public class Lading {
@JsonProperty("Work")
private ArrayList<Work> work;
public ArrayList<Work> getWork() {
return work;
}
public void setWork(ArrayList<Work> work) {
this.work = work;
}
}
@JsonIgnoreProperties(ignoreUnknown = true)
public class Work {
@JsonProperty("WorkLocation")
private ArrayList<WorkLocation> workLocation;
public ArrayList<WorkLocation> getWorkLocation() {
return workLocation;
}
public void setWorkLocation(ArrayList<WorkLocation> workLocation) {
this.workLocation = workLocation;
}
}
@JsonIgnoreProperties(ignoreUnknown = true)
public class WorkLocation {
@JsonProperty("Location")
private Location location;
// GETTER
public Location getLocation() {
return location;
}
// SETTER
public void setLocation(Location location) {
this.location = location;
}
}
@JsonIgnoreProperties(ignoreUnknown = true)
public class Location {
@JsonProperty("Town")
private String town;
@JsonProperty("StateProvCode")
private String stateProvCode;
@JsonProperty("NationCode")
private String nationCode;
public String getTown() {
return town;
}
public void setTown(String town) {
this.town = town;
}
public String getNationCode() {
return nationCode;
}
public void setNationCode(String nationCode) {
this.nationCode = nationCode;
}
public String getStateProvCode() {
return stateProvCode;
}
public void setStateProvCode(String stateProvCode) {
this.stateProvCode = stateProvCode;
}
}
Now, check out the code where json is properly mapped
public static void main(String[] args) {
String jsonMessage = "" +
"{" +
" \"Work\": [{ " +
" \"WorkLocation\": { " +
" \"Location\": { " +
" \"Town\": \"Hana\", " +
" \"StateProvCode\": \"Hi\", " +
" \"NationCode\": \"US\" " +
" } " +
" } " +
" }, " +
" { " +
" \"WorkLocation\": { " +
" \"Location\": { " +
" \"Town\": \"Honolulu\", " +
" \"StateProvCode\": \"Hi\", " +
" \"NationCode\": \"US\" " +
" } " +
" } " +
" }] " +
"} ";
try {
ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
Lading lading = mapper.readValue(jsonMessage, Lading.class);
System.out.println("lading.toString = " + lading.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
Here, the error message warning shows up all the time you are trying to adjust the data in the‘jsonMessage’ var
com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.graybar.utilities.ups.beans.Location: no String-argument constructor…
The problem occurs when:
"{" +
" \"Work\": [{ " +
" \"WorkLocation\": { " +
" \"Location\": { " +
" \"Town\": \"Hana\", " +
" \"StateProvCode\": \"Hi\", " +
" \"NationCode\": \"US\" " +
" } " +
" } " +
" }, " +
" { " +
" \"WorkLocation\": { " +
" \"Location\": \"\" " +
" } " +
" } " +
" }] " +
"} ";
When trying to change the json from the following
{
"WorkLocation": {
"Location": {
"Town": "Honolulu",
"StateProvCode": "Hi",
"NationCode": "US"
}
}
}]
Into the code below
{
"WorkLocation": {
"Location": ""
}
}
Solution To Fix the no string-argument constructor/factory method to deserialize from string value
Solution 1
When you are coding, try to set the below code in your program can solve the issue
mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
or you can also add
mapper.configure(
DeserializationConfig.Feature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT,
true)
You can set this according to the version you are using.
Solution 2
You need to check how you are calling the method as arguments can be the same and that’s when yourIDE can catch many things.
You need to use: mapper.readValue(...)
If you have used the following, then you need to replace
mapper.convertValue(...)
Solution 3
In most of cases, the below code works wonders
ObjectMapper objectMapper = new ObjectMapper();
String jsonString = "{\"symbol\":\"ABCD\}";
objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
Trade trade = objectMapper.readValue(jsonString, new TypeReference<Symbol>() {});
When using the code, you can get the error solved. Check out
@JsonIgnoreProperties public class Symbol {
@JsonProperty("symbol")
private String symbol;
}
Solution 4
Another basic solution to this issue is to replace “” with curly brackets {} as the deserializer doesn’t identify the location constructor with a string argument.
Conclusion
Here we have discussed how you get the error no string-argument constructor/factory method to deserialize from string value along with the issue sample code. We also highlighted the possible solutions to get through the issue. Hope you find it helpful!