How to reduce the time for sending data to remote server? - java

E.g. there are 10MB data stored in my tablet. The data has a list structure. Each entry in the list is about 3500 Bytes.
Currently, I send one entry each time with the following codes:
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(ipport+ phpHandler);
HttpResponse response = null;
try {
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "utf-8"));
response = httpclient.execute(httppost);
} catch (UnsupportedEncodingException e) {
} catch (ClientProtocolException e) {
} catch (IOException e) {
}
But to send this 10MB data, it took a long time. Each sending of an entry takes about 1 second.
Any solution to improve the efficiency?

You can build a JSON string object which contains all the entities and then compress it with gzip or any other compression scheme.
The benefit of building a JSON object is you can transmit all the objects as one request, instead of sending it separately. This would eliminate the latency of establishing a new connection everytime.
// your data list = listData
JSONArray newArray = new JSONArray();
for (int i = 0, lsize = listData.size(); i < lsize; i++) {
try {
newArray.put(i, listData.get(i));
} catch (JSONException e) {
e.printStackTrace();
}
}
This code would build a JSONArray with all the elements in the listData (it should be a list of strings)
now you can easily convert the JSONArray to a string using
newArray.toString()
Now you can send this JSON string over the network, and you can easily deserialize a JSON object in any server side language.
As for Gzip compression, you might want to look at this link
Here is a question on SO about sending GZip compressed data over HTTP in android
GZip POST request with HTTPClient in Java

I am agreeing with the answer of #Ahmed. you better use jSON string object then compress using gzip libray.
for JSON there are lots of helpful tutorials. following link is really helpful
http://www.vogella.com/articles/AndroidJSON/article.html
here you can see the simple way to write json
public void writeJSON() {
JSONObject object = new JSONObject();
try {
object.put("name", "Jack Hack");
object.put("score", new Integer(200));
object.put("current", new Double(152.32));
object.put("nickname", "Hacker");
} catch (JSONException e) {
e.printStackTrace();
}
}
and to compress and decompress using gzip Here i am adding some sample codes from the answer https://stackoverflow.com/a/6718707/931982
public static byte[] compress(String string) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream(string.length());
GZIPOutputStream gos = new GZIPOutputStream(os);
gos.write(string.getBytes());
gos.close();
byte[] compressed = os.toByteArray();
os.close();
return compressed;
}
public static String decompress(byte[] compressed) throws IOException {
final int BUFFER_SIZE = 32;
ByteArrayInputStream is = new ByteArrayInputStream(compressed);
GZIPInputStream gis = new GZIPInputStream(is, BUFFER_SIZE);
StringBuilder string = new StringBuilder();
byte[] data = new byte[BUFFER_SIZE];
int bytesRead;
while ((bytesRead = gis.read(data)) != -1) {
string.append(new String(data, 0, bytesRead));
}
gis.close();
is.close();
return string.toString();
}

Related

Downloading file with SharePoint API: file damaged

I'm developing a Java library for basic operations on SharePoint using Graph API.
I make a call on this entry point using SOAP UI:
https://graph.microsoft.com/v1.0/drives/{drive-id}/items/{item-id}/content
And I obtain a raw response:
%PDF-1.6
%âãÏÓ
1751 0 obj
<</Filter/FlateDecode/First 98/Length 322/N 11/Type/ObjStm>>stream
hޜԽJ1†á[ÉL’ó“–m,md±ÁElTü)¼{3“wXYDØ©¾3!ç<)&I^kˆ!ymÁ¤gë¥ÍE ...
endstream
endobj
startxref
2993893
%%EOF
It look like i'm retrieving an input stream.
In the HttpRequest class I try to build a response object that returns the InputStream. My property fileInputStream is an InputStream:
SharePointDownloadResponseModel returnValue = new SharePointDownloadResponseModel();
InputStream inputStream = new ByteArrayInputStream(response.toString().getBytes(StandardCharsets.UTF_8));
returnValue.setFileInputStream(inputStream);
return returnValue;
Now in my manager class I try to save the input stream in the hard drive. I handle 2 cases. First case, I have a fileName a folder to store the file. My request object :
if(request.getDownloadFolder() != null && request.getFileName() !=null) {
InputStream initialStream = returnValue.getFileInputStream();
FileOutputStream fos = new FileOutputStream(request.getDownloadFolder() + "/" + request.getFileName());
BufferedOutputStream bos = new BufferedOutputStream(fos );
// Read bytes from URL to the local file
byte[] buffer = new byte[4096];
int bytesRead = 0;
System.out.println("Downloading " + request.getFileName());
while ((bytesRead = initialStream.read(buffer)) != -1) {
bos.write(buffer, 0, bytesRead);
}
bos.flush();
// Close destination stream
bos.close();
// Close URL stream
initialStream.close();
}
The document is created where it should be created but the file is damaged and can't be opened. I wonder what is the issue at this stage.
I finally solved my issue. Here is a basic method that shows my implementation :
public class DownloadFile {
public static void main(String[] args) throws IOException {
String url = "https://graph.microsoft.com/v1.0/drives/{driveId}/items/{itemId}/content";
SharePointCredentialRequest sharePointCredentialRequest = new SharePointCredentialRequest(Constants.TENANT_CLIENT_ID,
Constants.TENANT_CLIENT_SECRET, Constants.TENANT_AUTHORITY);
String token = Utils.getToken(sharePointCredentialRequest);
CloseableHttpClient client = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(url);
httpGet.setHeader("Authorization", "Bearer " + token);
try (CloseableHttpResponse response = client.execute(httpGet)) {
HttpEntity entity = response.getEntity();
if (entity != null) {
System.out.println(response.getAllHeaders().length);
System.out.println(entity.getContentEncoding());
System.out.println(entity.getContentLength());
System.out.println(entity.getContentType().getElements().toString());
try {
// do something useful with the stream
InputStream inputStream = IOUtils.toBufferedInputStream(response.getEntity().getContent());
File targetFile = new File("C:\\myFolder\\kant.pdf");
FileUtils.copyInputStreamToFile(inputStream, targetFile);
} catch (IOException | UnsupportedOperationException e) {
e.printStackTrace();
}
}
}
}
}

Http response: Cannot convert JSON into stream

I have an API in JAVA to upload a zip file to a server in Delphi, and I am doing it as follows:
DSRESTConnection conn = new DSRESTConnection();
conn.setHost("example.com");
conn.setPort(8080);
TServerMethods1 proxy = new TServerMethods1(conn);
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(baos);
ZipOutputStream zos = new ZipOutputStream(bos);
zos.putNextEntry(new ZipEntry("test.json"));
byte[] bytes = inputJson.getBytes();
zos.write(bytes, 0, bytes.length);
zos.close();
bos.close();
baos.close();
TStream outZip = new TStream(baos.toByteArray());
zipResponse = proxy.UserZipUpLoad("username", "password", 5, outZip, outZip.asByteArray().length);
} catch (DBXException | IOException e) {
e.printStackTrace();
}
and here is the API:
public UserZipUpLoadReturns UserZipUpLoad(String user, String pwd, int ZipType, TStream strmUpLoad, long iSize) throws DBXException {
DSRESTCommand cmd = getConnection().CreateCommand();
cmd.setRequestType(DSHTTPRequestType.POST);
cmd.setText("TServerMethods1.UserZipUpLoad");
cmd.prepare(get_TServerMethods1_UserZipUpLoad_Metadata());
cmd.getParameter(0).getValue().SetAsString(user);
cmd.getParameter(1).getValue().SetAsString(pwd);
cmd.getParameter(2).getValue().SetAsInt32(ZipType);
cmd.getParameter(3).getValue().SetAsStream(strmUpLoad);
cmd.getParameter(4).getValue().SetAsInt64(iSize);
getConnection().execute(cmd);
UserZipUpLoadReturns ret = new UserZipUpLoadReturns();
ret.ReturnCode = cmd.getParameter(5).getValue().GetAsInt32();
ret.ReturnString = cmd.getParameter(6).getValue().GetAsString();
ret.returnValue = cmd.getParameter(7).getValue().GetAsInt32();
return ret;
}
To create the body for the request, _parameter is created of the params in the API which cannot be in the url such as a byteArray or blob:
boolean CanAddParamsToUrl = true;
_parameters = new TJSONArray();
for (DSRESTParameter parameter : ParametersToSend)
if (CanAddParamsToUrl && isURLParameter(parameter))
URL += encodeURIComponent(parameter) + '/';
else // add the json representation in the body
{
CanAddParamsToUrl = false;
parameter.getValue().appendTo(_parameters);
}
and using the _parameters, body is built:
TJSONObject body = new TJSONObject();
body.addPairs("_parameters", _parameters);
p.setEntity(new StringEntity(body.toString(), "utf-8"));
I don't have access to the server side and don't know what happens there. When I send a JSON object or any other strings, the server returns ok but as soon as I zip the JSON and send it, the server return error 500 saying "Cannot convert input JSON into a stream". I think the JSON it is referring is the body not the JSON string in the file.
From the last part of the code I can see why a string would work but I don't know how to use the current code to send a zip file as requested.
Is there anyway to use this code? or should I change it? If so, how?
Does anybody know if this is a bug?

How to get JSON Key/Value pairs with JSP [duplicate]

I'm very new to RESTFull WCF Services and even newer to calling them from an Android app. Here's my WCF service:
[ServiceContract]
public interface IPeople
{
[OperationContract]
void DoWork();
[WebGet(UriTemplate = "/GetPeople",
BodyStyle = WebMessageBodyStyle.WrappedRequest,
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json)]
[OperationContract]
string GetPeople();
}
The implementation of the interface:
public string GetPeople()
{
PeoplesEntities qe = new PeoplesEntities();
var result = from q in qe.tPeople
select q;
int count = result.Count();
int index = new Random().Next(count);
tPeople people = result.OrderBy(a=>a.ID).Skip(index).FirstOrDefault();
// result.First().ToString();
return people.FirstName + " - " + people.LastName;
}
and this is how i'm consuming it through an android service:
try {
HttpGet request = new HttpGet(SERVICE_URI + "/GetPeople");
request.setHeader("Accept", "application/json");
request.setHeader("Content-type", "application/json");
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpResponse response = httpClient.execute(request);
HttpEntity responseEntity = response.getEntity();
// Read response data into buffer
char[] buffer = new char[(int)responseEntity.getContentLength()];
InputStream stream = responseEntity.getContent();
InputStreamReader reader = new InputStreamReader(stream);
reader.read(buffer);
stream.close();
JSONArray plates = new JSONArray(new String(buffer));
return new String(buffer);
} catch (Exception e) {
e.printStackTrace();
return e.toString();
}
}
The exception I get is what is mentioned in the subject. What's strange is the value tha ti'm expecting is returned in the exception. I have no clue why it's expecting the square bracket.
FYI, most of the code i used is taken directly from online examples. Any help would be greatly appreciated. Thanks.
You're trying to create a JSONArray from a string that doesn't contain valid JSON array syntax. A JSONArray can be created from a string of the form [item1, item2, item3....] but you're just returning a single item in your string: FirstName LastName.
The line after it just returns the buffer, so the JSONArray call is pointless, anyway. You don't need the JSONArray call at all, since you're not dealing with JSON data. Just remove that line.

How can i do a http get request in Blackberry

i have to do a http GET request on the URL http://api.twitter.com/1/users/show.json?screen_name=Kaka and i will get a JSON object, but i don't know how i have to do it.
Anyone could help me?
Thanks you.
This BlackBerry code sample shows how you do that
Or, From another fairly simple example, that uses the org.json.me package added to BlackBerry Java 6.0:
HttpConnection conn = null;
InputStream in = null;
ByteArrayOutputStream out = null;
try {
String url = "http://api.twitter.com/1/users/show.json?screen_name=Kaka";
conn = (HttpConnection) Connector.open(url, Connector.READ);
conn.setRequestMethod(HttpConnection.GET);
int code = conn.getResponseCode();
if (code == HttpConnection.HTTP_OK) {
in = conn.openInputStream();
out = new ByteArrayOutputStream();
byte[] buffer = new byte[in.available()];
int len = 0;
while ((len = in.read(buffer)) > 0) {
out.write(buffer);
}
out.flush();
String response = new String(out.toByteArray());
JSONObject resObject = new JSONObject(response);
String key = resObject.getString("Insert Json Key");
Vector resultsVector = new Vector();
JSONArray jsonArray = resObject.getJSONArray("Insert Json Array Key");
if (jsonArray.length() > 0) {
for (int i = 0; i < jsonArray.length();i++) {
Vector elementsVector = new Vector();
JSONObject jsonObj = jsonArray.getJSONObject(i);
elementsVector.addElement(jsonObj.getString("Insert Json Array Element Key1"));
elementsVector.addElement(jsonObj.getString("Insert Json Array Element Key2"));
resultsVector.addElement(elementsVector);
}
}
}
} catch (Exception e) {
Dialog.alert(e.getMessage());
} finally {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
if (conn != null) {
conn.close();
}
}
Obviously, in the second example, you have to insert the names of the JSON keys that your JSON data actually uses (left as an exercise for the poster). Also, you'll probably know something about how the JSON objects are structured, as objects, and arrays, etc. So, your code for unpacking the JSON data into JSONObjects and JSONArrays may look a little different than above, depending on the structure of your own JSON data.

upload image from android phone to the server

I am new to android trying to work on uploading image in to server.
Got some sample code from the Internet. But it is showing some error in the line which am not able to handle it. Can any one help me in this case. And the link which is fetch the code is http://blog.sptechnolab.com/2011/03/09/android/android-upload-image-to-server/
and the error is getting is
"The method encodeBytes(byte[]) is undefined for the type Base64"
and the corresponding
i have even downloaded base64.java file in the project
There is no encodeBytes in the API. Use encodeToString.
You can use these methods instead
public static String encodeToString (byte[] input, int offset, int len, int flags)
Since: API Level 8
Base64-encode the given data and return a newly allocated String with the result.
Parameters
input : the data to encode
offset : the position within the input array at which to start
len : The number of bytes of input to encode
flags : controls certain features of the encoded output.
Passing DEFAULT results in output that adheres to RFC 2045.
public static String encodeToString (byte[] input, int flags)
Since: API Level 8
Base64-encode the given data and return a newly allocated String with the result.
Parameters
input : the data to encode
flags :controls certain features of the encoded output.
Passing DEFAULT results in output that adheres to RFC 2045.
Whaaaa!
You MUST indent your code!
For every { you open you should space to the right so you'll see better what your code is doing:
This is good:
try {
something();
} catch (Exception e) {
weMessedUp();
if (e == i)
{
lol();
}
}
This is bad:
try {
something();
} catch (Exception e) {
weMessedUp();
if (e == i)
{
lol();
}
}
It's only for reading, your programs will be faster to understand if in one week you want to modify something.
In eclipse to indent, do ctrl + a to select your whole code, then ctrl + i to indent.
This doesn't answer you question but will help others to answer and you to improve your skills.
You can simply open the file as a bytestream and send it as a stream to your httpconnection?
Opening a file as a stream like so:
File inFile = new File(fileName);
BufferedReader br = new BufferedReader(
new InputStreamReader(
new FileInputStream(inFile)
)
);
URL url = new URL("http://www.google.com");
URLConnection connection = url.openConnection();
connection.setDoOutput(true);
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
while ((decodedString = br.readLine()) != null) {
out.write(decodedString);
}
out.close();
This is the implementation for reading a file line by line. Not sure if it will work given the encoding of an image without line breaks, but you should be able to reengineer to stream byte-by-byte without much trouble.
public class UploadImage extends Activity {
InputStream inputStream;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.icon); ByteArrayOutputStream <span id="IL_AD5" class="IL_AD">stream</span> = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 90, stream); //compress to which format you want.
byte [] byte_arr = stream.toByteArray();
String image_str = Base64.encodeBytes(byte_arr);
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("image",image_str));
try{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://10.0.2.2/Upload_image_ANDROID/upload_image.php");
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
String the_string_response = convertResponseToString(response);
Toast.makeText(UploadImage.this, "Response " + the_string_response, Toast.LENGTH_LONG).show();
}catch(Exception e){
Toast.makeText(UploadImage.this, "ERROR " + e.getMessage(), Toast.LENGTH_LONG).show();
System.out.println("Error in http connection "+e.toString());
}
}
public String convertResponseToString(HttpResponse response) throws IllegalStateException, IOException{
String res = "";
StringBuffer buffer = new StringBuffer();
inputStream = response.getEntity().getContent();
int contentLength = (int) response.getEntity().getContentLength(); //getting content length…..
Toast.makeText(UploadImage.this, "contentLength : " + contentLength, Toast.LENGTH_LONG).show();
if (contentLength < 0){
}
else{
byte[] data = new byte[512];
int len = 0;
try
{
while (-1 != (len = inputStream.read(data)) )
{
buffer.append(new String(data, 0, len)); //converting to string and appending to stringbuffer…..
}
}
catch (IOException e)
{
e.printStackTrace();
}
try
{
inputStream.close(); // closing the stream…..
}
catch (IOException e)
{
e.printStackTrace();
}
res = buffer.toString(); // converting stringbuffer to string…..
Toast.makeText(UploadImage.this, "Result : " + res, Toast.LENGTH_LONG).show();
//System.out.println("Response => " + EntityUtils.toString(response.getEntity()));
}
return res;

Categories