I am using Volley for my API call. I need to post a image to my sever.
I have tried many MultipartRequest implementation, None works.
I just tried using a sample from How to send a “multipart/form-data” POST in Android with Volley by AZ_.
But I get MultipartRequest.getBody: IOException writing to ByteArrayOutputStream Error.
Can you help me out on my code, or know any complete sample for uploading a image using Volley please. Thank you.
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import org.apache.http.HttpEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.util.CharsetUtils;
import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyLog;
//Code by:
//https://stackoverflow.com/questions/16797468/how-to-send-a-multipart-form-data-post-in-android-with-volley
//AZ_
//
/**
* Problems : E/Volley﹕ [17225] MultipartRequest.getBody: IOException writing to ByteArrayOutputStream
*/
public class MultipartRequest extends Request<String> {
MultipartEntityBuilder entity = MultipartEntityBuilder.create();
HttpEntity httpentity;
private String FILE_PART_NAME = "files";
private final Response.Listener<String> mListener;
private final File mFilePart;
private final Map<String, String> mStringPart;
private Map<String, String> headerParams;
private final MultipartProgressListener multipartProgressListener;
private long fileLength = 0L;
public MultipartRequest(String url, Response.ErrorListener errorListener,
Response.Listener<String> listener, File file, long fileLength,
Map<String, String> mStringPart,
final Map<String, String> headerParams, String partName,
MultipartProgressListener progLitener) {
super(Method.POST, url, errorListener);
this.mListener = listener;
this.mFilePart = file;
this.fileLength = fileLength;
this.mStringPart = mStringPart;
this.headerParams = headerParams;
this.FILE_PART_NAME = partName;
this.multipartProgressListener = progLitener;
entity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
try {
entity.setCharset(CharsetUtils.get("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
buildMultipartEntity();
httpentity = entity.build();
}
// public void addStringBody(String param, String value) {
// if (mStringPart != null) {
// mStringPart.put(param, value);
// }
// }
private void buildMultipartEntity() {
entity.addPart(FILE_PART_NAME, new FileBody(mFilePart, ContentType.create("image/gif"), mFilePart.getName()));
if (mStringPart != null) {
for (Map.Entry<String, String> entry : mStringPart.entrySet()) {
entity.addTextBody(entry.getKey(), entry.getValue());
}
}
}
#Override
public String getBodyContentType() {
return httpentity.getContentType().getValue();
}
#Override
public byte[] getBody() throws AuthFailureError {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
httpentity.writeTo(new CountingOutputStream(bos, fileLength, multipartProgressListener));
}
catch (IOException e) {
VolleyLog.e("IOException writing to ByteArrayOutputStream");
}
return bos.toByteArray();
}
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
try {
// System.out.println("Network Response "+ new String(response.data, "UTF-8"));
return Response.success(new String(response.data, "UTF-8"),
getCacheEntry());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
// it should never happen though
return Response.success(new String(response.data), getCacheEntry());
}
}
#Override
protected void deliverResponse(String response) {
mListener.onResponse(response);
}
//Override getHeaders() if you want to put anything in header
public static interface MultipartProgressListener {
void transferred(long transfered, int progress);
}
public static class CountingOutputStream extends FilterOutputStream {
private final MultipartProgressListener progListener;
private long transferred;
private long fileLength;
public CountingOutputStream(final OutputStream out, long fileLength,
final MultipartProgressListener listener) {
super(out);
this.fileLength = fileLength;
this.progListener = listener;
this.transferred = 0;
}
public void write(byte[] b, int off, int len) throws IOException {
out.write(b, off, len);
if (progListener != null) {
this.transferred += len;
int prog = (int) (transferred * 100 / fileLength);
this.progListener.transferred(this.transferred, prog);
}
}
public void write(int b) throws IOException {
out.write(b);
if (progListener != null) {
this.transferred++;
int prog = (int) (transferred * 100 / fileLength);
this.progListener.transferred(this.transferred, prog);
}
}
}
}
User API Class
public void uploadFile(String api, File file, long fileLength, String partName, final UserUploadSuccessListener listener) {
this.listener = listener;
String url = Constant.DOMAIN + api;
Map<String, String> mHeaderParams = new HashMap<String, String>();
mHeaderParams.put("pram", "pramValue");
MultipartRequest multipartRequest = new MultipartRequest
(url, errorListener, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
listener.onUserUploadFile(response);
}
}, file, fileLength, null, mHeaderParams, partName, null);
multipartRequest.setRetryPolicy(new DefaultRetryPolicy(
30000, //30 seconds - change to what you want
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
mRequestQueue.add(multipartRequest);
}
Then Call it on MainActivity:
private void test1(){
File file = new File("path:/storage/emulated/0/copy_folder/Magazine/images/assets/images/img_0007.jpg");
long fileLength = file.length();
new UserApi().uploadFile("upload", file, fileLength, "imgPost", new UserApi.UserUploadSuccessListener() {
#Override
public void onUserUploadFile(String response) {
text.setText("uploadImage() - onUserUploadFile -> \n " + response.toString());
}
#Override
public void onError(VolleyError error) {
text.setText("uploadImage() - onError -> \n " + error.toString());
}
#Override
public void onResponseError(String message) {
text.setText("uploadImage() - onResponseError -> \n " + message);
}
});
}
Here are my dependencies in Android Studio:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.2.0'
compile 'com.google.code.gson:gson:2.3'
compile 'com.mcxiaoke.volley:library:1.0.+'
compile('org.apache.httpcomponents:httpmime:4.3.6') {
exclude module: 'httpclient'
}
compile 'org.apache.httpcomponents:httpclient-android:4.3.5'
}
Related
My implementation:
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ReadListener;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.WriteListener;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.output.TeeOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
public class ApiLoggingFilter implements Filter {
private static final Logger LOGGER = LoggerFactory.getLogger(ApiLoggingFilter.class);
ApiLoggingFilter(String requestIdParamName, String requestIdMDCParamName) {
this.requestIdParamName = requestIdParamName;
this.requestIdMDCParamName = requestIdMDCParamName;
}
private String requestIdParamName;
private String requestIdMDCParamName;
#Override
public void init(FilterConfig filterConfig) throws ServletException {
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
try {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
Map<String, String> requestMap = this.getTypesafeRequestMap(httpServletRequest);
BufferedRequestWrapper bufferedRequest = new BufferedRequestWrapper(httpServletRequest);
BufferedResponseWrapper bufferedResponse = new BufferedResponseWrapper(httpServletResponse);
String requestId = requestMap.containsKey(requestIdParamName) ? requestMap.get(requestIdParamName)
: UUID.randomUUID().toString();
MDC.put(requestIdMDCParamName, requestId);
final StringBuilder logRequest = new StringBuilder("HTTP ").append(httpServletRequest.getMethod())
.append(" \"").append(httpServletRequest.getServletPath()).append("\" ").append(", parameters=")
.append(requestMap).append(", body=").append(bufferedRequest.getRequestBody())
.append(", remote_address=").append(httpServletRequest.getRemoteAddr());
LOGGER.info(logRequest.toString());
try {
chain.doFilter(bufferedRequest, bufferedResponse);
} finally {
final StringBuilder logResponse = new StringBuilder("HTTP RESPONSE ")
.append(bufferedResponse.getContent());
LOGGER.info(logResponse.toString());
MDC.clear();
}
} catch (Throwable a) {
LOGGER.error(a.getMessage());
}
}
private Map<String, String> getTypesafeRequestMap(HttpServletRequest request) {
Map<String, String> typesafeRequestMap = new HashMap<String, String>();
Enumeration<?> requestParamNames = request.getParameterNames();
while (requestParamNames.hasMoreElements()) {
String requestParamName = (String) requestParamNames.nextElement();
String requestParamValue;
if (requestParamName.equalsIgnoreCase("password")) {
requestParamValue = "********";
} else {
requestParamValue = request.getParameter(requestParamName);
}
typesafeRequestMap.put(requestParamName, requestParamValue);
}
return typesafeRequestMap;
}
#Override
public void destroy() {
}
private static final class BufferedRequestWrapper extends HttpServletRequestWrapper {
private ByteArrayInputStream bais = null;
private ByteArrayOutputStream baos = null;
private BufferedServletInputStream bsis = null;
private byte[] buffer = null;
public BufferedRequestWrapper(HttpServletRequest req) throws IOException {
super(req);
// Read InputStream and store its content in a buffer.
InputStream is = req.getInputStream();
this.baos = new ByteArrayOutputStream();
byte buf[] = new byte[1024];
int read;
while ((read = is.read(buf)) > 0) {
this.baos.write(buf, 0, read);
}
this.buffer = this.baos.toByteArray();
}
#Override
public ServletInputStream getInputStream() {
this.bais = new ByteArrayInputStream(this.buffer);
this.bsis = new BufferedServletInputStream(this.bais);
return this.bsis;
}
String getRequestBody() throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(this.getInputStream()));
String line = null;
StringBuilder inputBuffer = new StringBuilder();
do {
line = reader.readLine();
if (null != line) {
inputBuffer.append(line.trim());
}
} while (line != null);
reader.close();
return inputBuffer.toString().trim();
}
}
private static final class BufferedServletInputStream extends ServletInputStream {
private ByteArrayInputStream bais;
public BufferedServletInputStream(ByteArrayInputStream bais) {
this.bais = bais;
}
#Override
public int available() {
return this.bais.available();
}
#Override
public int read() {
return this.bais.read();
}
#Override
public int read(byte[] buf, int off, int len) {
return this.bais.read(buf, off, len);
}
#Override
public boolean isFinished() {
return false;
}
#Override
public boolean isReady() {
return true;
}
#Override
public void setReadListener(ReadListener readListener) {
}
}
public class TeeServletOutputStream extends ServletOutputStream {
private final TeeOutputStream targetStream;
public TeeServletOutputStream(OutputStream one, OutputStream two) {
targetStream = new TeeOutputStream(one, two);
}
#Override
public void write(int arg0) throws IOException {
this.targetStream.write(arg0);
}
public void flush() throws IOException {
super.flush();
this.targetStream.flush();
}
public void close() throws IOException {
super.close();
this.targetStream.close();
}
#Override
public boolean isReady() {
return false;
}
#Override
public void setWriteListener(WriteListener writeListener) {
}
}
public class BufferedResponseWrapper implements HttpServletResponse {
HttpServletResponse original;
TeeServletOutputStream tee;
ByteArrayOutputStream bos;
public BufferedResponseWrapper(HttpServletResponse response) {
original = response;
}
public String getContent() {
return bos.toString();
}
public PrintWriter getWriter() throws IOException {
return original.getWriter();
}
public ServletOutputStream getOutputStream() throws IOException {
if (tee == null) {
bos = new ByteArrayOutputStream();
tee = new TeeServletOutputStream(original.getOutputStream(), bos);
}
return tee;
}
#Override
public String getCharacterEncoding() {
return original.getCharacterEncoding();
}
#Override
public String getContentType() {
return original.getContentType();
}
#Override
public void setCharacterEncoding(String charset) {
original.setCharacterEncoding(charset);
}
#Override
public void setContentLength(int len) {
original.setContentLength(len);
}
#Override
public void setContentLengthLong(long l) {
original.setContentLengthLong(l);
}
#Override
public void setContentType(String type) {
original.setContentType(type);
}
#Override
public void setBufferSize(int size) {
original.setBufferSize(size);
}
#Override
public int getBufferSize() {
return original.getBufferSize();
}
#Override
public void flushBuffer() throws IOException {
tee.flush();
}
#Override
public void resetBuffer() {
original.resetBuffer();
}
#Override
public boolean isCommitted() {
return original.isCommitted();
}
#Override
public void reset() {
original.reset();
}
#Override
public void setLocale(Locale loc) {
original.setLocale(loc);
}
#Override
public Locale getLocale() {
return original.getLocale();
}
#Override
public void addCookie(Cookie cookie) {
original.addCookie(cookie);
}
#Override
public boolean containsHeader(String name) {
return original.containsHeader(name);
}
#Override
public String encodeURL(String url) {
return original.encodeURL(url);
}
#Override
public String encodeRedirectURL(String url) {
return original.encodeRedirectURL(url);
}
#SuppressWarnings("deprecation")
#Override
public String encodeUrl(String url) {
return original.encodeUrl(url);
}
#SuppressWarnings("deprecation")
#Override
public String encodeRedirectUrl(String url) {
return original.encodeRedirectUrl(url);
}
#Override
public void sendError(int sc, String msg) throws IOException {
original.sendError(sc, msg);
}
#Override
public void sendError(int sc) throws IOException {
original.sendError(sc);
}
#Override
public void sendRedirect(String location) throws IOException {
original.sendRedirect(location);
}
#Override
public void setDateHeader(String name, long date) {
original.setDateHeader(name, date);
}
#Override
public void addDateHeader(String name, long date) {
original.addDateHeader(name, date);
}
#Override
public void setHeader(String name, String value) {
original.setHeader(name, value);
}
#Override
public void addHeader(String name, String value) {
original.addHeader(name, value);
}
#Override
public void setIntHeader(String name, int value) {
original.setIntHeader(name, value);
}
#Override
public void addIntHeader(String name, int value) {
original.addIntHeader(name, value);
}
#Override
public void setStatus(int sc) {
original.setStatus(sc);
}
#SuppressWarnings("deprecation")
#Override
public void setStatus(int sc, String sm) {
original.setStatus(sc, sm);
}
#Override
public String getHeader(String arg0) {
return original.getHeader(arg0);
}
#Override
public Collection<String> getHeaderNames() {
return original.getHeaderNames();
}
#Override
public Collection<String> getHeaders(String arg0) {
return original.getHeaders(arg0);
}
#Override
public int getStatus() {
return original.getStatus();
}
}
}
I've created a custom filter over my Spring app to log the request and responses including headers, params and body text.
It works fine for requests and responses usually, but when applied to a service which returns a large payload, the service returns all lines in full in the response but the service logs the response truncated to only a few lines.
Response header "transfer-encoding": "chunked" is what I believe is causing the odd behaviour for the logging. I think my logging code might be defaulting to a fixed size in the absence of content-length as it is streaming.
Is there a wrapper class or better approach I could take to get to copy the stream until completion. I have scoured the web but haven't seen this specific question asked - this one came close https://stackoverflow.com/questions/59295514/how-to-stream-chunked-response-with-spring-boot-restcontroller
I tried numerous filter implementations others have posted but the behaviour remained the same.
In this class I am sending request to server asynchronously by extending AsyncTask using HttpClient, I have created two custom classes one for Uploading and Downloading of Images from the server, and other for sending JSON Object and array. Beside this I'm also able to differentiate the requests using RequestTag
Can we also do the same using volley?
How can I upgrade to Volley from the HttpClient having same approach like in below class?
package com.creative.projectmanager;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import org.apache.commons.logging.Log;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
/**
* server manager class. performs all server requests asynchronously
*/
public class ServerManager {
final private String SERVER_ADDRESS = "http://192.168.200.10/";
public void login(String email, String password, int requestTag) {
String url = SERVER_ADDRESS + "index.php?mobile/" + "login";
HashMap<String, String> params = new HashMap<>();
params.put("email", email);
params.put("password", password);
params.put("authenticate", "false");
android.util.Log.w("My App", email + " " + password + " " + requestTag);
AsyncHttpPost requestSender = new AsyncHttpPost(url, params, requestTag);
requestSender.execute();
}
public void downloadImage(String imageUrl, int imageSize, int requestTag) {
ImageDownloadTask imageDownloadTask = new ImageDownloadTask(imageUrl, imageSize, requestTag);
imageDownloadTask.execute();
}
private class AsyncHttpPost extends AsyncTask<Void, Void, String> {
private String url = "";
private HashMap<String, String> postParams = null;
private int requestTag;
private String errorMessage = "";
public AsyncHttpPost(String url, HashMap<String, String> params, int tag) {
this.url = url;
postParams = params;
this.requestTag = tag;
}
#Override
protected String doInBackground(Void... params) {
byte[] result;
String resultString = "";
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
try {
ArrayList<NameValuePair> nameValuePairs = new ArrayList<>();
for (String key:postParams.keySet()
) {
nameValuePairs.add(new BasicNameValuePair(key, postParams.get(key)));
}
android.util.Log.w("My App",nameValuePairs.toString());
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
HttpResponse response = httpClient.execute(httpPost);
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() == HttpURLConnection.HTTP_OK) {
errorMessage = "ok";
result = EntityUtils.toByteArray(response.getEntity());
resultString = new String(result, "UTF-8");
}
}
catch (UnsupportedEncodingException e) {
errorMessage = "Encoding is not supported";
}
catch (Exception e) {
errorMessage = "An error occurred";
}
return resultString;
}
#Override
protected void onPostExecute(String s) {
if (errorMessage.equals("ok")) {
sourceActivity.requestFinished(s, requestTag);
}
else
sourceActivity.requestFailed(errorMessage, requestTag);
}
}
private class ImageDownloadTask extends AsyncTask<String, String, String> {
private String imageUrl;
private int imageSize;
private int requestTag;
Bitmap image;
public ImageDownloadTask(String imageUrl, int imageSize, int requestTag) {
this.imageUrl = imageUrl;
this.imageSize = imageSize;
this.requestTag = requestTag;
}
#Override
protected String doInBackground(String... params) {
try {
URL url = new URL(imageUrl);
InputStream inputStream = new BufferedInputStream(url.openStream());
image = createScaledBitmapFromStream(inputStream, imageSize);
}
catch (Exception e){
//do nothing
}
return null;
}
#Override
protected void onPostExecute(String s) {
sourceActivity.imageDownloaded(image, requestTag);
}
protected Bitmap createScaledBitmapFromStream(InputStream inputStream, int minimumDesiredBitmapSize) {
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream, 32*1024);
try {
BitmapFactory.Options decodeBitmapOptions = new BitmapFactory.Options();
if (minimumDesiredBitmapSize > 0) {
BitmapFactory.Options decodeBoundsOptions = new BitmapFactory.Options();
decodeBoundsOptions.inJustDecodeBounds = true;
bufferedInputStream.mark(32 * 1024);
BitmapFactory.decodeStream(bufferedInputStream, null, decodeBoundsOptions);
bufferedInputStream.reset();
int originalWidth = decodeBoundsOptions.outWidth;
int originalHeight = decodeBoundsOptions.outHeight;
decodeBitmapOptions.inSampleSize = Math.max(1, Math.min(originalWidth/minimumDesiredBitmapSize, originalHeight/minimumDesiredBitmapSize));
}
return BitmapFactory.decodeStream(bufferedInputStream, null, decodeBitmapOptions);
}
catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
bufferedInputStream.close();
} catch (IOException ignored) {}
}
}
}
}
There are a lot of examples of how to make requests with Volley, so "upgrading" will mean rewriting your code in different way.
Volley, in my opinion is not the best library for HTTP calls, I would recommend you to try
http://square.github.io/retrofit/
for loading images use http://square.github.io/picasso/ or glide. These libraries will help you make you code cleaner whit out boilerplate stuff.
I want to get the variable "response" from the BDDRequest class for using it in a ListView in my MainActivity class, how i can do ?
public class BDDRequest implements Serializable {
private final long serialVersionUID = 1L;
static private Activity activity;
public String req;
public BDDRequest(){}
public static void GetRequest(final Context t, UserEmployeeInfo User) {
activity = (Activity) t;
RequestQueue queue = Volley.newRequestQueue(t);
ParamsSend params = new ParamsSend();
params.setUser(User);
ParserJson<ParamsSend> pj = new ParserJson<>(params);
String strJson;
try {
strJson = pj.writeJSON();
} catch (JsonProcessingException e) {
strJson = "null";
}
final String data = strJson;
String REST_API_URL = "http://212.227.53.116:8080/WSmartgroom/rest/perso/request";
Log.d("lol", strJson);
StringRequest myReq = new StringRequest(Request.Method.PUT,
REST_API_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("reponse:", response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("That didn't work!", "Error");
}
}) {
#Override
public String getBodyContentType() {
return "application/json";
}
#Override
public byte[] getBody() throws AuthFailureError {
return data.getBytes();
}
};
queue.add(myReq);
}
}
Use an interface for it,
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import java.io.Serializable;
public class BDDRequest implements Serializable {
private final long serialVersionUID = 1L;
static private Activity activity;
public String req;
public BDDRequest() {
}
public static void GetRequest(final Context t, UserEmployeeInfo User, final Callback callback) {
activity = (Activity) t;
RequestQueue queue = Volley.newRequestQueue(t);
ParamsSend params = new ParamsSend();
params.setUser(User);
ParserJson<ParamsSend> pj = new ParserJson<>(params);
String strJson;
try {
strJson = pj.writeJSON();
} catch (JsonProcessingException e) {
strJson = "null";
}
final String data = strJson;
String REST_API_URL = "http://212.227.53.116:8080/WSmartgroom/rest/perso/request";
Log.d("lol", strJson);
StringRequest myReq = new StringRequest(Request.Method.PUT,
REST_API_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("reponse:", response);
callback.onSuccess(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("That didn't work!", "Error");
callback.onError();
}
}) {
#Override
public String getBodyContentType() {
return "application/json";
}
#Override
public byte[] getBody() throws AuthFailureError {
return data.getBytes();
}
};
queue.add(myReq);
}
public interface Callback {
void onSuccess(String response);
void onError();
}
}
And implement the interface on your class .
Use like this,
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.widget.TextView;
import com.example.BDDRequest.Callback;
public class MainActivity extends FragmentActivity implements Callback {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BDDRequest.GetRequest(this, new UserEmployeeInfo(), this);
}
#Override
public void onSuccess(String response) {
// Bind the data to the listview
}
#Override
public void onError() {
//Show fallback message here
}
}
You're declaring onResponse method. Inside it, response is a parameter. Why do you want to get a parameter which you're putting into? The question is not clear.
I want post json object included image to my server using Volley Library it post empty fields to server , image file posted successfully
I should post Json in this formate
{ "user_id":"value" , "post_title":"value","Specialty":"value","post_detail":"value", "uploaded_file","file" }
here is my android code
import android.util.Log;
import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.VolleyLog;
import com.android.volley.toolbox.HttpHeaderParser;
import com.imaadv.leaynik.Util.AppConstants;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.StringBody;
import org.json.JSONObject;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* Created by NT on 10/26/15.
*/
public class PhotoMultipartRequest<T> extends Request<T> {
private MultipartEntityBuilder mBuilder = MultipartEntityBuilder.create();
private Response.Listener<T> mListener;
private File mImageFile;
protected Map<String, String> headers;
private JSONObject params;
private String file_name;
private boolean hasFile;
public PhotoMultipartRequest(JSONObject params, String url, Response.ErrorListener errorListener, Response.Listener<T> listener, String file_name, File imageFile, boolean hasFile) {
super(Method.POST, url, errorListener);
mListener = listener;
mImageFile = imageFile;
this.params = params;
this.file_name = file_name;
this.hasFile = hasFile;
BuildMultiPartEntity();
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = super.getHeaders();
if (headers == null || headers.equals(Collections.emptyMap())) {
headers = new HashMap<>();
}
headers.put("accept", "application/json");
headers.put("Content-type","application/json");
return headers;
}
private void BuildMultiPartEntity() {
// Set keys = params.keySet();
// for (Iterator i = keys.iterator(); i.hasNext(); ) {
// String key = (String) i.next();
// try {
//
// }catch (Exception e){
// e.printStackTrace();
// }
//
// }
StringBody userId = new StringBody(params.get(AppConstants.USER_ID) ,ContentType.APPLICATION_JSON);
StringBody postDetail = new StringBody(params.get(AppConstants.POST_DETAIL) ,ContentType.APPLICATION_JSON);
StringBody postTitle = new StringBody(params.get(AppConstants.POST_TITLE) ,ContentType.APPLICATION_JSON);
StringBody Speciality = new StringBody(params.get(AppConstants.SPECIALTY) ,ContentType.APPLICATION_JSON);
mBuilder.addPart(AppConstants.USER_ID ,userId );
mBuilder.addPart(AppConstants.POST_DETAIL ,postDetail );
mBuilder.addPart(AppConstants.POST_TITLE ,postTitle );
mBuilder.addPart(AppConstants.SPECIALTY ,Speciality );
mBuilder.addTextBody(AppConstants.DATA, params.toString());
if (hasFile) {
mBuilder.addBinaryBody(file_name, mImageFile, ContentType.create("image/jpeg"), mImageFile.getName());
}
mBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
mBuilder.setLaxMode().setBoundary("xx").setCharset(Charset.forName("UTF-8"));
}
#Override
public String getBodyContentType() {
String contentTypeHeader = mBuilder.build().getContentType().getValue();
return contentTypeHeader;
}
#Override
public byte[] getBody() throws AuthFailureError {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
mBuilder.build().writeTo(bos);
} catch (IOException e) {
VolleyLog.e("IOException writing to ByteArrayOutputStream bos, building the multipart request.");
}
return bos.toByteArray();
}
#Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
T result = null;
return Response.success(result, HttpHeaderParser.parseCacheHeaders(response));
}
#Override
protected void deliverResponse(T response) {
mListener.onResponse(response);
}
#Override
protected VolleyError parseNetworkError(VolleyError volleyError) {
Log.i("Error1", volleyError.getMessage());
return super.parseNetworkError(volleyError);
}
#Override
public void deliverError(VolleyError error) {
Log.i("Error2", error.getMessage());
super.deliverError(error);
}
}
Could any one guide me what is wrong in my code
You can see your answer on follow this 3 link.....
Click here
http://www.survivingwithandroid.com/2013/05/android-http-downlod-upload-multipart.html
http://www.androidhive.info/2014/05/android-working-with-volley-library-1/
https://www.simplifiedcoding.net/android-volley-tutorial-to-upload-image-to-server/
Best Luck..
I have a working FTP system with android, but I want to be able to track the bytes as they get uploaded, so I can update a progress bar as the upload progresses. Is this possible with Android? Right now, I'm using org.apache.common.net.ftp and the code I'm using is below. Also, I am running this in an AsyncTask.
package com.dronnoc.ftp.complex;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.io.CopyStreamEvent;
import org.apache.commons.net.io.CopyStreamListener;
import org.apache.commons.net.io.Util;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Window;
public class Main extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.main);
String text = "BIGFILE"; //Big file here
InputStream data = new ByteArrayInputStream(text.getBytes());
new ComplexFTPTransfer().execute(data);
}
private class ComplexFTPTransfer extends AsyncTask<InputStream, Long[], Void>
{
private FTPClient ftp = null;
#Override
protected void onPreExecute() {
super.onPreExecute();
try {
ftp = new FTPClient();
ftp.connect("hostname");
} catch (SocketException e) {
this.cancel(true);
} catch (IOException e) {
this.cancel(true);
}
Main.this.setProgressBarIndeterminateVisibility(true);
}
#Override
protected Void doInBackground(InputStream... params) {
if(!this.isCancelled())
{
try
{
if(ftp.login("user", "pass"))
{
ftp.enterLocalPassiveMode();
InputStream item = params[0];
int streamSize = 0;
while(item.read() != -1)
{
streamSize++;
}
InputStream is = new BufferedInputStream(params[0], streamSize);
OutputStream os = ftp.storeFileStream("/test.txt");
Util.copyStream(is, os, streamSize, streamSize, new CopyStreamListener() {
#Override
public void bytesTransferred(long totalBytesTransferred, int bytesTransferred, long streamSize) {
publishProgress(new Long[] {totalBytesTransferred, streamSize});
}
#Override
public void bytesTransferred(CopyStreamEvent event) {
}
});
ftp.completePendingCommand();
}
ftp.logout();
ftp.disconnect();
}
catch (IOException e) {
}
catch (Exception e) {
}
}
return null;
}
#Override
protected void onProgressUpdate(Long[]... values) {
super.onProgressUpdate(values);
Log.d("UPDATE", values[0] + " of " + values[1] + " copied.");
//TODO Put code here
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
Main.this.setProgressBarIndeterminateVisibility(false);
}
}
}
What I want to know is if I can run a progress bar, updating every few uploaded bytes?
Cheers
This question has an implementation of an InputStream that includes a progress callback. Use that InputStream and call publishProgress from that callback for incremental updates during the file upload.
Download this .jar file
httpmime-4.1.1.jar and commons-net.jar
try {
FTPClient ftpClient = new FTPClient();
ftpClient.connect(InetAddress
.getByName(Your host Url));
ftpClient.login(loginName, password);
System.out.println("status :: " + ftpClient.getStatus());
ftpClient.changeWorkingDirectory(your directory name);
ftpClient.setFileType(FTP.IMAGE_FILE_TYPE);
//Your File path set here
File file = new File("/sdcard/my pictures/image.png");
BufferedInputStream buffIn = new BufferedInputStream(
new FileInputStream(myImageFile));
ftpClient.enterLocalPassiveMode();
ProgressInputStream progressInput = new ProgressInputStream(
buffIn);
boolean result = ftpClient.storeFile(UPLOADFILENAME + ".png",
progressInput);
System.out.println("result is :: " + result);
buffIn.close();
ftpClient.logout();
ftpClient.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
//ProgressInputStream
import java.io.IOException;
import java.io.InputStream;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
public class ProgressInputStream extends InputStream {
/* Key to retrieve progress value from message bundle passed to handler */
public static final String PROGRESS_UPDATE = "progress_update";
private static final int TEN_KILOBYTES = 1024 * 40;
private InputStream inputStream;
//private Handler handler;
private long progress;
private long lastUpdate;
private boolean closed;
public ProgressInputStream(InputStream inputStream) {
this.inputStream = inputStream;
this.progress = 0;
this.lastUpdate = 0;
this.closed = false;
}
#Override
public int read() throws IOException {
int count = inputStream.read();
return incrementCounterAndUpdateDisplay(count);
}
#Override
public int read(byte[] b, int off, int len) throws IOException {
int count = inputStream.read(b, off, len);
return incrementCounterAndUpdateDisplay(count);
}
#Override
public void close() throws IOException {
super.close();
if (closed)
throw new IOException("already closed");
closed = true;
}
private int incrementCounterAndUpdateDisplay(int count) {
if (count < 0)
progress += count;
lastUpdate = maybeUpdateDisplay(progress, lastUpdate);
return count;
}
private long maybeUpdateDisplay(long progress, long lastUpdate) {
if (progress - lastUpdate < TEN_KILOBYTES) {
lastUpdate = progress;
sendLong(PROGRESS_UPDATE, progress);
}
return lastUpdate;
}
public void sendLong(String key, long value) {
Bundle data = new Bundle();
data.putLong(key, value);
Message message = Message.obtain();
message.setData(data);
//handler.sendMessage(message);
}
}
This can be done using Secure FTP Factory library.
You just need to implement an instance of the com.jscape.inet.ftp.FtpListener interface, register the instance with the Ftp class and overload the progress(FtpProgressEvent event) method to capture progress information.
JavaDoc: Overview (secure FTP Factory API)
Download: Java FTP, Java FTPS and Java SFTP Components