This is an old example. Better use B4XSerializator to serialize objects.
One of the nice things about using B4J server as the backend of B4A applications is that you can send and receive objects such as custom types and collections of custom types instead of working with bytes or strings.
In this example we have two custom types:
	
	
	
	
	
	
	
		
			
			
			
			
			
		
	
	
	
		
	
	
		
	
These types are declared both in the server and the client applications.
The client will send a list of Orders and the server will return an OrderResult object. The serialization of the objects is done with RandomAccessFile.WriteObject / ReadObject. It supports all primitive types, custom types, arrays and collections. Note that Bitmaps are not supported.
Client Code
	
	
	
	
	
	
	
		
			
			
			
			
			
		
	
	
	
		
	
	
		
	
Server code
Main module:
	
	
	
	
	
	
	
		
			
			
			
			
			
		
	
	
	
		
	
	
		
	
OrderHander class:
	
	
	
	
	
	
	
		
			
			
			
			
			
		
	
	
	
		
	
	
		
	
Note that the server writes the object into a temporary buffer. The buffer must be large enough in order to hold the serialized data. You can check raf.CurrentPosition after writing the object to get an estimation of the required size. Another option is to use a temporary file as done in the client. However for this to work properly you need to set the handler to run in single threaded mode.
Note that you will see the following message in the logs:
You can ignore it. It happens on the first time that a type with a different package is discovered.
			
			One of the nice things about using B4J server as the backend of B4A applications is that you can send and receive objects such as custom types and collections of custom types instead of working with bytes or strings.
In this example we have two custom types:
			
				B4X:
			
		
		
		Type Order(ProductKey As String, Amount As Int, Comment As String)
Type OrderResult(NumberOfOrders As Int, Success As Boolean)These types are declared both in the server and the client applications.
The client will send a list of Orders and the server will return an OrderResult object. The serialization of the objects is done with RandomAccessFile.WriteObject / ReadObject. It supports all primitive types, custom types, arrays and collections. Note that Bitmaps are not supported.
Client Code
			
				B4X:
			
		
		
		Sub Process_Globals
   Type Order(ProductKey As String, Amount As Int, Comment As String)
   Type OrderResult(NumberOfOrders As Int, Success As Boolean)
 
   Private raf As RandomAccessFile
   'server link
   Private link As String = "http://192.168.0.100:51042/order"
End Sub
Sub Activity_Create(FirstTime As Boolean)
   If FirstTime Then
     raf.Initialize(File.DirInternal, "temp", False)
   End If
 
   Dim Orders As List
   Orders.Initialize
   For i = 1 To 20
     Dim o As Order
     o.Initialize
     o.ProductKey = "Item #" & i
     o.Amount = 7
     o.Comment = "abcdef"
     Orders.Add(o)
   Next
   SendObject(Orders)
End Sub
Sub SendObject (Obj As Object)
   raf.WriteObject(Obj, True, 0)
   Dim size As Int = raf.CurrentPosition
   Dim data(size) As Byte
   raf.CurrentPosition = 0
   Do While raf.CurrentPosition < size
     raf.ReadBytes(data, raf.CurrentPosition, size - raf.CurrentPosition, _
       raf.CurrentPosition)
   Loop
 
   Dim j As HttpJob
   j.Initialize("send object", Me)
   j.PostBytes(link, data)
End Sub
Sub ReadObject (In As InputStream) As Object
   Dim out As OutputStream
   out.InitializeToBytesArray(0)
   File.Copy2(In, out)
   Dim raf2 As RandomAccessFile
   raf2.Initialize3(out.ToBytesArray, False)
   Dim res As Object = raf2.ReadObject(0)
   raf2.Close
   Return res
End Sub
Sub JobDone(j As HttpJob)
   If j.Success Then
     Dim result As OrderResult = ReadObject(j.GetInputStream)
     Log(result)
   Else
     Log("Error: " & j.ErrorMessage)
   End If
   j.Release
End SubServer code
Main module:
			
				B4X:
			
		
		
		Sub Process_Globals
   Type Order(ProductKey As String, Amount As Int, Comment As String)
   Type OrderResult(NumberOfOrders As Int, Success As Boolean)
   Private srvr As Server
End Sub
Sub AppStart (Args() As String)
   srvr.Initialize("")
   srvr.Port = 51042
   srvr.AddHandler("/order", "OrderHandler", False)
   srvr.Start
   StartMessageLoop
End SubOrderHander class:
			
				B4X:
			
		
		
		Sub Class_Globals
   'The buffer must be large enough to hold the result object.
   Private bufferSize As Int = 1000
End Sub
Public Sub Initialize
End Sub
Sub Handle(req As ServletRequest, resp As ServletResponse)
   Dim orders As List = ReadObject(req.InputStream)
   Dim result As OrderResult
   result.Initialize
   For Each o As Order In orders
     'work with the order
     Log(o.ProductKey & ", " & o.Amount & ", " & o.Comment)
     result.NumberOfOrders = result.NumberOfOrders + 1
   Next
   result.Success = True
   SendObject(result, resp.OutputStream)
End Sub
Sub ReadObject (In As InputStream) As Object
   Dim out As OutputStream
   out.InitializeToBytesArray(0)
   File.Copy2(In, out)
   Dim raf2 As RandomAccessFile
   raf2.Initialize3(out.ToBytesArray, False)
   Dim res As Object = raf2.ReadObject(0)
   raf2.Close
   Return res
End Sub
Sub SendObject (Obj As Object, Out As OutputStream)
   Dim raf As RandomAccessFile
   Dim buffer(bufferSize) As Byte
   raf.Initialize3(buffer, False)
   raf.WriteObject(Obj, True, 0)
   Out.WriteBytes(buffer, 0, raf.CurrentPosition)
End SubNote that the server writes the object into a temporary buffer. The buffer must be large enough in order to hold the serialized data. You can check raf.CurrentPosition after writing the object to get an estimation of the required size. Another option is to use a temporary file as done in the client. However for this to work properly you need to set the handler to run in single threaded mode.
Note that you will see the following message in the logs:
Class not found: b4a.example.main$_order, trying: b4j.example.main$_order
You can ignore it. It happens on the first time that a type with a different package is discovered.
			
				Last edited: 
			
		
	
							 
				 
 
		 
 
		 
 
		 
 
		