In JsnoToApex class I try to GET JSON file from https://openweathermap.org/current. When I try to parse JSON.CreateParses I get these error: Illegal assignment from System.JSONParser to JsonParser
I try to make API that show weather in London.
public with sharing class JsonToApex {
#future(callout=true)
public static void parseJSONResponse() {
String resp;
Http httpProtocol = new Http();
// Create HTTP request to send.
HttpRequest request = new HttpRequest();
// Set the endpoint URL.
String endpoint = 'https://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=b6907d289e10d714a6e88b30761fae22';
request.setEndPoint(endpoint);
// Set the HTTP verb to GET.
request.setMethod('GET');
// Send the HTTP request and get the response.
// The response is in JSON format.
HttpResponse response = httpProtocol.send(request);
resp = response.getBody();
JSONParser parser = JSON.createParser(resp);
JsonMapper response = (JsonMapper) System.JSON.deserialize(res.getBody(), JsonMapper.class);
}
}
I expect to get Json file and in future map it using https://json2apex.herokuapp.com/
The problem was in first JSONParser. I had to add System.JSONParser to make it work.
System.JSONParser parser = JSON.createParser(resp);
You may have two approaches:
If you have already map the JSON into an Apex class, you may just use
JSON2Apex aClass = (JSON2Apex) System.JSON.deserialize(resp, JSON2Apex.class);
Where JSON2Apex is the mapping Apex class.
Use the JSON.deserializeUntyped(String jsonString) to deserialize the JSON to any Object in Apex class, like:
Map<String, Object> objMap = (Map<String, Object>) JSON.deserializeUntyped(resp);
Related
I came across a weird scenario.
I was calling a External API which is returning Lists of LinkedHashMap (E.g: List<LinkedHashMap<String, String>)
So the question is how to convert this JSON response to Custom Response object in Java
Use the below code to convert JSON response to Custom Response object in Java.
ResponseEntity<Object> response = restTemplate.exchange(
pathURL,
HttpMethod.{GET/POST ..},
createHeader(),
Object.class
);
final List<LinkedHashMap> responseList = objectMapper
.convertValue(
response.getBody(),
new TypeReference<List<LinkedHashMap>>() {
}
);
LinkedHashMap<String, String> responseMap = responseList.get(0);
CustomResponseObj infoResp = objectMapper.convertValue(responseMap, CustomResponseObj.class);
private HttpEntity<?> createHeader() {
HttpHeaders headers = new HttpHeaders();
return new HttpEntity<>(headers);
}
I would like to print the json response from a RESTful request in the browser in a easy human readable format, keeping json's linebreaks and indentations.
My current code saves the json response in a String and prints the string without any formatting.
In RESTFulController.java
#Controller
public class RESTFulControllerController {
#RequestMapping("myrequest")
public String myRequest(Model model) {
//--> Initializations
RestTemplate rest_template= new RestTemplate();
String url = "https://example.com/api";
//--> Create http request
HttpHeaders headers = new HttpHeaders();
MultiValueMap<String, String> body_map = new LinkedMultiValueMap<>();
body_map.add("resource_id", "value_of_resource_id");
HttpEntity<MultiValueMap<String, String>> request_entity = new HttpEntity<>(body_map, headers);
//--> Post http request
String response = rest_template.postForObject(url, request_entity, String.class);
//--> Add data for display
model.addAttribute("response", response);
return "print_response";
}
In templates/print_response.html
<body>
[[${response}]]
</body>
There is no need for further processing the response, it will be used only for its visualization in the browser. Is it better to do the formatting in the controller or in the template? and how?
Thanks in advance!
You can try to convert your response string to a json object and then back to a indented string:
ObjectMapper objectMapper = new ObjectMapper();
Object json = objectMapper.readValue(response, Object.class);
String indented = objectMapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(json);
For some reason RestSharp is not deserializing the response:
RestClient client = new RestClient(baseURL);
RestRequest request = new RestRequest("api/location/" + locationID, Method.GET);
IRestResponse<Location> response = client.Execute<Location>(request);
return response.Data;
I confirm the Web API is returning valid result.
The response object has:
Content: {"LocationID":3,"PrintName":"MyCountry","ISO3166_1_alpha3":"XXX"}
StatusCode: OK
ResponseStatus: Completed
However response.Data has a Location object with default values (null).
Using Json.NET over RestSharp Content works (meaning the correct data is there):
Location loc = JsonConvert.DeserializeObject<Location>(response.Content);
The Location class should not matter in this case since Json.NET is able to deserialize. For some reason RestSharp is not deserializing.
public class Location
{
public int LocationID;
public string PrintName;
public string ISO3166_1_alpha3;
}
I think RestSharp client will only deserialize properties. Try to append
{ get; set; }
to each field. It should work.
I think the server is returning an incorrect Content-Type (not 'application/json'). If so, you can tell Restsharp to do json deserialization by setting the correct Content-Type:
RestClient client = new RestClient(baseURL);
RestRequest request = new RestRequest("api/location/" + locationID, Method.GET);
//because the response returned is probably an incorrect content type, fix it here
request.OnBeforeDeserialization = resp => { resp.ContentType = "application/json"; };
IRestResponse<Location> response = client.Execute<Location>(request);
return response.Data;
I have created a rest webservice which has a below code in one method:
#POST
#Path("/validUser")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public JSONObject validUserLogin(#QueryParam(value="userDetails") String userDetails){
JSONObject json = null;
try{
System.out.println("Service running from validUserLogin :"+userDetails);
json = new JSONObject(userDetails);
System.err.println("UserName : "+json.getString("userName")+" password : "+json.getString("password"));
json.put("httpStatus","OK");
return json;
}
catch(JSONException jsonException) {
return json;
}
}
I am using Apache API in the client code.And below client code is calling this service, by posting some user related data to this service:
public static String getUserAvailability(String userName){
JSONObject json=new JSONObject();
try{
HttpContext context = new BasicHttpContext();
HttpClient client = new DefaultHttpClient();
client.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2109);
URI uri=new URIBuilder(BASE_URI+PATH_VALID_USER).build();
HttpPost request = new HttpPost(uri);
request.setHeader("Content-Type", "application/json");
json.put("userName", userName);
StringEntity stringEntity = new StringEntity(json.toString());
request.setEntity(stringEntity);
HttpResponse response = client.execute(request,context);
System.err.println("content type : \n"+EntityUtils.toString(response.getEntity()));
}catch(Exception exception){
System.err.println("Client Exception: \n"+exception.getStackTrace());
}
return "OK";
}
The problem is, I am able to call the service, but the parameter I passed in the request to service results in null.
Am I posting the data in a wrong way in the request. Also I want to return some JSON data in the response, but I am not able to get this.
With the help of Zack , some how i was able to resolve the problem,
I used jackson-core jar and changed the service code as below.
#POST
#Path("/validUser")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public JSONObject validUserLogin(String userDetails){
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readValue(userDetails, JsonNode.class);
System.out.println("Service running from validUserLogin :"+userDetails);
System.out.println(node.get("userName").getTextValue());
//node.("httpStatus","OK");
return Response.ok(true).build();
}
I was using Jersey 1.16 to consume a JSON, but now I'm with difficulties to consume a JSON using Jersey 2.0 (that implements JAX-RS 2.0).
I have a JSON response like this:
{
"id": 105430,
"version": 0,
"cpf": "55443946447",
"email": "maria#teste.br",
"name": "Maria",
}
and the method that consumes it:
public static JSONObject get() {
String url = "http://127.0.0.1:8080/core/api/person";
URI uri = URI.create(url);
final Client client = ClientBuilder.newClient();
WebTarget webTarget = client.target(uri);
Response response = webTarget.request(MediaType.APPLICATION_JSON).get();
if (response.getStatus() == 200) {
return response.readEntity(JSONObject.class);
}
}
I also tried:
return webTarget.request(MediaType.APPLICATION_JSON).get(JSONObject.class);
But the jSONObject return is null. I don't understand my error because the response is OK!
This is how to use the Response type correctly:
private void getRequest() {
Client client = ClientBuilder.newClient();
String url = "http://localhost:8080/api/masterdataattributes";
WebTarget target = client.target(url);
Response res = target
.request(MediaType.APPLICATION_JSON)
.get();
int status = res.getStatus();
String json = res.readEntity(String.class);
System.out.println(String.format("Status: %d, JSON Payload: %s", status, json));
}
If you're just interested in the payload, you could also just issue a get(String.class). But usually you will also want to check the response status, so working with the Response is usually the way to go.
If you want a typed (generic) JSON response, you could also have readEntity return a Map, or a list of Map if the response is an array of objects as in this example:
List<Map<String, Object>> json = res.readEntity(new GenericType<List<Map<String, Object>>>() {});
String id = (String) json.get(0).get("id");
System.out.println(id);
I have found the solution. Maybe it is not the best of, but it works.
public static JsonObject get() {
String url = "http://127.0.0.1:8080/core/api/person";
URI uri = URI.create(url);
final Client client = ClientBuilder.newClient();
WebTarget webTarget = client.target(uri);
Response response = webTarget.request(MediaType.APPLICATION_JSON).get();
//Se Response.Status.OK;
if (response.getStatus() == 200) {
StringReader stringReader = new StringReader(webTarget.request(MediaType.APPLICATION_JSON).get(String.class));
try (JsonReader jsonReader = Json.createReader(stringReader)) {
return jsonReader.readObject();
}
}
return null;
}
I switched the class JSONObject (package import org.codehaus.jettison) by JsonObject (package javax.json) and I used the methods to manipulate the content as String.
S.
mmey answer is the correct and optimal one, instead of invoking the service twice it does it one time.