Android中图片上传服务器(android端和服务端)

主要利用技术:

1)volley框架的改造

2)利用bitmap进行将图片进行压缩

3)利用base64将图片进行以字节流的形式进行输出


首先介绍一下volley框架:

点击打开链接


想要和后台数据交互,并以json的形式进行接受数据,就需要进行改造,下面两个类中,

一个是接受数组类型的json,以及就是接受普通类型的json,主要区别就是一个是JSONArray,一个是JSON

1)JSONArray

public class NormalPostRequestArray extends Request<JSONArray> {
    private Map<String,String> mMap;
    private Listener<JSONArray> mListener;

    public NormalPostRequestArray(String url, Listener<JSONArray> listener, ErrorListener errorListener, Map<String,String> map) {
        super(Request.Method.POST, url, errorListener);

        mListener = listener;
        mMap = map;
    }

    //mMap是已经按照前面的方式,设置了参数的实例
    @Override
    protected Map<String,String> getParams() throws AuthFailureError {
        return mMap;
    }

    //此处因为response返回值需要json数据,和JsonObjectRequest类一样即可
    @Override
    protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) {
        try {
            String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));

            return Response.success(new JSONArray(jsonString), HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JSONException je) {
            return Response.error(new ParseError(je));
        }
    }

    @Override
    protected void deliverResponse(JSONArray response) {
        mListener.onResponse(response);
    }
}
2)JSONOBejct

public class NormalPostRequest extends Request<JSONObject> {
    private Map<String,String> mMap;
    private Listener<JSONObject> mListener;

    public NormalPostRequest(String url, Listener<JSONObject> listener, ErrorListener errorListener, Map<String,String> map) {
        super(Request.Method.POST, url, errorListener);
        mListener = listener;
        mMap = map;
    }

    //mMap是已经按照前面的方式,设置了参数的实例
    @Override
    protected Map<String,String> getParams() throws AuthFailureError {
        return mMap;
    }

    //此处因为response返回值需要json数据,和JsonObjectRequest类一样即可
    @Override
    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
        try {
            String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));

            return Response.success(new JSONObject(jsonString), HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JSONException je) {
            return Response.error(new ParseError(je));
        }
    }

    @Override
    protected void deliverResponse(JSONObject response) {
        mListener.onResponse(response);
    }
}

利用上面两个类,来实现文件上传,并返回json数据

核心代码

public void  load(Bitmap photodata) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            //将bitmap一字节流输出 Bitmap.CompressFormat.PNG 压缩格式,100:压缩率,baos:字节流
            photodata.compress(Bitmap.CompressFormat.PNG, 100, baos);
            baos.close();
            byte[] buffer = baos.toByteArray();
            System.out.println("图片的大小:"+buffer.length);

            //将图片的字节流数据加密成base64字符输出
            String photo = Base64.encodeToString(buffer, 0, buffer.length,Base64.DEFAULT);
            String url = Url.url("/androidUser/imageUpload");
            RequestQueue queue = Volley.newRequestQueue(context);
            Map<String, String> map = new HashMap<>();
            map.put("photo", photo);
            NormalPostRequest normalPostRequest = new NormalPostRequest(url, jsonObjectProductListener, errorListener, map);
            queue.add(normalPostRequest);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


对于android端主要内容就是这些,主要利用volley框架实现网络传输,并且能够返回json数据即可,对于图片上传,只不过是将图片类型转换成字符流,然后传到后台,在在 后台进行解析。

好了 ,看一下后台代码的主要功能实现

后台我主要是利用springmvc进行的开发,当然,转换成struts是非常简单的,大家可以自己去练习

@ResponseBody
	@RequestMapping(value = "/imageUpload")
	public Object imageUpload(@RequestParam(value = "photo") String photo, @RequestParam(value = "phoneNumber") String phoneNumber, HttpServletRequest request, HttpServletResponse response) throws IllegalStateException, IOException {
		User user = userService.checkPhone(phoneNumber);
		Map<String, Object> map = new HashMap<>();
		try {
			request.setCharacterEncoding("utf-8");
			response.setCharacterEncoding("utf-8");
			response.setContentType("text/html");
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {

			// 对base64数据进行解码 生成 字节数组,不能直接用Base64.decode();进行解密
			byte[] photoimg = new BASE64Decoder().decodeBuffer(photo);
			for (int i = 0; i < photoimg.length; ++i) {
				if (photoimg[i] < 0) {
					// 调整异常数据
					photoimg[i] += 256;
				}
			}
			// 获取项目运行路径
			String pathRoot = request.getSession().getServletContext().getRealPath("");
			// 生成uuid作为文件名称
			String uuid = UUID.randomUUID().toString().replaceAll("-", "");

			String path = "/images/" + uuid + "head.png";
			// byte[] photoimg =
			// Base64.decode(photo);//此处不能用Base64.decode()方法解密,我调试时用此方法每次解密出的数据都比原数据大
			// 所以用上面的函数进行解密,在网上直接拷贝的,花了好几个小时才找到这个错误(菜鸟不容易啊)
			System.out.println("图片的大小:" + photoimg.length);
			File file = new File(pathRoot + path);
			if (!file.exists()) {
				file.createNewFile();
			}
			FileOutputStream out = new FileOutputStream(file);
			out.write(photoimg);
			out.flush();
			out.close();
			//设置数据
			user.setHeadPortrait(path);
			user.setUpdateTime(new Date());
			System.out.println(user);
			if (userService.update(user) != 0) {
				map.put("updateImage", "success");
				map.put("imageUrl", path);
			} else {
				map.put("updateImage", "filed");
			}

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return map;
	}


其中@ResponseBody主要为了让其直接返回数据,即json格式的

@RequestMappping主要是客户端访问服务器端的地址

@RequestParam主要是传递的参数

android端源码:点击打开链接

服务端源码:点击打开链接


  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值