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":

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


To reduce the traffic I converted the code to :

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

In the server side I have an API developed in Python :
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'}

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

I wrote this code :

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


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

In the server side for GET I have:

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


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")


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)


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:

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

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

josejad

Expert
Licensed User
Longtime User
I´m not sure what is the problem with JobDone
 
Upvote 0
Top