android文件上传

7 篇文章 0 订阅
3 篇文章 0 订阅

最近写的app项目涉及到用户更换头像,就涉及到文件上传,在网上找了很多教程,最后选了一个看起来比较接地气的,伪造post文件上传

原博客地址:https://blog.csdn.net/anan890624/article/details/52510299

博客好像并没有给出服务器端的代码吗,因为是post提交文件上传,正好和我之前做的基于表单的文件上传吻合,服务器端参考的是http://www.360doc.com/content/14/0506/15/7532272_375213559.shtml这篇文章的代码。

自己写的服务器端代码:

package com.servlet;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.tomcat.util.http.fileupload.FileItem;
import org.apache.tomcat.util.http.fileupload.RequestContext;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
import org.apache.tomcat.util.http.fileupload.servlet.ServletRequestContext;

import com.bean.Organize;
import com.service.OrganizeService;
import com.service.UserService;
import com.utils.Tool;


@WebServlet("/UploadServlet")
public class UploadServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;


	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		DiskFileItemFactory factory = new DiskFileItemFactory();
		
		String path = null;
		
		path = this.getServletContext().getRealPath("/upload");
		System.out.println(path);
		
		ServletFileUpload servletFileUpload = new ServletFileUpload();
		servletFileUpload.setFileItemFactory(factory);
		servletFileUpload.setFileSizeMax(1000*1000);
		servletFileUpload.setHeaderEncoding("UTF-8"); 
		String id = request.getHeader("id");
		System.out.println("id="+id);
		
		
        if(!ServletFileUpload.isMultipartContent(request)){
            return;
        }
		try {
			List<FileItem> fileItems = servletFileUpload.parseRequest(new ServletRequestContext(request));
			FileItem fileItem = null;
			Iterator<FileItem> it = fileItems.iterator();
			while(it.hasNext()) {
				FileItem item = it.next();
				if(item.isFormField()) {
					String fieldName = item.getFieldName();
					String value = item.getString("UTF-8");
					System.out.println("name="+fieldName+",value="+value);
				}else {
					fileItem = item;
					File uploadDir = new File(path);
					if(!uploadDir.exists()) {
						uploadDir.mkdirs();
					}
					path = path + "/" +(int)(Math.random()*10000);
					File file = new File(path+".jpg");
					path = file.getAbsolutePath();
					

					InputStream in = fileItem.getInputStream();
					
					OutputStream out = new FileOutputStream(file);
					
					byte buffer[] = new byte[1024];
					int len=0;
					while((len=in.read(buffer))>0) {
						out.write(buffer, 0, len);
					}
					
					in.close();
					out.close();
				}
			}
			
			//更改地址为网络地址
			int begin=path.indexOf("ClubServer");
			int last=path.length();
			path = Tool.ip+path.substring(begin,last);
			System.out.println(path);
			
			//保存上传的图片地址
			if(id.startsWith("user:")) {
				id = id.substring(5);
				System.out.println(id);
				UserService us = new UserService();
				boolean flag = us.updateHeadImg(id,path);
				
				response.getWriter().write(flag?path:"0");
			}
			if(id.startsWith("org:")) {
				id = id.substring(4);
				id = new String(id.getBytes(Tool.getEncoding(id)),"UTF-8");
				System.out.println(id+":"+Tool.getEncoding(id));
				OrganizeService os = new OrganizeService();
				boolean flag = os.updateOrganizeImg(id,path);
				response.getWriter().write(flag?path:"0");
				
			}
			
			
		} catch (Exception e) {
			
			e.printStackTrace();
		}
	}


	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

里面除了文件上传外,加了一些将图片地址和其他信息(user_id等)存入数据库的代码。存的时候地址记得转换成网络地址。

然后就是android端上传代码:

package com.example.mypplication;

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import bean.User;
import utils.Tool;
import utils.UserDataOp;

public class ChangeHeadImgActivity extends Activity {

    private final int OPEN_ALBUM_FLAG = 1023;   //打开相册
    private final int OPEN_CAMERA_FLAG = 1024;      //打开相机
    private ImageView mShowIV;
    private String mSaveDir;// 拍照存放的文件夹名字
    private String mFileName;// 拍照存放的文件的名字
    private String user_id;
    private TextView tv_info;
    private String url;
    private HttpClient httpClient;
    private UserDataOp ud;
    private String img_path;
    private Bitmap bitmap;

    // 要上传的本地文件路径
    private String uploadFile;

    // 上传到服务器的指定位置
    private String actionUrl = Tool.ip+Tool.webName+"UploadServlet";

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.changeheadimg);
        mShowIV = (ImageView) findViewById(R.id.iv_head);
        tv_info = (TextView) findViewById(R.id.tv_info);

    }

    public void changeimg(View v) {

        uploadFile = this.getFilesDir().getAbsolutePath();
        Intent intent;

        intent = new Intent(Intent.ACTION_PICK,
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        intent.setType("image/*");
        startActivityForResult(intent, OPEN_ALBUM_FLAG);

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        File file;
        Bitmap bitmap;
        OutputStream outputStream;

        if (resultCode == RESULT_OK) {
            Uri originUri = data.getData();
            String[] proj = { MediaStore.Images.Media.DATA };

            Cursor cursor = managedQuery(originUri, proj, null, null, null);
            int columnIndex = cursor
                    .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            String path = cursor.getString(columnIndex);

            uploadFile = path;
            mShowIV.setImageURI(originUri);

            bitmap = getCompressBitmap(path);


            //android6.0需动态获取外部存储访问权限
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && this.checkSelfPermission(
                    Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {

                this.requestPermissions(new String[]{
                        Manifest.permission.READ_EXTERNAL_STORAGE,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE
                }, 1);
            }

//            mShowIV.setImageBitmap(bitmap);//将选中的图片展示出来

            /* 创建一个新的文件,存放压缩过的bitmap,用于发送给服务器 */
            String saveDir = uploadFile;
            File dir = new File(saveDir);
            if (!dir.exists()) {
                dir.mkdir();
            }
            // 创建一个临时文件用来存放图片
            String fileName = "tmp.jpg";
            file = new File(this.getFilesDir().getAbsolutePath(), fileName);
            if (file.exists()) {
                file.delete();
            }
            try {
                file.createNewFile();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            try {

                file.createNewFile();
                outputStream = new FileOutputStream(file);
                // //将bitmap写入file
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
                /* 到这里已经成功将bitmap写入file了,此时可以将file或者流发送给服务器了 */

            } catch (Exception e) {
                e.printStackTrace();
            }

            uploadFile = file.getAbsolutePath();
//            tv_info.setText(path);
            new Thread(new UploadThread()).start();

        }

    }



    public class UploadThread implements Runnable {
        @Override
        public void run() {

            upload();
        }

    }

    public void upload() {
        String path="";

        String end = "\r\n";
        String twoHyphens = "--";
        String boundary = "******";
        URL url;
        try {
            url = new URL(actionUrl);
            HttpURLConnection httpURLConnection = (HttpURLConnection) url
                    .openConnection();
            httpURLConnection.setChunkedStreamingMode(128 * 1024);// 128K
            // 允许输入输出流
            httpURLConnection.setDoInput(true);
            httpURLConnection.setDoOutput(true);
            httpURLConnection.setUseCaches(false);
            // 使用POST方法
            httpURLConnection.setRequestMethod("POST");
            httpURLConnection.setRequestProperty("Connection", "Keep-Alive");
            httpURLConnection.setRequestProperty("Charset", "UTF-8");
            httpURLConnection.setRequestProperty("Content-Type",
                    "multipart/form-data;boundary=" + boundary);

            //将id(用户id格式     user:+id  社团id格式     org:+id)传到服务器
            httpURLConnection.setRequestProperty("id", user_id);

            DataOutputStream dos = new DataOutputStream(
                    httpURLConnection.getOutputStream());
            dos.writeBytes(twoHyphens + boundary + end);
            dos.writeBytes("Content-Disposition: form-data; name=\"uploadfile\"; filename=\""
                    + uploadFile.substring(uploadFile.lastIndexOf("/") + 1)
                    + "\"" + end);
            dos.writeBytes(end);

            FileInputStream fis = new FileInputStream(uploadFile);
            byte[] buffer = new byte[8192]; // 8k
            int count = 0;
            // 读取文件
            while ((count = fis.read(buffer)) != -1) {
                dos.write(buffer, 0, count);
            }
            fis.close();
            dos.writeBytes(end);
            dos.writeBytes(twoHyphens + boundary + twoHyphens + end);
            dos.flush();
            InputStream is = httpURLConnection.getInputStream();
            InputStreamReader isr = new InputStreamReader(is, "utf-8");
            BufferedReader br = new BufferedReader(isr);
            String result = br.readLine();
            Log.i("tag", result);
            dos.close();
            is.close();

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

    }


    public Bitmap getCompressBitmap(String path) {
        int BASE_SIZE = 400;// 需要压缩到的最小宽高
        Bitmap bitmap;
        BitmapFactory.Options options = new BitmapFactory.Options();
        // 只计算几何尺寸不返回bitmap,这样不会占用内存
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);

        int width = options.outWidth;
        int height = options.outHeight;
        int min = width < height ? width : height;
        int rate = min / BASE_SIZE;// 压缩倍率
        if (rate < 1)
            rate = 1;
        options.inSampleSize = rate;
        options.inJustDecodeBounds = false;
        bitmap = BitmapFactory.decodeFile(path, options);
        return bitmap;
    }




}

直接全粘过来,最初只写了upload()方法,在模拟器上创建一个文件顺利传到了服务器,写完发现,真机没法直接创建文件...完成图片上传还得调用相册程序,这里参考了https://blog.csdn.net/nnmmbb/article/details/16949349,调用相机程序代码我就删了,觉得太麻烦,只做了调用相册程序。同时它还提供了getCompressBitmap()方法压缩图片,可以自己修改要压缩的尺寸,怎么突然就自动换字体了。。。然后androidmanifest.xml一定要记得添加网络权限和外部存储读写权限,我刚开始就忘了加,还在那一直测,奇怪他没反应。

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

好不容易做好这一切,用eclipse API19完美传送图片到服务器,但当我把代码转到android studio使用的API28时,又传不了了(摊手),弄了好久,网上查发现,api>23要手动获取读写外部存储权限,wtf,于是网上找了代码,加进去(上边已经加进去了),才算是终于完成了,心好累。。。

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && this.checkSelfPermission(
                    Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {

                this.requestPermissions(new String[]{
                        Manifest.permission.READ_EXTERNAL_STORAGE,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE
                }, 1);
            }

最后还有,要将用户信息连带图片一起传到服务器,才能在数据库将图片与用户匹配

httpURLConnection.setRequestProperty("id", user_id);

因为http协议api什么的还不太熟,我是直接给他加到请求头里了。。。

最后就是不知道为什么Tomcat服务器老是自动删除我创建的uolpad文件夹,哎~

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值