Bloodboy
(Tobias)
January 2, 2022, 7:59pm
1
Hello all,
is there any way to get also the http status code (200,401) when using sendHttpGetRequest/sendHttpPostRequests?
I query the API of my wallbox and partly you only get a http status conde instead of a real answer.
If this is not possible, I have seen that if the http status code of sendHttpGetRequest/sendHttpPostRequests is not successful (200 or 201), this appears in the log as an error.
Can I possibly catch this via try/catch?
E.g. when there is an error logging into my wallbox, the following error appears in the log:
[ERROR] [enhab.core.model.script.actions.HTTP] - Fatal transport error: java.util.concurrent.ExecutionException: org.eclipse.jetty.client.HttpResponseException: HTTP protocol violation: Authentication challenge without WWW-Authenticate header
This seems to be a 401…
rlkoshak
(Rich Koshak)
January 2, 2022, 8:23pm
2
No you cannot get the code from the actions. You’ll have to resort to lower level HTTP libraries to get the codes.
You can’t catch that error because it’s just a log statement, not a thrown exception.
Bloodboy
(Tobias)
January 24, 2022, 8:03pm
3
Hi rlkoshak,
thanks for your explanation and sorry for my late feedback!
I figured out how to use the low level java http libraries in a lambda:
import java.net.URL
import java.net.HttpURLConnection
import java.io.BufferedInputStream
import java.io.BufferedReader
import java.io.InputStreamReader
import org.eclipse.xtext.xbase.lib.Functions
import java.util.Map
val Functions$Function4<String, String, Map<String,String>, String, Map<String,String>> http = [method, url, headers, payload |
val endpointUrl = new URL(url)
val HttpURLConnection connection = endpointUrl.openConnection() as HttpURLConnection
var StringBuffer sb = new StringBuffer()
var BufferedReader br
var String inputLine = ""
connection.setConnectTimeout(5000)
connection.requestMethod = method
for (Map.Entry<String, String> set : headers.entrySet())
{
// Printing all elements of a Map
//logInfo("EaseeHome API","httpGet headers:" + set.getKey() + " = " + set.getValue())
connection.setRequestProperty(set.getKey(), set.getValue())
}
connection.doOutput = true
connection.setDoInput = true
if (method == 'POST')
{
connection.outputStream.write(payload.getBytes("UTF-8"))
}
if (connection.responseCode == 200 || connection.responseCode == 201)
{
br = new BufferedReader(new InputStreamReader(new BufferedInputStream(connection.getInputStream())))
while ((inputLine = br.readLine()) !== null)
{
sb.append(inputLine)
}
}
else
{
br = new BufferedReader(new InputStreamReader(new BufferedInputStream(connection.getErrorStream())))
while ((inputLine = br.readLine()) !== null)
{
sb.append(inputLine)
}
}
var result = newHashMap("httpResponseCode" -> connection.responseCode.toString, "json" -> sb.toString)
return result
]
The lambda returns a HashMap with first the response code and then the response answer.
Your use it like this:
RequestBody = '{ "userName": "'+userName+'", "password": "'+password+'" }'
var headers = newHashMap("content-type" -> "application/json")
result = http.apply('POST',url,headers,RequestBody)
json = result.get("json")
if(result.get("httpResponseCode") == "200" || result.get("httpResponseCode") == "201")
{
item_json.postUpdate(json)
}
You can use post and get method.