Spring REST API is responding with following response:
On successful execution : It returns me a response of Text type.
On unsuccessful execution : It returns me JSON error object.
Front-End Service Class :
private detailsURL = 'http://localhost:8080/register';
constructor(private http:HttpClient){}
register(regisDetails): Observable<any>{
return this.http.post(this.detailsURL,regisDetails);
}
Front-End Component Class:
registerUser(){
this.service.register(this.regisForm.value).subscribe(
success => this.successMessage = success,
error => this.errorMessage = error.error.errorMessage
);
}
In case of error I'm getting the error message I'm supposed to get. But in case of success I'm not getting the successMessage.
Just wanted to know if there's any way to fetch the Text type response on front end. Or else I'll have to change my backend to send response of JSON Type for successful execution as well.
Please help me understand this thing.
You have to set the status for your response. In the controller part you have to mention consumes="application/json" in api request.
You should be doing your changes at the backend and provide the response in Json format response for both the success and backend. That would be the ideal solution.
It is really a bad design to provide a different response than what is expected. You could check the value of the header in request "accept:application/json" and provide response as was expected by the front end
Front End Fix :
However, in the front end you could always use
JSON.parse(success) to convert the text to Json object and use it further as required.
In my controller file I have a method that reads the incoming HTTP request, reads the user data from the Database, encodes the result in JSON (using jsx) and sends it in response.
sensorusersdetails('GET', []) ->
Headers = [{'Access-Control-Allow-Origin', "*"},
{'Access-Control-Allow-Methods', "GET, OPTIONS"},
{'Content-Type', "application/json"},
{'Access-Control-Allow-Headers', "X-Requested-With"},
{'Access-Control-Max-Age', "180"}],
Building = Req:query_param("bld"),
io:format("User Data request from Node.js server~n~p~n",
[Req:query_params()]),
{{Year,Month,Day},{_,_,_}} = erlang:localtime(),
StrDate = lists:flatten(io_lib:format("~4..0w-~2..0w-~2..0w",
[Year,Month,Day])),
BUserDataList = boss_db:find(sensoruser_data, [{building, 'equals', Building}]),
io:format("Current Users Data stored in the database: ~n~p~n",[BUserDataList]),
MyUserJSONList = sensor_preapre_data(BUserDataList, StrDate),
io:format("The Present Date Sensor Users Data with Binary 1: ~n~p~n",[MyUserJSONList]),
MyUserJSONListLength = length(MyUserJSONList),
if MyUserJSONListLength > 0 ->
MyFinalList = sensor_data_final(MyUserJSONList),
io:format("The Present Date Sensor Users Data without Binary 2: ~n~p~n",[MyFinalList]),
{200, [MyFinalList], Headers};
%%{json, MyFinalList};
true ->
{200, "NO DATA FOUND", Headers}
%%{json, [{error, "NO DATA FOUND"}]}
end.
In the Chicagoboss Server logs I'm getting:
The Present Date Sensor Users Data with Binary 1:
[[<<"{\"username\":\"KPBatman1\",\"building\":\"A\",\"device\":\"Fitbit\",\"date\":\"2017-07-23\",\"calorie\":732,\"distance\":6.4399999999999995,\"elevation\":0,\"floor\":0,\"steps\":8}">>],
[<<"{\"username\":\"KPSuperman1\",\"building\":\"A\",\"device\":\"Jawbone\",\"date\":\"2017-07-23\",\"calorie\":0,\"distance\":0.0,\"elevation\":0,\"floor\":0,\"steps\":0}">>]]
The Present Date Sensor Users Data without Binary 2:
[["{\"username\":\"KPBatman1\",\"building\":\"A\",\"device\":\"Fitbit\",\"date\":\"2017-07-23\",\"calorie\":732,\"distance\":6.4399999999999995,\"elevation\":0,\"floor\":0,\"steps\":8}"],
["{\"username\":\"KPSuperman1\",\"building\":\"A\",\"device\":\"Jawbone\",\"date\":\"2017-07-23\",\"calorie\":0,\"distance\":0.0,\"elevation\":0,\"floor\":0,\"steps\":0}"]]
However, when I send the HTTP request - the JSON response I am getting:
{"username":"KPBatman1","building":"A","device":"Fitbit","date":"2017-07-23","calorie":732,"distance":6.4399999999999995,"elevation":0,"floor":0,"steps":8}
{"username":"KPSuperman1","building":"A","device":"Jawbone","date":"2017-07-23","calorie":0,"distance":0.0,"elevation":0,"floor":0,"steps":0}
What is the correct way to send JSON response?
However, when I send the HTTP request - the JSON response I am
getting:
{"username":"KPBatman1","building":"A", ...}
{"username":"KPSuperman1","building":"A", ...}
And? What did you expect/want to get?
The following code works for me because the output is what I expected to see:
-module(cb_tutorial_greeting_controller, [Req]).
-compile(export_all).
hello('GET', []) ->
Headers = [
{'Access-Control-Allow-Origin', "*"},
{'Access-Control-Allow-Methods', "GET, OPTIONS"},
{'Content-Type', "application/json"},
{'Access-Control-Allow-Headers', "X-Requested-With"},
{'Access-Control-Max-Age', "180"}
],
Data = [
[<<"{\"username\":\"KPBatman1\",\"building\":\"A\"}">>],
[<<"{\"username\":\"KPSuperman1\",\"building\":\"A\"}">>]
],
Json = jsx:encode(Data),
{200, Json, Headers}.
In my browser, I see:
[["{\"username\":\"KPBatman1\",\"building\":\"A\"}"],["{\"username\":\"KPSuperman1\",\"building\":\"A\"}"]]
Note that MyFinalList isn't even valid JSON:
13> Data = [["{\"a\":\"Batman\"}"], ["{\"b\":\"Superman\"}"]].
[["{\"a\":\"Batman\"}"],["{\"b\":\"Superman\"}"]]
14> jsx:is_json(Data).
false
See what I did there?
EDIT: Here's a bit more context to how the JSON is received. I'm using the ApiAI API to generate a request to their platform, and they have a method to retrieve it, like this:
# instantiate ApiAI
ai = apiai.ApiAI(CLIENT_ACCESS_TOKEN)
# declare a request obect, fill in in lower lines
request = ai.text_request()
# send ApiAI the request
request.query = "{}".format(textobject.body)
# get response from ApiAI
response = request.getresponse()
response_decode = response.read().decode("utf-8")
response_data = json.loads(response_decode)
I'm coding a webapp in Django and trying to read through a JSON response POSTed to a webhook. The code to read through the JSON, after it has been decoded, is:
if response_data['result']['action'] != "":
Request.objects.create(
request = response_data['result']['resolvedQuery']
)
When I try to run this code, I get this error:
KeyError: 'result'
on the line
if response_data['result']['action'] != "":
I'm confused because it looks to me like 'result' should be a valid key to this JSON that is being read:
{
'id':'65738806-eb8b-4c9a-929f-28dc09d6a333',
'timestamp':'2017-07-10T04:59:46.345Z',
'lang':'en',
'result':{
'source':'agent',
'resolvedQuery':'Foobar',
'action':'Baz'
},
'alternateResult':{
'source':'domains',
'resolvedQuery':'abcdef',
'actionIncomplete':False,
},
'status':{
'code':200,
'errorType':'success'
}
}
Is there another way I should be reading this JSON in my program?
Try:
import JSON
if 'action' in response_data:
parsed_data = json.loads(response_data)
if parsed_data['result']['action'] != "":
Request.objects.create(request = parsed_data['result']['resolvedQuery'])
Thanks for everyone's thoughts. It turned out there was an another error with how I was trying to implement the ApiAI API, and that was causing this error. It now reads through the JSON fine, and I'm using #sasuke's suggestion.
I have a REST service which I am testing with SoapUI. The first step in my TestSuite returns the following Response (Json):
{
"mtMessageId": 52003685,
"status":
{
"value": 0,
"code": "OK",
"text": "Text message submitted"
},
"custMessageId": 123,
"custMessageRef": null
}
I want to 'Transfer' the value from the mtMessageId into the HTTP Get Request in the next step.
The request is formatted like "/SMS/{id}"
How do I transfer the value into the Request?
First of all you have to set the resource of your get method in your request with a property for example using /SMS/${#TestCase#id} in order to retrieve it from the first request.
Then add a groovy script testStep between your requests. An use the follow code to get the id from the json response of the first request and set as a property for the second request.
import groovy.json.*
// get the response from the first request using its name
def response = context.expand('${Request 1#Response}')
// parse it
def json = new JsonSlurper().parseText(response)
log.info json.mtMessageId
// get the json value an set it as property in testCase
context.testCase.setPropertyValue("id",json.mtMessageId.toString())
Note that you can use property transfer testStep to get the value from your request and set it as a property, however since SOAPUI converts all to xml I prefer to use a groovy script to work json.
Hope it helps,
I am using Play scala WS to send a REST api call to a web server and sometimes get an exception error. Json is sent to the server and the response from the server could be one of the following.
Server returns a valid Json response.
Server returns "No valid Json found"
Server returns an error web page that triggers the exception error com.fasterxml.jackson.core.JsonParseException: Unexpected character ('<' (code 60)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')
How do I modify the code below to get the contents of the web page without the exception error?
import play.api.libs.ws._
var tempText = Helpers.await(WS.url("localhost:9000/someApi").post(jsonToSend)).body
println(tempText)
tempJson = Json.parse(tempText)
println(tempJson)
Much depends on how "correct" that downstream API server is.
In a perfect world, we could probably assert the following facts:
Success case => HTTP status is 200, HTTP Content-Type header is application/json
"No valid Json found" => HTTP status is 404 or similar non-200, HTTP Content-Type header is application/json
"Error web page" => HTTP status is not 200, Content-Type is text/html
If the above assertions are all true, then we can simply put a little bit of "protection" around our response-handling rather than just jumping in and trying to parse it as JSON:
val futureOptionalResult = WS.url("localhost").post("...").map { response =>
response.status match {
case 200 => {
println(response.body)
println(response.json)
Some(response.json)
}
case _ => {
println(s"Not OK: ${response.status} - body is: ${response.body}")
None
}
}
}
Some notes:
Doing it asynchronously is just as easy as using an await and scales better
response.json returns the same thing as your explicit Json.parse on the body
I'm returning an Option[JsValue] that holds the returned JSON if it worked
If the above assumptions are not true, deeper inspection of the Content-Type header, finer-grained switching on the status value and/or other attributes of the response will probably be needed. Good luck!