I wrote a programm that can up-/download documents to sharepoint and check them in/out. It is used for data integration purposes and works quite well.
It was implemented using SOAP, but unfortunately the Server is configured to only be able to handle files with a size lesser than 50MB via SOAP.
The server configuration is fixed, so I have to work around that.
I added some code and I am able to up/download bigger files now, but If I want to check them in via SOAP I get the same error.
Now I wonder If it is possible to checkin/out files using the httpclient.
My code so far...
public class HttpClient {
private static final Logger LOGGER = LogManager.getLogger(HttpClient.class.getName());
HttpClient() {
}
public static void download(final String source, final File resultingFile) {
CloseableHttpClient client = WinHttpClients.createSystem();
HttpGet httpRequest = new HttpGet(source);
CloseableHttpResponse httpResponse = null;
try {
httpResponse = client.execute(httpRequest);
HttpEntity entity = httpResponse.getEntity();
if(httpResponse.getStatusLine() != null && httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
LOGGER.warn(httpResponse.getStatusLine());
}else {
LOGGER.debug(httpResponse.getStatusLine());
FileUtils.touch(resultingFile);
InputStream is = entity.getContent();
File outFile = new File(resultingFile.getAbsolutePath());
FileOutputStream fos = new FileOutputStream(outFile);
int inByte;
while ((inByte = is.read()) != -1) {
fos.write(inByte);
}
is.close();
fos.close();
client.close();
}
} catch (ClientProtocolException e) {
LOGGER.warn(e);
} catch (UnsupportedOperationException e) {
LOGGER.warn(e);
} catch (IOException e) {
LOGGER.warn(e);
}
}
public static void upload(final File source, final String destination) {
CloseableHttpClient httpclient = WinHttpClients.createSystem();
HttpPut httpRequest = new HttpPut(destination);
httpRequest.setEntity(new FileEntity(new File(source.getPath())));
CloseableHttpResponse httpResponse = null;
try {
httpResponse = httpclient.execute(httpRequest);
EntityUtils.consume(httpResponse.getEntity());
if (httpResponse.getStatusLine() != null && httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_CREATED) {
LOGGER.debug(httpResponse.getStatusLine());
LOGGER.info("Upload of " + source.getName() + " via HTTP-Client succeeded.");
} else if (httpResponse.getStatusLine() != null && httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
LOGGER.debug(httpResponse.getStatusLine());
}else {
LOGGER.warn("Uploading " + source.getName() + " failed.");
LOGGER.warn(httpResponse.getStatusLine().getStatusCode() + ": " + httpResponse.getStatusLine().getReasonPhrase());
}
} catch (IOException e) {
LOGGER.warn(e);
LOGGER.warn(e.getMessage());
}
return;
}
}
Related
I am trying to download file using Java URL class, but it is downloading HTML content instead.
class DownloadFileHttpCilent {
public static void main(String[] args) throws Exception {
try {
CloseableHttpClient client = HttpClientBuilder.create().build();
HttpGet request = new HttpGet(
"https://url");
String encoding=Base64.getEncoder().encodeToString(("abcd:pwd").getBytes());
request.setHeader("Authorization", "Basic " + encoding);
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
int responseCode = response.getStatusLine().getStatusCode();
System.out.println("Request Url: " + request.getURI());
System.out.println("Response Code: " + responseCode);
InputStream is = entity.getContent();
String filePath = "c:\\file1.zip";
FileOutputStream fos = new FileOutputStream(new File(filePath));
int inByte;
while ((inByte = is.read()) != -1) {
fos.write(inByte);
}
is.close();
fos.close();
client.close();
System.out.println("File Download Completed!!!");
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (UnsupportedOperationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
For other open source URLs, it's working fine, but only in this case, in which it is password protected, it is downloading HTML content.
Output:
Request Url: https://abcd.cahj.com/defj
Response Code: 200
File Download Completed!!!
I have an Android application that records an audio file and uploads it to an API for fingerprinting. The app works well when it uploads for the first time and gets the right response. However, on trying to upload again the request from the app seems to reach the server without the uploaded file. Strangely, when I close the app completely and open it again, it works well. However, I want it to be able to do the uploads continuously without having to close it after every attempt.
Here is my code:
public class MainActivity extends Activity {
class UploadFileTask extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... voids) {
String responseString = "";
HttpResponse response = null;
try {
//below is the API url
String url = "http://1**.**.**.**:8000/api/tag/";
File track = new File(Environment.getExternalStorageDirectory(), "mezzo.mp3");
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
MultipartEntityBuilder reqEntity = MultipartEntityBuilder.create();
reqEntity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
FileBody fb = new FileBody(track);
//InputStream inputStream = new ;
//reqEntity.addPart("track", fb);
reqEntity.addBinaryBody("track", track);
final HttpEntity myEntity = reqEntity.build();
httppost.setEntity(myEntity);
Log.i("request", String.valueOf(myEntity));
response = httpclient.execute(httppost);
//process response
responseString = new BasicResponseHandler().handleResponse(response);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null!=response)
{
try
{
HttpEntity httpEntity = response.getEntity();
if (null != httpEntity)
{
httpEntity.consumeContent();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
return responseString;
}
protected void onPostExecute(final String responseString) {
runOnUiThread(new Thread() {
public void run() {
Toast.makeText(getApplicationContext(),
responseString, Toast.LENGTH_LONG).show();
}
});
}
What I'm I doing wrong?
I am not sure but I suspect that the http response might not be consumed entirely.
Can you try consuming the response before you return from the function in a finally block:
finally
{
if (null!=response)
{
try
{
HttpEntity httpEntity = response.getEntity();
if (null != httpEntity)
{
httpEntity.consumeContent();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
I've got org.apache.http.HttpResponse object, which I'm using at different places in the code. One of those places is for logging.
The problem is that when I run following log code:
HttpEntity entity = response.getEntity();
try {
String content = Base64.encodeToString(
EntityUtils.toByteArray(entity), Base64.DEFAULT);
sb.append(content + "\r\n");
} catch (Exception e) {
sb.append("\r\n\r\n====EXCEPTION=====\r\n" + e.toString()
+ "\r\n");
}
and than I try to read entry content in the actual processing code, that causes the code to throw following exception:
java.lang.IllegalStateException: Content has been consumed
My question is: how do I read the entity without consuming it in the log code?
UPDATE
here's the full code of the function I use to transform httpresponse to string:
static String toString(org.apache.http.HttpResponse response) {
try {
if (response == null) {
return "null";
}
StringBuilder sb = new StringBuilder();
sb.append("==============BEGIN HttpResponse================\r\n");
StatusLine sl = response.getStatusLine();
if (sl == null) {
sb.append("status line is null\r\n");
} else {
sb.append(String.format("%s %s\r\n", sl.getStatusCode(),
sl.getReasonPhrase()));
}
for (Header h : response.getAllHeaders()) {
if (h == null) {
sb.append("header is null\r\n");
continue;
}
sb.append(String.format("%s: %s\r\n", h.getName(), h.getValue()));
}
sb.append("\r\r\r\n");
HttpEntity entity = response.getEntity();
if (entity == null) {
sb.append("content is null");
} else {
try {
String content = Base64.encodeToString(
EntityUtils.toByteArray(entity), Base64.DEFAULT);
sb.append(content + "\r\n");
} catch (Exception e) {
sb.append("\r\n\r\n====EXCEPTION=====\r\n" + e.toString()
+ "\r\n");
}
}
sb.append("\r\n==============END HttpResponse================\r\n");
return sb.toString();
} catch (Exception e) {
return e.toString();
}
}
Ok. So what I ended up doing is implementing my own HttpEntity class, and than just using response.setEntity(...) to replace the previous entity. That class stores the result as binary array and returns it as many times as necessary.
It might give you some performance issues, but will work:
Example of my HttpClient with logging.
private CloseableHttpResponse invoke(HttpRequestBase http) {
try {
CloseableHttpResponse response = client.execute(http);
if (http instanceof HttpPost) {
InputStream inputStream = ((HttpPost) http).getEntity().getContent();
String body = IOUtils.toString(inputStream, Charset.defaultCharset());
HttpEntity respBody = response.getEntity();
String responseBody = StreamUtils.copyToString(respBody.getContent(), Charset.defaultCharset());
response.setEntity(new StringEntity(responseBody));
LOG.info(String.format("Sending request: [%s] %s => [%s] \nPayload:\n%s \nResponse:\n%s", http.getMethod(), http.getURI(), response.getStatusLine(), body, responseBody));
} else {
LOG.info(String.format("Sending request: [%s] %s => [%s]", http.getMethod(), http.getURI(), response.getStatusLine()));
}
return response;
} catch (IOException e) {
throw new RuntimeException("HTTP request failed: " + http.toString(), e);
}
}
Main idea is following:
1. make http call
2. copy to string your response body:
HttpEntity respBody = response.getEntity();
String responseBody = StreamUtils.copyToString(respBody.getContent(), Charset.defaultCharset());
log it
set new response entity like response.setEntity(new StringEntity(responseBody));
This example work good for small test framework, not sure it's good code for production application
I can not upload large video to server android?
i try to use this method
private void UploadLargeFile(String[] args) throws Exception {
CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault();
try {
httpclient.start();
File upload = new File(args[0]);
File download = new File(args[1]);
ZeroCopyPost httpost = null;
try {
httpost = new ZeroCopyPost(URLTOUploadFile", upload,
ContentType.create("video/mp4"));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ZeroCopyConsumer<File> consumer = null;
consumer = new ZeroCopyConsumer<File>(download) {
#Override
protected File process(final HttpResponse response,
final File file, final ContentType contentType)
throws Exception {
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
throw new ClientProtocolException("Upload failed: "
+ response.getStatusLine());
}
return file;
}
};
Future<File> future = httpclient.execute(httpost, consumer, null);
File result;
result = future.get();
System.out.println("Response file length: " + result.length());
System.out.println("Shutting down");
} finally {
httpclient.close();
}
System.out.println("Done");
}
in the first line of CloseableHttpAsyncClient i got NoSuchFieldFound error
can any one help me?
I want to create a restful web service in java using jersey API and consume it in android application. I got this question on SO but it talks about java client whereas I have android client.
My service looks like this:
#Path("/no")
public class CheckNumber {
#POST
#Produces("application/json")
#Consumes("application/json")
public String getDetails(#PathParam("cNo") String cNo) {
String CardNo="";
try {
JSONObject jsonObj = new JSONObject(cNo);
CardNo=jsonObj.getString("CardNo");
} catch (ParseException e1) {
e1.printStackTrace();
}
//Do something
return "someValue";
}
}
Now comes the client side:
public class MainActivity extends Activity {
JSONObject json = new JSONObject();
String wsdl = "http://192.168.1.105:8080/restdemo/check/no/";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new RequestTask().execute("1234567890");
}
class RequestTask extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String add = "{\"CardNo\":\"" + uri[0] + "\"}";
HttpPost postMethod = new HttpPost(wsdl);
String responseString = null;
try {
postMethod.addHeader("Content-Type", "application/json");
HttpEntity entity = new StringEntity(add);
postMethod.setEntity(entity);
response = httpclient.execute(postMethod);
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
} else {
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
}
}
}
I'm just starting with rest web services. I successfully created a sample rest service which consumes string and returns string and used this service in android app.
But when I try to pass json string using POST method. It's giving following errorin log:
java.io.IOException: Internal Server Error
at com.example.restclient.MainActivity$RequestTask.doInBackground(MainActivity.java:85)
where MainActivity.java:85 is throw new IOException(statusLine.getReasonPhrase()); which implies that statusLine.getStatusCode() is not returning HttpStatus.SC_OK. Instead it's returning status code = 500.
Any help appreciated.
It will be good to see the server side log to understand better.
Try creating the entity with UTF8 and set the content-type in the string entity rather than in the postMethod
StringEntity stringEntity = new StringEntity(myJsonDocStr, HTTP.UTF_8);
stringEntity.setContentType("application/json");
Try this code, It works for me
Boolean NetworkLostFlag = false;
HttpParams httpParameters = new BasicHttpParams();
int timeoutConnection = 10000;
HttpConnectionParams.setConnectionTimeout(httpParameters,
timeoutConnection);
int timeoutSocket = 12000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
HttpClient httpclient = new DefaultHttpClient(httpParameters);
HttpPost httppost = new HttpPost(strUrl");
try {
httppost.setEntity(new UrlEncodedFormEntity(new BasicNameValuePair(arg1, val1), "UTF-8"));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
try {
// do something useful
StringBuffer buffer = new StringBuffer();
byte[] b = new byte[4096];
for (int n; (n = instream.read(b)) != -1;) {
buffer.append(new String(b, 0, n));
}
result = buffer.toString();
} catch (Exception e) {
NetworkLostFlag = true;
// TODO: handle exception
} finally {
instream.close();
}
}
} catch (Exception e) {
NetworkLostFlag = true;
e.printStackTrace();
}