I have C# based web API. I am using Newtonsoft JSON to transfer the data.
[HttpGet]
[Route("birthdays/{month}")]
public String GetBirthdays(int month)
{
List<BirthdayPropertiesDTO> dtoList = Mapper.Map<List<Property>, List<BirthdayPropertiesDTO>> (worker.PropertiesRepo.Get().ToList());
foreach(BirthdayPropertiesDTO dto in dtoList)
{
dto.Birthdays = Mapper.Map<List<BirthdayList>, List<BirthdayDTO>>(worker.BirthdayRepo.Get(e => e.LocID == dto.ID && e.BirthMonth == month).ToList());
}
return JsonConvert.SerializeObject(dtoList);
}
I have used a nearly identical approach (within the same API) for other endpoints, and have been able to successfully consume the data with JavaScript and PHP. However, the following Java code:
public class RESTClient {
private static String END_POINT = "http://localhost:57263/locations/birthdays";
public String sendRequest() {
Gson gson = new Gson();
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
List<Property> propObj = new ArrayList<Property>();
Type formType = new TypeToken<List<Property>>() {
}.getType();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
String props = restTemplate.getForObject(
MessageFormat.format("{0}/{1}", END_POINT, LocalDateTime.now().getMonthValue()), String.class, headers);
propObj = gson.fromJson(props, formType);
return props;
}
}
returns an exception:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 2 path $
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:224)
at com.google.gson.Gson.fromJson(Gson.java:888)
at com.google.gson.Gson.fromJson(Gson.java:853)
at com.google.gson.Gson.fromJson(Gson.java:802)
at com.google.gson.Gson.fromJson(Gson.java:774)
at com.midamcorp.birthdaylist.RESTClient.sendRequest(RESTClient.java:33)
at RESTTest.testRequest(RESTTest.java:17)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:539)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:761)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:461)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:207)
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 2 path $
at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:385)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:213)
... 29 more
I have referenced similar questions (including this one), but have yet to find a resolution to my problem.
According to this tool, the JSON is valid.
"[{\"ID\":1,\"PropertyNumber\":\"1094\",\"Email\":\"email@email.com\",\"ManagerEmail\":\"email@email.com\",\"Birthdays\":[]},{\"ID\":2,\"PropertyNumber\":\"1175\",\"Email\":\"email@email.com\",\"ManagerEmail\":\"email@email.com\",\"Birthdays\":[]}
I also tried wrapping the object in another class (instead of using a List implementation), but received a similar exception.
package com.midamcorp.birthdaylist;
import java.util.ArrayList;
import java.util.List;
public class BirthdayPropertyList {
private List<Property> properties = new ArrayList<Property>();
public List<Property> getProperties() {
return properties;
}
public void setProperties(List<Property> properties) {
this.properties = properties;
}
}
The Java object:
public class Property {
private int id;
private String propertyNumber;
private String email;
private String managerEmail;
private List<Birthday> birthdays;
public String getPropertyNumber() {
return propertyNumber;
}
public void setPropertyNumber(String propertyNumber) {
this.propertyNumber = propertyNumber;
}
public String getStoreEmail() {
return email;
}
public void setStoreEmail(String storeEmail) {
this.email = storeEmail;
}
public String getManagerEmail() {
return managerEmail;
}
public void setManagerEmail(String managerEmail) {
this.managerEmail = managerEmail;
}
public List<Birthday> getBirthdays() {
return birthdays;
}
public void setBirthdays(List<Birthday> birthdays) {
this.birthdays = birthdays;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
The C# DTO:
public class BirthdayPropertiesDTO
{
public int ID { get; set; }
public String PropertyNumber { get; set; }
public String Email { get; set; }
public String ManagerEmail { get; set; }
public List<BirthdayDTO> Birthdays { get; set; }
}
Any advice would be appreciated.