Android Question HttpJob - Post and receive bytes

Hello,

I developed a code to to send and receive JSON data to an API. The original code send and receive an JSON and is working fine.

Now I want to do the same code to send and receiving bytes to reduce the traffic. I could do the code for POST bytes, below the original code for "POST JSON" and new code for "POST BYTES":

[CODE lang="b4x" title="Original Post"] JsonData=GenerateJSON("TbColetaProdutoLocal")
Http_TbColetaProdutoLocal.Initialize("inserecoletaprodutolocal", Me)
Http_TbColetaProdutoLocal.username = GlobalModule.username
Http_TbColetaProdutoLocal.password = GlobalModule.password
Http_TbColetaProdutoLocal.PostString(host & "/inserecoletaprodutolocal", JsonData)
Http_TbColetaProdutoLocal.GetRequest.SetContentType("application/json")
Http_TbColetaProdutoLocal.GetRequest.Timeout = 2400000
wait for (Http_TbColetaProdutoLocal) JobDone(Http_TbColetaProdutoLocal As HttpJob)
If Http_TbColetaProdutoLocal.Success Then

If Not(Main.dbSQL.IsInitialized) Then
Main.dbSQL.Initialize(File.DirInternal, "cra.db", False)
End If
Main.dbSQL.ExecNonQuery("update TbColetaprodutoLocal set enviado=1 where enviado=0")
Main.dbSQL.Close

Log("Dados de ColetaProdutoLocal Enviados")

Else
ToastMessageShow("Erro ao enviar dados de ColetaProdutoLocal", True)
End If
Http_TbColetaProdutoLocal.release[/CODE]


To reduce the traffic I converted the code to :

[CODE lang="b4x" title="New Code using bytes compressed"] JsonData=GenerateJSON("TbColetaProdutoLocal")

SendData = ByteConvert.StringToBytes(JsonData, "UTF-8")
Http_TbColetaProdutoLocal.Initialize("inserecoletaprodutolocal", Me)
Http_TbColetaProdutoLocal.username = GlobalModule.username
Http_TbColetaProdutoLocal.password = GlobalModule.password
Http_TbColetaProdutoLocal.PostBytes(host & "/inserecoletaprodutolocal_v2", Compressor.CompressBytes(SendData, "zlib"))
Http_TbColetaProdutoLocal.GetRequest.SetContentType("application/octet-stream") '
Http_TbColetaProdutoLocal.GetRequest.Timeout = 480000
wait for (Http_TbColetaProdutoLocal) JobDone(Http_TbColetaProdutoLocal As HttpJob)
If Http_TbColetaProdutoLocal.Success Then

If Not(Main.dbSQL.IsInitialized) Then
Main.dbSQL.Initialize(File.DirInternal, "cra.db", False)
End If
Main.dbSQL.ExecNonQuery("update TbColetaprodutoLocal set enviado=1 where enviado=0")
Main.dbSQL.Close

Log("Dados de ColetaProdutoLocal Enviados")

Else
Log("ERRO ao enviar ColetaProdutoLocal")
ToastMessageShow("Erro ao enviar dados de ColetaProdutoLocal", True)
End If
Http_TbColetaProdutoLocal.release[/CODE]

In the server side I have an API developed in Python :
[CODE lang="b4x" title="Server Side"]class inserecoletaprodutolocal_v2(Resource):
@auth.login_required
def post(self):

conn = db_connect()
json_bytes=zlib.decompress( request.data )
json_str = json_bytes.decode('utf-8')
data = json.loads(json_str)
print json_str
conn.execute("exec cra_insertrecord 'CRA_TbColetaProdutoLocal','" + json_str + "'")

conn.commit()
conn.close()
return {'status':'success'}[/CODE]

Both codes is working fine, but now I need do the same thing not for "POST" but for the "GET"

I wrote this code :

[CODE lang="b4x" title="Request"] Http_LojaProdutoModulo.Initialize("LojaProdutoModulo", Me)
Http_LojaProdutoModulo.Download(host & "/lojaprodutomodulo_v2/" & idUsuario)
Http_LojaProdutoModulo.username = GlobalModule.username
Http_LojaProdutoModulo.password = GlobalModule.password
Http_LojaProdutoModulo.GetRequest.Timeout = 480000[/CODE]


[CODE lang="b4x" title="JobDone"]Sub JobDone(Job As HttpJob)
ProgressDialogHide
Dim parser As JSONParser

If Job.Success Then
Dim ByteConvert As ByteConverter
Dim Compressor As CompressedStreams
Dim ReceivedData() As Byte

Dim str As String


ReceivedData = Compressor.DecompressBytes(Job.GetString.GetBytes("UTF8"), "zlib")

str=ByteConvert.StringFromBytes(ReceivedData, "UTF-8")

parser.Initialize(str)


Dim root As List = parser.NextArray
For Each colroot As Map In root
Dim cdLoja As Int = colroot.Get("cdLoja")
Dim cdProduto As Int = colroot.Get("cdProduto")
Dim cdOnda As Int = colroot.Get("cdOnda")
Dim nuMod As String = colroot.Get("nuMod")
Dim packvirtual As Int = colroot.Get("packvirtual")
Main.dbSQL.ExecNonQuery2("INSERT INTO TbLojaProdutoModulo (cdLoja, cdProduto, cdOnda, nuMod, packvirtual) values (?, ?, ?, ?, ?)", Array As Object(cdLoja, cdProduto, cdOnda, nuMod, packvirtual ))
Next


end if
[/CODE]

In the server side for GET I have:

[CODE lang="b4x" title="Server Side ( GET)"]class LojaProdutoModulo_v3(Resource):
@auth.login_required
def get(self, cod_usuario):
conn = db_connect()
query = conn.execute("select distinct top 10 tLPM.cdLoja, tLPM.cdProduto, tLPM.cdOnda, dbo.PMC_ModulosProduto(nuModulo) as nuMod, case when isNull(tLMP10.cdOnda, 0)=0 then 0 else 1 end as packvirtual from tbLojaProdutoModulo tLPM with (Nolock) inner join tbUsuarioLoja tUL with (Nolock) on tUL.cdLoja = tLPM.cdLoja and tUL.cdOnda = tLPM.cdOnda inner join tbProduto tP with (Nolock) on tLPM.cdProduto = tP.cdProduto left join tbLojaProdutoModulo_10 tLMP10 with (Nolock) on tLMP10.cdloja=tLPM.cdLoja and tLMP10.cdProduto=tLPM.cdProduto and tLMP10.cdOnda=tLPM.cdOnda where tUL.cdUsuario = %d order by tLPM.cdLoja, tLPM.cdOnda, tLPM.cdProduto" %int(cod_usuario))
rows = conn.fetchall()

rowarray_list = []
for row in rows:
t = (row[0], row[1], row[2], row[3], row[4])
rowarray_list.append(t)

j = json.dumps(rowarray_list) + "\n"
json_bytes = j.encode('utf-8')
content = zlib.compress(json_bytes, 5)
response = make_response(content)
response.headers['Content-length'] = len(content)
response.headers['Content-Encoding'] = 'gzip'
return response[/CODE]


The server can answer a "byte" data, but I don´t know to transform this byte in string. In B4A I got this error in the line

ReceivedData = Compressor.DecompressBytes(Job.GetString.GetBytes("UTF8"), "zlib")


[CODE lang="b4x" title="error"]
Error occurred on line: 237 (HttpJob)
java.util.zip.ZipException: incorrect header check
at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:183)
at java.io.FilterInputStream.read(FilterInputStream.java:107)
at anywheresoftware.b4a.objects.streams.File.Copy2(File.java:361)
at anywheresoftware.b4a.randomaccessfile.CompressedStreams.DecompressBytes(CompressedStreams.java:152)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:348)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
at anywheresoftware.b4a.BA$2.run(BA.java:387)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:241)
at android.app.ActivityThread.main(ActivityThread.java:7604)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:941)
[/CODE]


Probably I doing something wrong handling the server response, but I dont know how can I transform the reponse from bytes to string.
 
Last edited:
Tks a lot Erel, with your help I was able make the correct code using Job.GetInputStream, now it is working fine!

About JobDone, I´m not sure what is the problem with JobDone. I did call "download" and then I´m using the jobdone to ctach the result, like:

[CODE lang="b4x" title="HttpJob - Download"]Dim Http_LojaProdutoModulo As HttpJob
Http_LojaProdutoModulo.Initialize("LojaProdutoModulo", Me)
Http_LojaProdutoModulo.Download(host & "/lojaprodutomodulo_v3/" & idUsuario)
Http_LojaProdutoModulo.username = GlobalModule.username
Http_LojaProdutoModulo.password = GlobalModule.password
Http_LojaProdutoModulo.GetRequest.Timeout = 480000

Sub JobDone(Job As HttpJob)
If Job.Success Then
if Job.JobName = "LojaProdutoModulo" Then
'Insert results in the table
...
end if
end if

End sub[/CODE]

Apparently everything is working ok, but I don´t know if is totally correct the code. Should I change something in the code?
 
Upvote 0
I´m not sure what is the problem with JobDone
 
Upvote 0
Back
Top