直接上代码,首先自定义的request:
- public class MultipartRequest extends Request<JSONObject> {
- private VolleyErrorListener errorListener = null;
- private VolleyResponseListener listener = null;
- private MultipartRequestParams params = null;
- private HttpEntity httpEntity = null;
- public MultipartRequest(String url, VolleyJsonResponseHandler handler, MultipartRequestParams params) {
- this(Method.POST,params, url, handler, null);
- }
- public MultipartRequest(int method,MultipartRequestParams params, String url, VolleyJsonResponseHandler handler,
- Context context) {
- super(method, RequestUrl.BASE_URL + url, null);
- // TODO Auto-generated constructor stub
- this.params = params;
- this.errorListener = new VolleyErrorListener(context, handler, false, this);
- this.listener = new VolleyResponseListener(context, handler);
- }
- @Override
- public byte[] getBody() throws AuthFailureError {
- // TODO Auto-generated method stub
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- if(params != null) {
- httpEntity = params.getEntity();
- try {
- httpEntity.writeTo(baos);
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- Logger.d("IOException writing to ByteArrayOutputStream");
- }
- String str = new String(baos.toByteArray());
- Logger.d("bodyString is :" + str);
- }
- return baos.toByteArray();
- }
- @Override
- protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
- // TODO Auto-generated method stub
- try {
- String jsonString = new String(response.data,
- HttpHeaderParser.parseCharset(response.headers));
- return Response.success(new JSONObject(jsonString),
- HttpHeaderParser.parseCacheHeaders(response));
- } catch (UnsupportedEncodingException e) {
- errorListener.setFlag(false);
- return Response.error(new ParseError(response));
- } catch (JSONException je) {
- errorListener.setFlag(false);
- return Response.error(new ParseError(response));
- }
- }
- @Override
- public Map<String, String> getHeaders() throws AuthFailureError {
- // TODO Auto-generated method stub
- Map<String, String> headers = super.getHeaders();
- if (null == headers || headers.equals(Collections.emptyMap())) {
- headers = new HashMap<String, String>();
- }
- MainApplication.getInstance().addSessionCookie(headers);
- return headers;
- }
- @Override
- public String getBodyContentType() {
- // TODO Auto-generated method stub
- String str = httpEntity.getContentType().getValue();
- return httpEntity.getContentType().getValue();
- }
- @Override
- protected void deliverResponse(JSONObject response) {
- // TODO Auto-generated method stub
- listener.onResponse(response);
- }
- @Override
- public void deliverError(VolleyError error) {
- // TODO Auto-generated method stub
- if(errorListener != null) {
- errorListener.onErrorResponse(error);
- }
- }
- public class MultipartRequestParams {
- protected ConcurrentHashMap<String, String> urlParams;
- protected ConcurrentHashMap<String, FileWrapper> fileParams;
- public MultipartRequestParams() {
- init();
- }
- public MultipartRequestParams(String key, String value) {
- init();
- put(key, value);
- }
- private void init() {
- urlParams = new ConcurrentHashMap<String, String>();
- fileParams = new ConcurrentHashMap<String, FileWrapper>();
- }
- /**
- * 添加value到request中
- * @param key
- * @param value
- */
- public void put(String key, String value) {
- if(key != null && value != null) {
- urlParams.put(key, value);
- }
- }
- /**
- * 添加文件到request中
- * @param key
- * @param file
- */
- public void put(String key, File file) {
- try {
- put(key, new FileInputStream(file), file.getName());
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- Logger.d("MultipartRequestParams file not found!!!");
- }
- }
- /**
- * 添加stream到request中
- * @param key
- * @param stream
- * @param fileName
- */
- public void put(String key, InputStream stream, String fileName) {
- put(key, stream, fileName, null);
- }
- /**
- * 添加stream到request中
- * @param key
- * @param stream
- * @param fileName
- * @param contentType
- */
- public void put(String key, InputStream stream, String fileName, String contentType) {
- if(key != null && stream != null) {
- fileParams.put(key, new FileWrapper(stream, fileName, contentType));
- }
- }
- public HttpEntity getEntity() {
- HttpEntity entity = null;
- if(!fileParams.isEmpty()) {
- MultipartEntity multipartEntity = new MultipartEntity();
- // Add string params
- for(ConcurrentHashMap.Entry<String, String> entry : urlParams.entrySet()) {
- multipartEntity.addPart(entry.getKey(), entry.getValue());
- }
- // Add file params
- int currentIndex = 0;
- int lastIndex = fileParams.entrySet().size() - 1;
- for(ConcurrentHashMap.Entry<String, FileWrapper> entry : fileParams.entrySet()) {
- FileWrapper file = entry.getValue();
- if(file.inputStream != null) {
- boolean isLast = currentIndex == lastIndex;
- if(file.contentType != null) {
- multipartEntity.addPart(entry.getKey(), file.getFileName(), file.inputStream, file.contentType, isLast);
- } else {
- multipartEntity.addPart(entry.getKey(), file.getFileName(), file.inputStream, isLast);
- }
- }
- currentIndex++;
- }
- entity = multipartEntity;
- }
- return entity;
- }
- private static class FileWrapper {
- public InputStream inputStream;
- public String fileName;
- public String contentType;
- public FileWrapper(InputStream inputStream, String fileName,
- String contentType) {
- this.inputStream = inputStream;
- this.fileName = fileName;
- this.contentType = contentType;
- }
- public String getFileName() {
- if (fileName != null) {
- return fileName;
- } else {
- return "nofilename";
- }
- }
- }
- class MultipartEntity implements HttpEntity {
- private final static char[] MULTIPART_CHARS = "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
- private String boundary = null;
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- boolean isSetLast = false;
- boolean isSetFirst = false;
- public MultipartEntity() {
- final StringBuffer buf = new StringBuffer();
- final Random rand = new Random();
- for (int i = 0; i < 30; i++) {
- buf.append(MULTIPART_CHARS[rand.nextInt(MULTIPART_CHARS.length)]);
- }
- this.boundary = buf.toString();
- }
- public void writeFirstBoundaryIfNeeds(){
- if(!isSetFirst){
- try {
- out.write(("--" + boundary + "\r\n").getBytes());
- } catch (final IOException e) {
- e.printStackTrace();
- }
- }
- isSetFirst = true;
- }
- public void writeLastBoundaryIfNeeds() {
- if(isSetLast){
- return;
- }
- try {
- out.write(("\r\n--" + boundary + "--\r\n").getBytes());
- } catch (final IOException e) {
- e.printStackTrace();
- }
- isSetLast = true;
- }
- public void addPart(final String key, final String value) {
- writeFirstBoundaryIfNeeds();
- try {
- out.write(("Content-Disposition: form-data; name=\"" +key+"\"\r\n\r\n").getBytes());
- out.write(value.getBytes());
- out.write(("\r\n--" + boundary + "\r\n").getBytes());
- } catch (final IOException e) {
- e.printStackTrace();
- }
- }
- public void addPart(final String key, final String fileName, final InputStream fin, final boolean isLast){
- addPart(key, fileName, fin, "application/octet-stream", isLast);
- }
- public void addPart(final String key, final String fileName, final InputStream fin, String type, final boolean isLast){
- writeFirstBoundaryIfNeeds();
- try {
- type = "Content-Type: "+type+"\r\n";
- out.write(("Content-Disposition: form-data; name=\""+ key+"\"; filename=\"" + fileName + "\"\r\n").getBytes());
- out.write(type.getBytes());
- out.write("Content-Transfer-Encoding: binary\r\n\r\n".getBytes());
- final byte[] tmp = new byte[4096];
- int l = 0;
- while ((l = fin.read(tmp)) != -1) {
- out.write(tmp, 0, l);
- }
- if(!isLast)
- out.write(("\r\n--" + boundary + "\r\n").getBytes());
- else {
- writeLastBoundaryIfNeeds();
- }
- out.flush();
- } catch (final IOException e) {
- e.printStackTrace();
- } finally {
- try {
- fin.close();
- } catch (final IOException e) {
- e.printStackTrace();
- }
- }
- }
- public void addPart(final String key, final File value, final boolean isLast) {
- try {
- addPart(key, value.getName(), new FileInputStream(value), isLast);
- } catch (final FileNotFoundException e) {
- e.printStackTrace();
- }
- }
- @Override
- public long getContentLength() {
- writeLastBoundaryIfNeeds();
- return out.toByteArray().length;
- }
- @Override
- public Header getContentType() {
- return new BasicHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
- }
- @Override
- public boolean isChunked() {
- return false;
- }
- @Override
- public boolean isRepeatable() {
- return false;
- }
- @Override
- public boolean isStreaming() {
- return false;
- }
- @Override
- public void writeTo(final OutputStream outstream) throws IOException {
- outstream.write(out.toByteArray());
- }
- @Override
- public Header getContentEncoding() {
- return null;
- }
- @Override
- public void consumeContent() throws IOException,
- UnsupportedOperationException {
- if (isStreaming()) {
- throw new UnsupportedOperationException(
- "Streaming entity does not implement #consumeContent()");
- }
- }
- @Override
- public InputStream getContent() throws IOException,
- UnsupportedOperationException {
- return new ByteArrayInputStream(out.toByteArray());
- }
其实MultipartParams和MultipartEntity主要都是用开源的AsyncHttpClient里面的源文件