安卓程序上传文件到java服务器

安卓程序上传文件到java服务器


主要思路:

将文件转换成Base64字符串,通过Http请求发送到服务器,在服务器端再进行转码,将Base64转换成
文件流


1 APP端

1 先通过Intent获取手机图库里的图片
private static final int CODE_REQUEST_IMG = 1;
private static final String IMG_TYPE = "image/*";
Intent intent4chooseFromFile = new Intent(Intent.ACTION_GET_CONTENT);
intent4chooseFromFile.setType(IMG_TYPE);
startActivityForResult(intent4chooseFromFile, CODE_REQUEST_IMG);
// requestCode起到一个标识符的作用,
// 在callback中可以根据requestCode来判断是返回的哪一个getContent的请求
// 比如很多程序获取图片,都是两个选择:从相机||从相册,这里只写一个做示例
2 这里就是根据请求码来决定下一步操作的示例:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
    case CODE_REQUEST_IMG:
        handleChooseAImgResult(resultCode, data);
        break;
    case CODE_TAKE_A_PHOTO:
        handleTakeAPhotoResult(resultCode, data);
        break;
    default:
        break;
    }
};
3 然后是handleChooseAImgResult()方法的具体实现:
/**
 * @param resultCode
 * @param data
 */
private void handleChooseAImgResult(int resultCode, Intent data) {
    if (resultCode != RESULT_OK) {
        Log.i("CHOOSE IMAGE", "no pic choosed");
        return;
    } else {
        Uri uri = data.getData();
        try {
            bitmap = BitmapFactory.decodeStream(getContentResolver()
                    .openInputStream(uri));
            if (bitmap != null) {
                imageView.setImageBitmap(bitmap);
                // 暂时设置在imageview上,这里不是重点
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        // 这个方法是重点,根据uri获取到图片在SDCARD中的实际位置
        String path = getImgPathFromContentUri(getApplicationContext(), uri);
        Log.i("path", path);
        triggerUpload(path);
    }
}
4 getImgPathFronContentUri()方法的具体实现:
/**
 * 
 * @param context
 * @param uri
 * @return image path
 */
private String getImgPathFromContentUri(Context context, Uri uri) {
    Cursor cursor = null;
    String path = "";
    String[] proj = new String[] { MediaStore.Images.Media.DATA };
    try {
        cursor = context.getContentResolver().query(uri, proj, null, null,
                null);
        if (cursor != null && cursor.moveToFirst()) {
            path = cursor.getString(0);
        }
    } finally {
        cursor.close();
    }
    return path;
}
5 获取到图片位置之后,就可以进行上传操作了。

如果对于contentprovider这一块操作不熟悉,在学习中可以直接使将文件路径hardcode成一个固定的路径。

url是:

private static final String URL = "http://192.168.1.102:8080/imageReceiver/ImageReceiverServlet";

其中:

1 http://192.168.1.102:8080是本机服务器的地址
2 imageReceiver是server端的javaweb工程名
3 ImageReceiverServlet是server端的servlet路径

上传

private void triggerUpload(final String imagePath) {
    StringRequest stringRequest = new StringRequest(Method.POST, URL,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    // 在这里接收到服务器返回的消息
                    Log.i("TAG", response);
                    if (response.equals("success")) {
                        Message message = Message.obtain();
                        message.what = UPLOAD_SUCEESS;
                        handler.sendMessage(message);
                    } else {
                        Message message = Message.obtain();
                        message.what = UPLOAD_FAILURE;
                        handler.sendMessage(message);
                    }
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    // 错误处理
                    Log.i("TAG", error.getMessage(), error);
                }
            }) {
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            // 在这里设置POST请求的参数
            // 因为POST请求和GET请求的结构格式不一样
            // 所以服务器端需要用DoPost()方法处理这个请求而不能用DoGet()方法
            HashMap<String, String> params = new HashMap<String, String>();
            params.put("image", mEncode(imagePath));
            params.put("userId", "123");
            return params;
        }
    };
    // 设置一个较大的超时的时间,因为上传文件比较耗费时间
    stringRequest.setRetryPolicy(new DefaultRetryPolicy(30000,
            DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
            DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
    mQueue.add(stringRequest);
}
6 这里用到的操作网络的jar包是volley,在onCreate()方法中将请求队列初始化:
mQueue = Volley.newRequestQueue(MainActivity.this);

在设置参数的时候:
params.put(“image”, mEncode(imagePath));

7 直接将Base64编码放进参数里,下面是mEncode()方法的具体实现:
// 1 将文件封装成inputStream
// 2 读取inputStream到byteArrayOutputStream中
// 3 通过 byteArrayOutputStream.toByteArray()把流转化成byte数组
// 4 将byte数组转换成Base64对象 并且返回
public String mEncode(String filename) {
    int bytesRead;
    byte[] bytes = null;
    byte[] buffer = new byte[8192]; // 缓冲区
    InputStream inputStream = null;
    ByteArrayOutputStream byteArrayOutputStream = null;
    try {
        inputStream = new FileInputStream(filename);
        byteArrayOutputStream = new ByteArrayOutputStream();
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            byteArrayOutputStream.write(buffer, 0, bytesRead);
        }
        bytes = byteArrayOutputStream.toByteArray();
    } catch (FileNotFoundException e1) {
        e1.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return Base64.encodeToString(bytes, Base64.DEFAULT);
}

通过

mQueue.add(stringRequest);
8 将请求加入队列之后,后台会发送请求并且等待结果,handler对于返回结果的处理:
private Handler handler = new Handler() {
    public void handleMessage(android.os.Message msg) {
        switch (msg.what) {
        case UPLOAD_SUCEESS:
            Toast.makeText(MainActivity.this, "upload success !",
                    Toast.LENGTH_SHORT).show();
            break;
        case UPLOAD_FAILURE:
            Toast.makeText(MainActivity.this, "upload failure !",
                    Toast.LENGTH_SHORT).show();
            break;
        default:
            break;
        }
    };
};

APP端的代码到这里结束,接下来是服务器端的代码

2 server端

1 接收文件的servlet:
private String result;

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
    // TODO Auto-generated method stub
    resp.setContentType("text/html;charset=UTF-8");
    resp.setCharacterEncoding("UTF-8");
    String imageBase64Code = req.getParameter("image");
    if (ImageHeler.convertCode2Image(imageBase64Code)) {
        result = "success";
    } else {
        result = "failure";
    }
    ServletOutputStream outputStream = resp.getOutputStream();
    outputStream.println(result);// 将结果输出给APP端
}

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
    this.doPost(req, resp);
}
2 ImageHelper的实现:
public class ImageHeler {

    public static boolean convertCode2Image(String imageBase64Code) {
        boolean isSuccess = false;
        try {
            // Converting a Base64 String into Image byte array
            byte[] imageByteArray = decodeImage(imageBase64Code);
            // Write a image byte array into file system
            FileOutputStream imageOutFile = new FileOutputStream(
                    "E:\\hardwork\\" + GTDateUtil.getCurrentStringDateAndTime()
                            + ".jpg");
            imageOutFile.write(imageByteArray);
            imageOutFile.close();
            isSuccess = true;
        } catch (FileNotFoundException e) {
            System.out.println("Image not found" + e);
        } catch (IOException ioe) {
            System.out.println("Exception while reading the Image " + ioe);
        }
        return isSuccess;
    }

    /**
     * Decodes the base64 string into byte array
     *
     * @param imageDataString
     *            - a {@link java.lang.String}
     * @return byte array
     */
    public static byte[] decodeImage(String imageDataString) {
        return Base64.decodeBase64(imageDataString);
    }
}
3 用日期来给图片命名:
dateAntTimeFormat = new SimpleDateFormat("yyyy-MM-dd-hh-mm-ss");
public static String getCurrentStringDateAndTime() {
    return dateAntTimeFormat.format(calendar.getTime());
}
4 web.xml的配置:
<servlet>
    <servlet-name>ImageReceiverServlet</servlet-name>
    <servlet-class>com.imagehelper.ImageReceiverServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>ImageReceiverServlet</servlet-name>
    <url-pattern>/ImageReceiverServlet</url-pattern>
</servlet-mapping>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值