OkHttpUtils.post()上传文件(Android前端上传与服务器后台接收)
2020-04-22 04:19
1146 查看
Android端
1、首先需要用到的包,现在build.gradle(app)里边添加依赖
implementation 'com.github.xxl6097:okhttputils:2.4.1' //或者implementation 'com.zhy:okhttputils:2.6.2' //此处用的第一种
废话不多说,直接上代码
2、上传代码multiFileUpload方法
public void multiFileUpload(ArrayList<Image> image) throws UnsupportedEncodingException { 为json字符串并设置编码 .content(new Gson().toJson(new User("zhy", "123"))) //用Gson将User对象转化为Json字符串的形式作为content .build() .execute(new MyStringCallback()); } mDialog = new SpotsDialog(SendFleaActivity.this,"上传中..."); final String url = AppConstant.uploadflea; Map<String, String> headers = new HashMap<>(); headers.put("Content-Disposition", "form-data;filename=enctype"); PostFormBuilder build = OkHttpUtils.post(); for (int i=0;i<image.size();i++){ //判断文件合法 if(!new File(image.get(i).getPath()).exists()){ Toast.makeText(SendFleaActivity.this,"文件不存在,请修改路径",Toast.LENGTH_LONG).show(); return; } //压缩图片 获取到file格式 File file = new File(BitmapUtil.compressImage(image.get(i).getPath())); //生成随即文件名,添加file,name是用户id build.addFile(getuserid(getApplicationContext()), getopenid(this)+ Universal.generateRandomFilename() +"01.png", file); } build.addHeader("head", URLEncoder.encode(getBean(), "UTF-8")) .url(url) .build() .execute(new StringCallback() { @Override public void onError(Call call, Exception e) { mDialog.dismiss(); Toast.makeText(SendFleaActivity.this, "服务器连接失败",Toast.LENGTH_LONG).show(); e.printStackTrace(); } @Override public void onResponse(Call call, String s) { mDialog.dismiss(); try { Toast.makeText(SendFleaActivity.this, URLDecoder.decode(s, "UTF-8"),Toast.LENGTH_LONG).show(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } // if (s.equals("0")){ // Toast.makeText(SendFleaActivity.this, s+"发布成功",Toast.LENGTH_LONG).show(); // }else { // Toast.makeText(SendFleaActivity.this,s+"发布失败",Toast.LENGTH_LONG).show(); // // } } @Override public void onBefore(Request request) { super.onBefore(request); mDialog.show(); } }); }
3、代码注释较少,里边还用到了其他类的方法,比如给文件命名的随机文件名,就用到了随机函数,还是放一下generateRandomFilename()方法
public static String generateRandomFilename(){ String RandomFilename = ""; Random rand = new Random();//生成随机数 int random = rand.nextInt(); Calendar calCurrent = Calendar.getInstance(); int intDay = calCurrent.get(Calendar.DATE); int intMonth = calCurrent.get(Calendar.MONTH) + 1; int intYear = calCurrent.get(Calendar.YEAR); String now = String.valueOf(intYear) + "_" + String.valueOf(intMonth) + "_" + String.valueOf(intDay) + "_"; RandomFilename = "_"+now + String.valueOf(random > 0 ? random : ( -1) * random); return RandomFilename; }
4、其中的Image类
public class Image implements Parcelable { private int id; private String path; private String thumbPath; private boolean isSelect; private String folderName; private String name; private long date; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } public String getThumbPath() { return thumbPath; } public void setThumbPath(String thumbPath) { this.thumbPath = thumbPath; } public boolean isSelect() { return isSelect; } public void setSelect(boolean select) { isSelect = select; } public String getFolderName() { return folderName; } public void setFolderName(String folderName) { this.folderName = folderName; } public String getName() { return name; } public void setName(String name) { this.name = name; } public long getDate() { return date; } public void setDate(long date) { this.date = date; } @Override public boolean equals(Object o) { if (o instanceof Image) { return this.path.equals(((Image) o).getPath()); } return false; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(this.id); dest.writeString(this.path); dest.writeString(this.thumbPath); dest.writeByte(this.isSelect ? (byte) 1 : (byte) 0); dest.writeString(this.folderName); dest.writeString(this.name); dest.writeLong(this.date); } public Image() { } protected Image(Parcel in) { this.id = in.readInt(); this.path = in.readString(); this.thumbPath = in.readString(); this.isSelect = in.readByte() != 0; this.folderName = in.readString(); this.name = in.readString(); this.date = in.readLong(); } public static final Creator<Image> CREATOR = new Creator<Image>() { @Override public Image createFromParcel(Parcel source) { return new Image(source); } @Override public Image[] newArray(int size) { return new Image[size]; } }; }
5、压缩图片方法类BitmapUtil
public class BitmapUtil { public static Bitmap calculateInSampleSize(String imagePath) { // 设置参数 BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; // 只获取图片的大小信息,而不是将整张图片载入在内存中,避免内存溢出 // 输出图像数据 //orginBitmap=: size: 14745600 width: 1440 heigth:2560 // Bitmap originBitmap = BitmapFactory.decodeFile(imagePath, options); // Log.w("originBitmap=", "size: " + originBitmap.getByteCount() + // " width: " + originBitmap.getWidth() + " height:" + originBitmap.getHeight()); int height = options.outHeight; int width = options.outWidth; int inSampleSize = 2; // 默认像素压缩比例,压缩为原图的1/2 int minLen = Math.min(height, width); // 原图的最小边长 if (minLen > 100) { // 如果原始图像的最小边长大于100dp(此处单位我认为是dp,而非px) float ratio = (float) minLen / 100.0f; // 计算像素压缩比例 inSampleSize = (int) ratio; } options.inSampleSize = inSampleSize; // 设置为刚才计算的压缩比例 options.inJustDecodeBounds = false; // 计算好压缩比例后,这次可以去加载原图了 Bitmap bm = BitmapFactory.decodeFile(imagePath, options); // 解码文件 //size: 74256 width: 102 heigth:182 Log.w("bm=", "size: " + bm.getByteCount() + " width: " + bm.getWidth() + " heigth:" + bm.getHeight()); // 输出图像数据 return bm; } /** * @param reqWidth 要求的宽 * @param reqHeight 要求的高 */ public static Bitmap decodeSampledBitmapFromResource(String path, int reqWidth, int reqHeight) { //Options 只保存图片尺寸大小,不保存图片到内存 BitmapFactory.Options options = new BitmapFactory.Options(); // 设置该属性为true,不加载图片到内存,只返回图片的宽高到options中。 // 第一次解析将inJustDecodeBounds设置为true,来获取图片大小 options.inJustDecodeBounds = true; //先加载图片 BitmapFactory.decodeFile(path, options); options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // 重新设置该属性为false,加载图片返回 // 使用获取到的inSampleSize值再次解析图片 options.inJustDecodeBounds = false; return BitmapFactory.decodeFile(path, options); } private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { int width = options.outWidth; int height = options.outHeight; int inSampleSize = 1; int widthRatio = Math.round((float) width / (float) reqWidth); int heightRatio = Math.round((float) height / (float) reqHeight); inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; return inSampleSize; } private static String PHOTO_FILE_NAME = "PMSManagerPhoto"; /** * 获取图片的旋转角度 * * @param filePath * @return */ public static int getRotateAngle(String filePath) { int rotate_angle = 0; try { ExifInterface exifInterface = new ExifInterface(filePath); int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_90: rotate_angle = 90; break; case ExifInterface.ORIENTATION_ROTATE_180: rotate_angle = 180; break; case ExifInterface.ORIENTATION_ROTATE_270: rotate_angle = 270; break; } } catch (IOException e) { e.printStackTrace(); } return rotate_angle; } /** * 旋转图片角度 * * @param angle * @param bitmap * @return */ public static Bitmap setRotateAngle(int angle, Bitmap bitmap) { if (bitmap != null) { Matrix m = new Matrix(); m.postRotate(angle); bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true); return bitmap; } return bitmap; } //转换为圆形状的bitmap public static Bitmap createCircleImage(Bitmap source) { int length = source.getWidth() < source.getHeight() ? source.getWidth() : source.getHeight(); Paint paint = new Paint(); paint.setAntiAlias(true); Bitmap target = Bitmap.createBitmap(length, length, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(target); canvas.drawCircle(length / 2, length / 2, length / 2, paint); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); canvas.drawBitmap(source, 0, 0, paint); return target; } /** * 图片压缩-质量压缩 * * @param filePath 源图片路径 * @return 压缩后的路径 */ public static String compressImage(String filePath) { //原文件 File oldFile = new File(filePath); //压缩文件路径 照片路径/ String targetPath = oldFile.getPath(); int quality = 50;//压缩比例0-100 Bitmap bm = getSmallBitmap(filePath);//获取一定尺寸的图片 int degree = getRotateAngle(filePath);//获取相片拍摄角度 if (degree != 0) {//旋转照片角度,防止头像横着显示 bm = setRotateAngle(degree,bm); } File outputFile = new File(targetPath); try { if (!outputFile.exists()) { outputFile.getParentFile().mkdirs(); //outputFile.createNewFile(); } else { outputFile.delete(); } FileOutputStream out = new FileOutputStream(outputFile); bm.compress(Bitmap.CompressFormat.JPEG, quality, out); out.close(); } catch (Exception e) { e.printStackTrace(); return filePath; } return outputFile.getPath(); } /** * 根据路径获得图片信息并按比例压缩,返回bitmap */ public static Bitmap getSmallBitmap(String filePath) { final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true;//只解析图片边沿,获取宽高 BitmapFactory.decodeFile(filePath, options); // 计算缩放比 options.inSampleSize = calculateInSampleSize(options, 480, 800); // 完整解析图片返回bitmap options.inJustDecodeBounds = false; return BitmapFactory.decodeFile(filePath, options); } }
6、在文件上传的multiFileUpload里边,下边这句话是post一个头文件,这里我将我需要上传的文本信息放在这里,也可以放在param里边 但是我发现这样读取不到,很烦,没找到原因,暂且放到头文件,getBean()方法就是我的文本信息,此处自行修改,不需要的话直接删除
build.addHeader("head", URLEncoder.encode(getBean(), "UTF-8"))
然后好像就没有别的东西了,发现缺少什么代码请及时联系
那么此处就是所有的Android的东西了
服务端代码
照样废话不多说,直接上代码//额 咋还不让复制了,复制就崩,不知道是不是csdn的问题还是我的问题
/** * Servlet implementation class UploadServlet */ @WebServlet(description = "flea商品发布",urlPatterns = {"/UploadServlet"}) public class UploadServlet extends HttpServlet { private static final long serialVersionUID = 1L; // 上传文件存储目录 private static final String UPLOAD_DIRECTORY = "upload"; // 上传配置 private static final int MEMORY_THRESHOLD = 1024 * 1024 * 3; // 3MB private static final int MAX_FILE_SIZE = 1024 * 1024 * 40; // 40MB private static final int MAX_REQUEST_SIZE = 1024 * 1024 * 50; // 50MB private static String SUCCESS = null; // 50MB private static String FAIL = null; static { try { SUCCESS = URLEncoder.encode("发布成功", "UTF-8"); FAIL = URLEncoder.encode("发布失败", "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } /** * 上传数据及保存文件 */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); // 检测是否为多媒体上传 if (!ServletFileUpload.isMultipartContent(request)) { // 如果不是则停止 PrintWriter writer = response.getWriter(); writer.println("Error: 表单必须包含 enctype=multipart/form-data"); writer.flush(); return; } // System.out.println("111"+getparam(request)); // 这一句的话 就是获取头文件的 String goods = URLDecoder.decode(getHeadersInfo(request).getOrDefault("head","失败"), "UTF-8"); // System.out.println(goods); saveImage(request,response, DBUtil.Insert_goods(goods)); // response.getWriter().println(back); // 跳转到 message.jsp // request.getServletContext().getRequestDispatcher("/message.jsp").forward( // request, response); } public static void saveImage(HttpServletRequest request,HttpServletResponse response,int goodid) throws IOException { // 配置上传参数 DiskFileItemFactory factory = new DiskFileItemFactory(); // 设置内存临界值 - 超过后将产生临时文件并存储于临时目录中 factory.setSizeThreshold(MEMORY_THRESHOLD); // 设置临时存储目录 factory.setRepository(new File(System.getProperty("java.io.tmpdir"))); ServletFileUpload upload = new ServletFileUpload(factory); // 设置最大文件上传值 upload.setFileSizeMax(MAX_FILE_SIZE); // 设置最大请求值 (包含文件和表单数据) upload.setSizeMax(MAX_REQUEST_SIZE); // 中文处理 upload.setHeaderEncoding("UTF-8"); // Request.QueryString["name"]; // 构造临时路径来存储上传的文件 // 这个路径相对当前应用的目录 String uploadPath = request.getServletContext().getRealPath("./") + File.separator + UPLOAD_DIRECTORY; // 如果目录不存在则创建 File uploadDir = new File(uploadPath); if (!uploadDir.exists()) { uploadDir.mkdir(); } try { Enumeration<String> enumeration = request.getParameterNames(); while(enumeration.hasMoreElements()){ String name = enumeration.nextElement(); String value = new String(request.getParameter(name).getBytes("iso8859-1"),"utf-8"); System.out.println(name+" : "+value);} // 解析请求的内容提取文件数据 @SuppressWarnings("unchecked") List<FileItem> formItems = upload.parseRequest(request); if (formItems != null && formItems.size() > 0) { int i = 0; // 迭代表单数据 for (FileItem item : formItems) { // System.out.println(item.getFieldName()); // 处理不在表单中的字段 if (!item.isFormField()) { String fileName = new File(item.getName()).getName(); // System.out.println(item.getName()+"++++++++++++"); //将图片信息保存到数据库 if (goodid!=0) { if (i==0){ DBUtil.Insert_one(DBUtil.TAB_flea_goods,goodid,"url",DBUtil.THIS_URL+item.getName()); i=2; } DBUtil.inser_image(DBUtil.TAB_flea_pic_url, goodid, item.getName()); String filePath = uploadPath + File.separator + fileName; File storeFile = new File(filePath); // 在控制台输出文件的上传路径 System.out.println(filePath); // 保存文件到硬盘 item.write(storeFile); // request.setAttribute("message", // "文件上传成功!"); } // else { // response.getWriter().println(FAIL); //// request.setAttribute("message", //// "错误信息: " + "发布失败"); // } } }response.getWriter().println(SUCCESS); } } catch (Exception ex) { try { response.getWriter().println(FAIL); }catch (Exception e){ response.getWriter().close(); } ex.printStackTrace(); // request.setAttribute("message", // "错误信息: " + ex.getMessage()); } } * * @param request * @return */ public static Map<String, String> getHeadersInfo(HttpServletRequest request) { Map<String, String> map = new HashMap<String, String>(); Enumeration headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()) { String key = (String) headerNames.nextElement(); String value = request.getHeader(key); // System.out.println(key + ":" + value); map.put(key, value); } return map; } }
其实这里只需要看saveImage方法就行,这就是保存图片的,剩下的都是我在数据库存储的过程,删掉即可,需要的可以参考,emm目前就这样,有啥子问题及时联系,虽然帮不了什么,,,,
- 点赞
- 收藏
- 分享
- 文章举报
相关文章推荐
- Django后台获取前端post上传的文件
- 利用HTTP协议实现Android文件上传至WEB服务器,采用PHP接收文件(参考网上自己实现)
- Android上传文件到Web服务器,PHP接收文件(一)
- Android端通过Okhttp与PHP服务器进行交互并实现文件上传下载(一)
- okhttp post请求上传服务器File文件
- android手机客户端上传文件,java servlet服务器端接收并保存到服务器
- android原生POST、httpClient4.X实现向PHP服务器上传文件
- android 选择视频文件 上传到后台服务器
- Android端通过Okhttp与PHP服务器进行交互并实现文件上传下载(二)
- android okHttp3 post上传图片给服务器
- android向服务器上传multipart/form-data文件(upload using multipart post using httpclient in android)
- Android上传文件到Web服务器,PHP接收文件(2)
- Android上传文件到Web服务器,PHP接收文件
- Android上传文件到Web服务器,PHP接收文件(二)
- Android上传文件到Web服务器,PHP接收文件(二)
- 【Android】Android客户端使用okhttp上传文件php服务器
- Android OkHttp Post上传文件并且携带参数
- Android OkhttpUtils上传图片和文件
- Maven项目:Spring MVC + Ajax + Json + RequestBody:POST后台服务器接收前端JSON数据并注解到POJO内