B4J Question How to return a value?And strange questions

hzq200409

Member
Licensed User
B4X:
'Handler class
Sub Class_Globals


End Sub

Public Sub Initialize
   
End Sub

Sub Handle(req As ServletRequest, resp As ServletResponse)
    Try
        request1
        StartMessageLoop
        'Do the work according to the results of request 1
        If XXXXXX Then
           
            request2
            StartMessageLoop
       
        Else
            request3
            StartMessageLoop
        End If
    Catch
        resp.SendError(500, "error....")
    End Try
End Sub

Sub request1()
    Dim hp As HttpJob
    hp.Initialize("",Me)
    hp.Download("http://www.example.com")
    Wait For(hp)JobDone(hp As HttpJob)
    'I need to return the result here
   
    hp.Release
    StopMessageLoop
End Sub

Sub request2()
    Dim hp As HttpJob
    hp.Initialize("",Me)
    hp.Download("http://www.example.com")
    Wait For(hp)JobDone(hp As HttpJob)
    'I need to return the result here
   
    hp.Release
    StopMessageLoop
End Sub

Sub request3()
    Dim hp As HttpJob
    hp.Initialize("",Me)
    hp.PostString("http://www.example.com",data)
    hp.GetRequest.SetHeader("Content-Type","application/json")
    hp.GetRequest.SetHeader("Content-Length",data.Length)
    Wait For(hp)JobDone(hp As HttpJob)
    'I need to return the result here
   
    hp.Release
    StopMessageLoop
End Sub
Hello, friends.
The code structure looks something like the above. (1) I want to return a value, what can I do? (2)request3's request will have status code 204 and a blank response. The expectation is that the other server will log my submitted data and generate a transaction entry. But it did not. My POSTMAN works fine.This problem has been bothering me for two days, and I don't know what I did wrong.

1693140635317.png
1693154363654.png
 
Last edited:

hzq200409

Member
Licensed User
Try put the XXXXXX, request2 and request3 inside request1.
Thank you very much for your kind response.
In fact, I solved it by declaring a variable in "Class_Globals". But I wonder if there's a more reasonable way. Now the main problem is the second.
 
Upvote 0

EnriqueGonzalez

Well-Known Member
Licensed User
Longtime User
'I need to return the result here
either pass the resp object as a parameter or use a class global as you mentioned. that should be all

also, you could use a http sync routine like this one to simplify the process:
 
Upvote 0

hzq200409

Member
Licensed User
either pass the resp object as a parameter or use a class global as you mentioned. that should be all

also, you could use a http sync routine like this one to simplify the process:
Thank you very much for your reply. The content of this page seems to talk about synchronization methods. I have a lot of "sub requestX" here and they are very time consuming. Since it was a jserver program, I had to consider additional requests that came in while the previous work was in progress.
 
Upvote 0

EnriqueGonzalez

Well-Known Member
Licensed User
Longtime User
Since it was a jserver program, I had to consider additional requests that came in while the previous work was in progress.
Jserver user encapsulation. Each handler will run in a different thread and within that thread you can call sync calls without delaying other calls with their own handlers.
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
The code structure looks something like the above.
When using Resumable Subs with handlers, you need to structure your code as follows:
B4X:
'Handler class
Sub Class_Globals
    Private allSucceeded As Boolean
End Sub

Public Sub Initialize
   
End Sub

Sub Handle(req As ServletRequest, resp As ServletResponse)
    doRequests ' Let another sub handle all the wait for's
    StartMessageLoop ' Only one startmessageloop necessary
    If Not(allSucceeded) Then
        resp.SendError(500, "error....")
    End If
End Sub

Sub doRequests 
    'Process your wait for's here. As structured, they will occur sequentially
    Try
        Wait For (request1) complete (result1 As String)
        'Do the work according to the results of request 1
        If result1="XXXXXX" Then
           wait for (request2) complete (result2 As String)
               If result2 <> "" Then
                allSucceeded = True
            End If
        Else
            Dim data As String = "some data to send"
            wait for (request3(data)) complete (result3 As String)
            If result3 = "" Then
                allSucceeded = True
            End If
        End If
    Catch
        Log($"Encountered error processing doRequests: ${LastException}"$)
    End Try
    StopMessageLoop ' as structured, only one call to stopmessageloop required
End Sub

'For request1, the returned string will trigger different outcomes
Sub request1()As ResumableSub
    Dim result As String
    Dim hp As HttpJob
    hp.Initialize("",Me)
    hp.Download("http://www.example.com")
    Wait For(hp)JobDone(hp As HttpJob)
    'I need to return the result here
    If hp.Success Then
        result = hp.GetString
    Else
        Log($"Encountered error in request1(): ${hp.ErrorMessage}"$)
    End If
    hp.Release
    Return result
End Sub

'For request2, a return of a blank string = failure
Sub request2() As ResumableSub
    Dim result As String
    Dim hp As HttpJob
    hp.Initialize("",Me)
    hp.Download("http://www.example.com")
    Wait For(hp)JobDone(hp As HttpJob)
    'I need to return the result here
       If hp.Success Then
        result = hp.GetString
    Else
        Log($"Encountered error in request2(): ${hp.ErrorMessage}"$)
    End If
    hp.Release
    Return result
End Sub

'For request3, a return of a blank string = success
'Note the usage of SetContentType
Sub request3(data As String) As ResumableSub
    Dim result As String
    Dim hp As HttpJob
    hp.Initialize("",Me)
    hp.PostString("http://www.example.com",data)
    'hp.GetRequest.SetHeader("Content-Type","application/json")
    hp.GetRequest.SetContentType("application/json") ' You're supposed to use the method, not SetHeader, for content type
    hp.GetRequest.SetHeader("Content-Length",data.Length)
    Wait For(hp)JobDone(hp As HttpJob)
    'I need to return the result here
    If Not(hp.Success) Then
        result = $"Encountered error in request3(): ${hp.ErrorMessage}"$
        Log(result)
    End If
    hp.Release
    Return result
End Sub
Note: You need to modify the code according to your needs, this is just a rewrite of the example of the structure code you posted above.
Links to study:
 
Upvote 0
Top