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目前就这样,有啥子问题及时联系,虽然帮不了什么,,,,