Upload images/videos to server using Servlet and Android Studio - android

I am trying to upload Images/Videos which are taken through Device camera to server at a specific folder which can be retrieved later in a dashboard.
I have gone through numerous posts and tutorials and all of them are basically using a JSP to choose a file and then upload it or they are using PHP as a server side code to upload it.
I have my whole backend developed in JAVA SERVLET and I need to include this upload/download functionality.
Basically what I want is to make a POST request using Retrofit or Volley to make a server request and file should be uploaded. (It's like when we use POSTMAN to fire an api call and choose an image as binary file to upload).
Links which I have tried :
Link 1 , Link 2, Link 3 and a lot more. All of them include JSP or something to choose file, I need to pass the media(image/video) as a parameter to the POST request.

So I finally managed to achieve it. I had to post an image/video as well as a JSON corresponding to that media.
My solution is as follows :
#WebServlet("/ImageUploadServlet")
#MultipartConfig
public class ImageUploadServlet extends HttpServlet {
..............
.............
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
long req_received_time=System.currentTimeMillis();
String to_be_saved_location="";
System.out.println("JSON received is : "+request.getParameter("input_json"));
JSONObject req = null;
try {
req = readPOST(request.getParameter("input_json"));
to_be_saved_location = "your_location";
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
SqlUtil.incident_reporting(xxx);// function to enter data in sql
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
InputStream in = request.getPart("image").getInputStream();//change it to video(it's just a parameter name)
OutputStream out = new FileOutputStream("/Users/driftking9987/Documents/Stuffs/"+to_be_saved_location+".jpg");//Add .mp4 for video
//OutputStream out = new FileOutputStream("/var/www/html/media/abc.mp4");
copy(in, out); //The function is below
out.flush();
out.close();
}
public static long copy(InputStream input, OutputStream output) throws IOException {
byte[] buffer = new byte[4096];
long count = 0L;
int n = 0;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
count += n;
}
return count;
}
While saving it on the server, I gave the tomcat user the permission to write in the media folder.
Below is the POSTMAN screenshot.

Related

new BlobStoreManager read write on Android 11

I previously used external storage to store specific data that I would like to share between my applications (without having any contentprovider "host")
File folder = new File(Environment.getExternalStorageDirectory(), "FOLDER_NAME");
File file = new File(folder, "FILE_NAME.dat");
FileOutputStream outputStream = new FileOutputStream(file);
That is why I am trying to use BlobStoreManager, as suggested in google's recommendation for targeting 30 (https://developer.android.com/training/data-storage/shared/datasets)
The read & write are based on a BlobHandle with 4 parameters, one being MessageDigest based on a "content". BlobHandle must use the same 4 parameters, or read will fail (SecurityException).
I managed to write data, and to read it, but it makes no sense:
It seems that in order to write, I need to use the data I want to write to generate the BlobHandle.
Then, to read, as BlobHandle must use the same 4 parameters, I also need the data I wrote to be able to read.
Totally illogic, as I wanted to read this data, I don't have it!
I must miss something or just do not understand how it work. If someone can help :)
Here are my sample:
If I set the following:
createBlobHandle: content = "mydata"
write: data = "mydata"
Then write will success, and read will success too. But it I can not know the value before reading it in a normal usecase :(
If I set the following (which would be logic, at least to me):
createBlobHandle: content = "somekey"
write: data = "mydata"
Then write will fail :(
#RequiresApi(api = Build.VERSION_CODES.R)
private BlobHandle createBlobHandle() {
//Transfer object
String content = "SomeContentToWrite";
String label = "label123";
String tag = "test";
//Sha256 summary of the transmission object
try {
byte[] contentByte = content.getBytes("utf-8");
MessageDigest md = MessageDigest.getInstance("sha256");
byte[] contentHash = md.digest(contentByte);
return BlobHandle.createWithSha256(contentHash, label,0, tag);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
private void write() {
String data = "SomeContentToWrite";
#SuppressLint("WrongConstant") final BlobStoreManager blobStoreManager = ((BlobStoreManager) applicationContext.getSystemService(Context.BLOB_STORE_SERVICE));
//Generate the session of this operation
try {
BlobHandle blobHandle = createBlobHandle();
if (blobHandle == null)
return;
long sessionId = blobStoreManager.createSession(blobHandle);
try (BlobStoreManager.Session session = blobStoreManager.openSession(sessionId)) {
try (OutputStream pfd = new ParcelFileDescriptor.AutoCloseOutputStream(session.openWrite(0, data.getBytes().length))) {
//The abstract of the written object must be consistent with the above, otherwise it will report SecurityException
Log.d(TAG, "writeFile: >>>>>>>>>>text = " + data);
pfd.write(data.getBytes());
pfd.flush();
//Allow public access
session.allowPublicAccess();
session.commit(applicationContext.getMainExecutor(), new Consumer<Integer>() {
#Override
public void accept(Integer integer) {
//0 success 1 failure
Log.d(TAG, "accept: >>>>>>>>" + integer);
}
});
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
private String read() {
String data = "";
#SuppressLint("WrongConstant") final BlobStoreManager blobStoreManager = ((BlobStoreManager) applicationContext.getSystemService(Context.BLOB_STORE_SERVICE));
BlobHandle blobHandle = createBlobHandle();
if (blobHandle != null) {
try (InputStream pfd = new ParcelFileDescriptor.AutoCloseInputStream(blobStoreManager.openBlob(createBlobHandle()))) {
//Read data
byte[] buffer = new byte[pfd.available()];
pfd.read(buffer);
String text = new String(buffer, Charset.forName("UTF-8"));
Log.d(TAG, "readFile: >>>>>>>>>>>>>>>>>>>>" + text);
} catch (IOException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
}
return data;
}
According to the official training documentation linked in the question, the missing piece of information, at the time of the question having been asked, is that the four pieces of data contained in the BlobHandler need to be uploaded to a server owned by the client application then subsequently downloaded by which ever other application wants to access the blob via the BlobStorageManager.
So it would seem that on-device blob discovery is not supported. There could also be a solution possible using a Content Provider which could offer up the four required pieces of data, thus circumventing the need for the server infrastructure.

Android OS - How to track Azure upload progress

I've been working with Azure on the Android OS and I managed to upload my video file (.mp4) to a Container I had already prepared for it.
I did this by getting a Shared Access Signature (SAS) first, which provided me with:
a temporary key
the name of the container to where I want to send the files
the server URI
Then, I started an AsyncTask to send the file to the container using the "upload".
I checked the container, and the file gets uploaded perfectly, no problems on that end.
My question is regarding the progress of the upload. Is it possible to track it? I would like to have an upload bar to give a better UX.
P.S - I'm using the Azure Mobile SDK
Here's my code:
private void uploadFile(String filename){
mFileTransferInProgress = true;
try {
Log.d("Funky Stuff", "Blob Azure Config");
final String gFilename = filename;
File file = new File(filename); // File path
String blobUri = blobServerURL + sharedAccessSignature.replaceAll("\"", "");
StorageUri storage = new StorageUri(URI.create(blobUri));
CloudBlobClient blobCLient = new CloudBlobClient(storage);
//Container name here
CloudBlobContainer container = blobCLient.getContainerReference(blobContainer);
blob = container.getBlockBlobReference(file.getName());
//fileToByteConverter is a method to convert files to a byte[]
byte[] buffer = fileToByteConverter(file);
ByteArrayInputStream inputStream = new ByteArrayInputStream(buffer);
if (blob != null) {
new UploadFileToAzure().execute(inputStream);
}
} catch (StorageException e) {
Log.d("Funky Stuff", "StorageException: " + e.toString());
e.printStackTrace();
} catch (IOException e) {
Log.d("Funky Stuff", "IOException: " + e.toString());
e.printStackTrace();
} catch (Exception e) {
Log.d("Funky Stuff", "Exception: " + e.toString());
e.printStackTrace();
}
mFileTransferInProgress = false;
//TODO: Missing ProgressChanged method from AWS
}
private class UploadFileToAzure extends
AsyncTask <ByteArrayInputStream, Void, Void>
{
#Override
protected Void doInBackground(ByteArrayInputStream... params) {
try {
Log.d("Funky Stuff", "Entered UploadFileToAzure Async" + uploadEvent.mFilename);
//Method to upload, takes an InputStream and a size
blob.upload(params[0], params[0].available());
params[0].close();
} catch (StorageException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
Thanks!
You can split your file and send its part using Block, there is a good example of your case in this link but it used C# so you should find the corresponding function in the android library reference.
Basically instead of sending you file as one big file, you split it to multiple files (bytes) and send it to azure so you can track the progress on how many bytes that already sent to azure

Threads, atomic boolean, synchronized design considerations for a method that has to wait for a result

My code is starting to get a bit hard to debug which leads me to believe that my design choices are not ideal. I am a novice Android programming and would love some help with streamlining the design for optimum operation.
Intro
I am writing an application that uses rfcomm interface to transfer data between a client and server device. The client needs to request certain things from the server using a specific key, then it needs to wait until the server sends the result back.
Current Design
A button press triggers a request for information from the server.
A new thread is started which performs the request.
A key which is a unique integer is converted to a byte array and sent to the server.
Thread has a while loop that is waiting for a specific boolean to flip from false to true indicating a response back from the server.
Information is received on the server side. Server uses key to identify what to do next.
server starts a thread to run some query and gets a jsonString back as a result.
Server sends jsonstring converted to byte array prepended with the same identifying key back to the client.
Client reads message, and sends the byte array to a handling method based on the identifying key.
Handling method stores jsonString to a class variable and then flips the boolean to let the other thread know that the value it was waiting on has been set.
Json string is converted to object on the client side. Something is done with that object.
This code currently correctly sends info to the server, server correctly does search and gets a valid json string result. However, the issue occurs when the server writes its results make to the client. I am getting 20 messages instead of one and none match the search key...
My questions
Am I doing things in an efficient way design wise?
Can I benefit from using synchronized keyword or and Atomic Boolean to make my code more thread safe? How would I go about implementing it?
Is there a max length for converting strings to byte array? Maybe the code is trying to break up the sending for me and that's why I'm getting 20 different results?
Relevant code
public class ClientSpokesmanClass {
private final int searchKey = 2222222; //set the key to some int.
private boolean pendingSearchResults = false;
List<Place> places = new ArrayList<Place>();
private final Handler handler = new Handler(){
#Override
public void handleMessage(Message msg){
switch(msg.what) {
...
case MESSAGE_READ:
//Message received from server
readAndDistribute(msg.arg1, msg.obj);
break;
...
}
}
};
public List<Place> getPlacesFromServer(String query){
//ask server for search results
requestSearchFromServer(query);
//just wait for them...
while (pendingSearchResults){
//just waiting
}
return places;
}
private void requestSearchFromConnectedDevice(String query) {
if (mBluetoothState == STATE_CONNECTED){
byte[] bites = new byte[4];
bites = ByteBuffer.wrap(bites).putInt(searchKey).array();
byte[] stringBytes = null;
try {
stringBytes = query.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
Log.e(TAG, "unsupported encoding", e);
}
int keyLength = bites.length;
int stringLength = stringBytes.length;
byte[] combined = new byte[keyLength+stringLength];
System.arraycopy(bites, 0, combined, 0, keyLength);
System.arraycopy(stringBytes, 0, combined, keyLength, stringLength);
mBluetoothService.write(combined);
}
pendingSearchResults = true;
}
private void receiveSearchResults(byte[] bites){
String jsonString = "";
PlacesJSONParser parser = new PlacesJSONParser();
try {
jsonString = new String(bites, "UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
Log.e(TAG, "unsupported encoding", e);
}
if (D) Log.d(TAG, "Json string we got is "+jsonString);
try {
places = parser.parse(new JSONObject(jsonString));
} catch (JSONException e) {
// TODO Auto-generated catch block
Log.e(TAG, "JSON exception", e);
}
pendingSearchResults = false;
}
/**
* Reads come here first. Then, based on the key prepended to them,
* they then go to other methods for further work.
* #param bytes
* #param buffer
*/
private synchronized void readAndDistribute(int bytes, Object buffer){
byte[] buff = (byte[]) buffer;
int key = ByteBuffer.wrap(Arrays.copyOfRange(buff, 0, 4)).getInt();
if (key == searchKey){
receiveSearchResults(Arrays.copyOfRange(buff, 4, bytes));
}else{
//do something else
}
}
}
.
public class ClientUI extends Activity {
...
onQueryTextSubmit(String query){
final String queryFinal = query;
Thread thread = new Thread(){
public void run() {
places = ClientSpokesmanClass.getPlacesFromServer(query);
doSomethingWithPlaces();
}
};
thread.start();
}
}
.
public class ServerReceive {
private searchKey = 2222222;
...
//code that handles messages, reads key, and then runs doSearchAndWriteResults()
...
private synchronized void doSearchAndWriteResults(byte[] bites){
if (D) Log.d(TAG, "+++writeSearchResults");
//Initialize query and placesString
String query = null;
String placesString;
//Convert byte array to the query string
try {
query = new String(bites, "UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
Log.e(TAG, "unsupported encoding",e);
}
//if the string was converted successfully...
if (query != null){
//Run the places query and set the json string to placesString
if (D) Log.d(TAG, "query is "+query);
PlacesProvider placeProvider = new PlacesProvider();
placesString = placeProvider.getPlacesString(query);
}
//initialize a bite array
byte[] stringBytes = null;
try {
//convert jsonString to byte array
stringBytes = placesString.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
Log.e(TAG, "unsupported encoding",e);
}
//Put the search key to a byte array. I am using this key on the client side
//to confirm that we are reading searchResults and not some other type of write.
byte[] bite = new byte[4];
bite = ByteBuffer.wrap(bite).putInt(searchKey).array();
//Get the lengths of the two byte arrays
int keyLength = bite.length;
int stringLength = stringBytes.length;
//combine the byte arrays for sending
byte[] combined = new byte[keyLength+stringLength];
System.arraycopy(bite, 0, combined, 0, keyLength);
System.arraycopy(stringBytes, 0, combined, keyLength, stringLength);
if (D) Log.d(TAG, "Actually writing things here...");
//send the byte arrrays over rfcomm
mBluetoothService.write(combined);
}
}
Take a look at https://github.com/gettyimages/connect_sdk_java. Specifically, at the test application. It performs a search using an AsyncTask and the private class notifies the UI via onPostExecute. Hopefully, this will get you further along.

InputStream receives incomplete data

I am using a Socket connection to connect to a database. When I pull data from the database via InputStream, sometimes it returns full data but most of the time it returns incomplete data (5%/95%). There's an EOF that the database sends but it only gets that far about 5% of the time.
#Override
protected Socket doInBackground(Void... params) {
Socket client = null;
try {
client = new Socket(SocketHelper.IP_ADDRESS, SocketHelper.PORT);
//output message
OutputStream output = client.getOutputStream();
output.write(message.getBytes("UTF-8"));
//parse response
//blocks here more of the time
SocketHelper.parseData(client.getInputStream());
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return client;
}
In my parse method, I look for the EOF and would normally close the InputStream and close the Socket there. I can't find any consistencies for the times it does reach the EOF. Right now the length of the data is static, I haven't adjusted it while I"m trying to figure this out. But the length of the data will be dynamic.
To read data from a Socket, in your parseData method you need to loop, calling read(byte[] b, int off, int len) until all the bytes you expect have arrived.
The read method returns the number of bytes actually read; keep looping until you've got everything. Remember to adjust the offset argument, so that you build up the full message.

Data being lost between Android device and python server using TCP

I'm somewhat new to network programming and am having some trouble. I am creating a JSON object on an Android device, connecting to a python server via TCP, and sending the JSON string. The connection gets accepted, but I keep losing the end of the string, so
json.loads(json_string)
is failing.
Here is the relevant Android code:
private class Worker implements Runnable
{
#Override
public void run()
{
//create the network socket
try
{
socket = new Socket(address, 4242);
Log.i(TAG, "timeout: " + socket.getSoTimeout());
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
packets = new ArrayList<JSONObject>();
for (jobs.moveToFirst(); jobs.isAfterLast() == false; jobs.moveToNext())
{
String jobName = jobs.getString(jobs.getColumnIndex(JobMetaData.JobTableMetaData.JOB));
Uri.Builder updated = new Uri.Builder();
updated.scheme("content");
updated.authority(JobMetaData.AUTHORITY);
updated.appendPath(jobName);
updated.appendPath("member");
updated.appendPath(JobMetaData.MemberTableMetaData.CHANGED);
updated.appendPath("true");
Cursor changed = getContentResolver().query(updated.build(), null, null, null, null);
Log.d(TAG, "number of members " + changed.getCount());
//create a JSON object out of the editable properties
for (changed.moveToFirst(); changed.isAfterLast() == false; changed.moveToNext())
{
JSONObject json = new JSONObject();
for (String att : changed.getColumnNames())
{
if (ListMetaData.validAtts.contains(att))
{
try
{
json.put(att, changed.getString(changed.getColumnIndex(att)));
}
catch (JSONException e)
{
// TODO Auto-generated catch block
Log.d(TAG, "JSON exception in DatagramService");
e.printStackTrace();
}
}
}
//include the GUID and job name
//for identification
try
{
json.put(JobMetaData.MemberTableMetaData.GUID,
changed.getString(changed.getColumnIndex(JobMetaData.MemberTableMetaData.GUID)));
json.put(JobMetaData.JobTableMetaData.JOB, jobName);
}
catch (JSONException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
packets.add(json);
}
changed.close();
}
Log.d(TAG, "entering send loop");
try
{
out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
out.flush();
}
catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
for (JSONObject packet : packets)
{
Log.d(TAG, "supposedly sending");
try
{
//now write the data
Log.d(TAG, "packet string: " + packet.toString());
out.write(packet.toString());
out.flush();
}
catch (IOException e)
{
}
}
try
{
out.write("Done");
out.flush();
out.close();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
stopSelf();
}
And the test server that I am using (written in python):
#!/usr/bin/env python
import SocketServer
import json
class MemberUpdateHandler(SocketServer.BaseRequestHandler):
def setup(self):
print self.client_address, "connected"
def handle(self):
while True:
self.JSONString = self.request.recv(8192).strip()
if self.JSONString == "Done":
return
self.handleJSON()
self.update()
def handleJSON(self):
JSONMember = json.loads(self.JSONString)
print "GUID:", JSONMember['ManufacturingGUID']
print "Weight:", JSONMember['Weight']
def update(self):
print "do something here"
if __name__ == "__main__":
ADDRESS = ''
PORT = 4242
HOST = (ADDRESS, PORT)
s = SocketServer.ThreadingTCPServer(HOST, MemberUpdateHandler)
s.serve_forever()
Here is the string that is being sent (it is long):
{"DetailCheckedBy":"","SketchRight":"","DetailLength":"142.75","DetailedDate":"**NOT SET**","EngineerVerifiedBothConns":"False","HoldStatus":"Not held","RevisionLevel":"No Revision","MemberNumber":"28","RequestVerifySectionSize":"False","TieForcesRight":"False","InputBy":"","IFCFinishDate_4":"**NOT SET**","IFCFinishDate_5":"**NOT SET**","Weight":"438.408","IFCTaskUID_1":"","IFCFinishDate_1":"**NOT SET**","ErectorOrder":"","IFCFinishDate_2":"**NOT SET**","IFCFinishDate_3":"**NOT SET**","IFCTaskUID_4":"","IFCTaskUID_5":"","IFCTaskUID_2":"","SketchLeft":"","IFCTaskUID_3":"","ErectorSequences":"","ReasonRejected":"","MemberCategory":"","EngineerVerifiedLeftConn":"False","BarcodeId":"","ManufacturingGUID":"42bbf9cc-52da-4712-a5fc-e37c5a544c14","aess":"False","FabricationComplete":"**NOT SET**","UserComment2":"","UserComment3":"","LoadNumber":"","UserComment1":"","ErectionBolted":"**NOT SET**","RequestVerifyLength":"False","RequestVerifyGrade":"False","Painted":"False","HeatCertNumber":"","Route1Description":"","IsExisting":"No","ReceivedFromApproval":"**NOT SET**","BackCheckedBy":"","BatchNumber":"","CostCodeReference":"","PONumber":"","Piecemark":"B_25","ReleasedForFabrication":"**NOT SET**","MemberDescription":"BEAM","EngineerVerifiedMemberReady":"False","IFCTaskName_2":"","IFCTaskName_1":"","IFCTaskName_4":"","RequestVerifyMemberPosition":"False","IFCTaskName_3":"","Erected":"**NOT SET**","RevisionCheckedBy_3":"","IFCTaskName_5":"","RevisionCheckedBy_2":"","RevisionCheckedBy_1":"","EngineerVerifiedLeftComments":"","RequestVerifyLeftConnMaterial":"False","RequestEngineerVerify":"False","RevisionCheckedDate_3":"**NOT SET**","RevisionCheckedDate_2":"**NOT SET**","RevisionCheckedDate_1":"**NOT SET**","EngineerVerifiedLength":"False","BackCheckedDate":"**NOT SET**","SubmittedForApproval":"**NOT SET**","EngineerVerifiedSpecial":"False","CostCodeDescription":"","IFCStartDate_5":"**NOT SET**","TieForcesLeft":"False","Fireproofed":"False","ErectorAvailable":"False","RequestVerifyRightConnMaterial":"False","DetailCheckedDate":"**NOT SET**","ErectorNonSteelSupported":"False","BeamPent":"False","StockStatus":"","Sequence":"1","RequestVerifyLeftLoad":"False","DetailFinalCheckDate":"**NOT SET**","ErectorMemberPlaced":"**NOT SET**","InstanceStatus":"","EngineerVerifiedRightConn":"False","DateReceived":"**NOT SET**","MemberType":"Beam","ModelCheckDate":"**NOT SET**","ReasonForHold":"","EngineerVerifiedRightComments":"","ReceivedOnJobSite":"**NOT SET**","RequestVerifyRightLoad":"False","CostCodePrice":"0.0","NestStatus":"","DateDue":"**NOT SET**","ShopSequence":"","EngineerVerifiedSectionSize":"False","ActualLength":"144","InputDate":"**NOT SET**","ErectorCity":"Unknown","EngineerVerifiedSpecial_comments":"","Route4Description":"","EngineerVerifiedGrade":"False","RightLocation":"0.0xx144.0xx156.0xx","IFCFinishTime_2":"","IFCFinishTime_1":"","IFCFinishTime_4":"","Route3Description":"","IFCFinishTime_3":"","LoadStatus":"","ErectorLongitude":"","DateModelCompleted":"61299957600000","Grade":"##SEKRIT KODE!!##","IFCFinishTime_5":"","Route2Description":"","RequestVerifyCamber":"False","ProjectedFabricationComplete":"**NOT SET**","DetailedBy":"","DetailFinalCheckBy":"","Description":"W8x35","ProjectedShippedDate":"**NOT SET**","NestName":"","IFCStartDate_2":"**NOT SET**","IFCStartTime_1":"","IFCStartDate_1":"**NOT SET**","IFCStartDate_4":"**NOT SET**","IFCStartDate_3":"**NOT SET**","IFCStartTime_5":"","IFCStartTime_4":"","IFCStartTime_3":"","DateHeld":"**NOT SET**","IFCStartTime_2":"","LeftLocation":"0.0xx0.0xx156.0xx","Job":"Mobile_x_x_x_x_Demo_x_x_x_x_IN_x_x_x_x_2011","SpecialCutWeld":"False","RejectedBy":"","ErectionWelded":"**NOT SET**","RequestVerifyRightConnConfig":"False","Vendor":"","PackageNumber":"","RejectedByErector":"**NOT SET**","ModelCheckedBy":"","ApprovalStatus":"Not reviewed","RequestVerifyLeftConnConfig":"False","ErectorLatitude":"","LotName":"","ActualShipDate":"**NOT SET**","NestId":""}
This is the error I get from the python server:
ValueError: Unterminated string starting at: line 1 column 1435 (char 1435)
which means that the string has been truncated to:
{"DetailCheckedBy":"","SketchRight":"","DetailLength":"142.75","DetailedDate":"**NOT SET**","EngineerVerifiedBothConns":"False","HoldStatus":"Not held","RevisionLevel":"No Revision","MemberNumber":"28","RequestVerifySectionSize":"False","TieForcesRight":"False","InputBy":"","IFCFinishDate_4":"**NOT SET**","IFCFinishDate_5":"**NOT SET**","Weight":"438.408","IFCTaskUID_1":"","IFCFinishDate_1":"**NOT SET**","ErectorOrder":"","IFCFinishDate_2":"**NOT SET**","IFCFinishDate_3":"**NOT SET**","IFCTaskUID_4":"","IFCTaskUID_5":"","IFCTaskUID_2":"","SketchLeft":"","IFCTaskUID_3":"","ErectorSequences":"","ReasonRejected":"","MemberCategory":"","EngineerVerifiedLeftConn":"False","BarcodeId":"","ManufacturingGUID":"42bbf9cc-52da-4712-a5fc-e37c5a544c14","aess":"False","FabricationComplete":"**NOT SET**","UserComment2":"","UserComment3":"","LoadNumber":"","UserComment1":"","ErectionBolted":"**NOT SET**","RequestVerifyLength":"False","RequestVerifyGrade":"False","Painted":"False","HeatCertNumber":"","Route1Description":"","IsExisting":"No","ReceivedFromApproval":"**NOT SET**","BackCheckedBy":"","BatchNumber":"","CostCodeReference":"","PONumber":"","Piecemark":"B_25","ReleasedForFabrication":"**NOT SET**","MemberDescription":"BEAM","EngineerVerifiedMemberReady":"False","IFCTaskName_2":"","IFCTaskName_1":"","IFCTaskName_4":"","RequestVerifyMemberPosition":"False","IFCTaskName_3":"","Erected":"**NOT SET**","RevisionCheckedBy_3":"","IFCTaskName_
Any help would be greatly appreciated. Thanks in advance.
UPDATE:
I have updated the code to reflect my tinkering. The string received by the server is now
{"DetailCheckedBy":"","SketchRight":"","DetailLength":"142.75","DetailedDate":"**NOT SET**","EngineerVerifiedBothConns":"False","HoldStatus":"Not held","RevisionLevel":"No Revision","MemberNumber":"28","RequestVerifySectionSize":"False","TieForcesRight":"False","InputBy":"","IFCFinishDate_4":"**NOT SET**","IFCFinishDate_5":"**NOT SET**","Weight":"438.408","IFCTaskUID_1":"","IFCFinishDate_1":"**NOT SET**","ErectorOrder":"","IFCFinishDate_2":"**NOT SET**","IFCFinishDate_3":"**NOT SET**","IFCTaskUID_4":"","IFCTaskUID_5":"","IFCTaskUID_2":"","SketchLeft":"","IFCTaskUID_3":"","ErectorSequences":"","ReasonRejected":"","MemberCategory":"","EngineerVerifiedLeftConn":"False","BarcodeId":"","ManufacturingGUID":"42bbf9cc-52da-4712-a5fc-e37c5a544c14","aess":"False","FabricationComplete":"**NOT SET**","UserComment2":"","UserComment3":"","LoadNumber":"","UserComment1":"","ErectionBolted":"**NOT SET**","RequestVerifyLength":"False","RequestVerifyGrade":"False","Painted":"False","HeatCertNumber":"","Route1Description":"","IsExisting":"No","ReceivedFromApproval":"**NOT SET**","BackCheckedBy":"","BatchNumber":"","CostCodeReference":"","PONumber":"","Piecemark":"B_25","ReleasedForFabrication":"**NOT SET**","MemberDescription":"BEAM","EngineerVerifiedMemberReady":"False","IFCTaskName_2":"","IFCTaskName_1":"","IFCTaskName_4":"","RequestVerifyMemberPosition":"False","IFCTaskName_3":"","Erected":"**NOT SET**","RevisionCheckedBy_3":"","IFCTaskName_5":"","RevisionCheckedBy_2":"","RevisionCheckedBy_1":"","EngineerVerifiedLeftComments":"","RequestVerifyLeftConnMaterial":"False","RequestEngineerVerify":"False","RevisionCheckedDate_3":"**NOT SET**","RevisionCheckedDate_2":"**NOT SET**","RevisionCheckedDate_1":"**NOT SET**","EngineerVerifiedLength":"False","BackCheckedDate":"**NOT SET**","SubmittedForApproval":"**NOT SET**","EngineerVerifiedSpecial":"False","CostCodeDescription":"","IFCStartDate_5":"**NOT SET**","TieForcesLeft":"False","Fireproofed":"False","ErectorAvailable":"False","RequestVerifyRightConnMaterial":"False","DetailCheckedDate":"**NOT SET**","ErectorNonSteelSupported":"False","BeamPent":"False","StockStatus":"","Sequence":"1","RequestVerifyLeftLoad":"False","DetailFinalCheckDate":"**NOT SET**","ErectorMemberPlaced":"**NOT SET**","InstanceStatus":"","EngineerVerifiedRightConn":"False","DateReceived":"**NOT SET**","MemberType":"Beam","ModelCheckDate":"**NOT SET**","ReasonForHold":"","EngineerVerifiedRightComments":"","ReceivedOnJobSite":"**NOT SET**","RequestVerifyRightLoad":"False","CostCodePrice":"0.0","NestStatus":"","DateDue":"**NOT SET**","ShopSequence":"","EngineerVerifiedSectionSize":"False","ActualLength":"144","InputDate":"**NOT SET**","ErectorCity":"Unknown","EngineerVerifiedSpecial_comments":"","Route4Description":"","EngineerVerifiedGrade":"False","RightLocation":"0.0xx144.0xx156.0xx","IFCFinishTime_2":"","IFCFinishTime_1":"","IFCFinishTime_4":"","Route3Description":"","IFCFinishTime_3":"","LoadStatus":"","ErectorLongitude":"","DateModelCompleted":"61299957600000","Grade":"##SEKRIT KODE!!##","IFCFinishTime_5":"","Route2Description":"","RequestVerifyCamber":"False","ProjectedFabricationComplete":"**NOT SET**","DetailedBy":"","DetailFinalCheckBy":"","Description":"W8x35","ProjectedShippedDate":"**NOT SET**","NestName":"","IFCStartDate_2":"**NOT SET**","IFCStartTime_1":"","IFCStartDate_1":"**NOT SET**","IFCStartDate_4":"**NOT SET**","IFCStartDate_3":"**NOT SET**","IFCStartTime_5":"","IFCStartTime_4":"","IFCStartTime_3":"","DateHeld":"**NOT SET**","IFCStartTime_2":"","LeftLocation":"0.0xx0.0xx156.0xx","Job":"Mobile_x_x_x_x_Demo_x_x_x_x_IN_x_x_x_x_2011","SpecialCutWeld":"False","RejectedBy":"","ErectionWelded":"**NOT SET**","RequestVerifyRightConnConfig":"False","Vendor":"","PackageNumber":"","RejectedByErector":"**NOT SET**","ModelCheckedBy":"","ApprovalStatus":"Not reviewed","RequestVerifyLeftConnConfig":"False","ErectorLatitude":"","LotName":"","ActualShipDate":"**NOT SET**","NestId":""}Done
followed by a mess of whitespace. Enough that gedit has trouble loading it all. One step forward two steps back. :/
sizeof(int) may not be the same on both devices. So you probably should hardcode something if you want to pass a binary integer.
If you evaluate int('\001\002\003\004\005\006\007\010'), you're unlikely to get what you want, and I believe that's close to what you're doing in your Python code. For one thing, the endianness of the two devices might be different, and for another, int() wants to evaluate ASCII or some other encoding, not raw endian-dependent integers.
On the python side, you might find this useful:
http://stromberg.dnsalias.org/~strombrg/bufsock.html
I'm not sure about the out.write() you're using, but at the lower level of send(), there's no guarantee that your entire buffer will be written in a single send() - it's allowed to stop early and just return how much was sent. Hopefully, java protects you from that detail the way bufsock does for python.
Why are you "assuming" that the string has been truncated? print it and see what it actually is.
Also, the string that is being sent (as you posted it) is not enclosed in {}, which means it is not proper JSON... I tried to copy/paste it in the interpreter, this raises a ValueError:
ValueError: Extra data: line 1 column 17 - line 1 column 3952 (char 17 - 3952)
I enclosed it in {} and it worked. You should try to see what the string you are receiving actually is on the python side, and then you can really see what's happening. I assume also, that since you are seeing the "Done" sent, then the content should have been sent completely.

Categories

Resources