安卓端同时上传文字和图片到服务器,服务器接收并处理

更简单的方法
请看这个安卓端同时上传图片和文字,服务器接收并处理(二))

之前看了很多博客,找到的无非就是要么只上传json,要么只上传图片。碰了许多的壁,因此我这里写一下自己已经测试成功的代码。


Android端使用Post上传图片和json代码

注意事项:

  1. 根据前端表单上传可知,我们需要将form的enctype设置成为multipart/form-data才可以完成传文件和传值。
  2. 根据前端表单上传可知,前端的input标签是需要写一个name的,这样后台才能根据name获取值。
  3. 一般安卓端上传json或者文件不会向前端传值一样,安卓上传的时候一般没有name这个key的.因此,服务器后台就不可能根据参数名来获取相应的值了。只能通过request对象获取InputStream来进行相应的操作了(或者使用Spring的注解 @RequestPBody)。但是由于文字和图片同时上传,使用这种方式处理起来可能略显麻烦。

因此我才用的方式是,在安卓端直接构造http的报文的方式,模拟出前端向后台传值传文件的操作,然后再向服务器发送请求。
Android代码(非真正Android代码,仅仅用来测试,并未写成app):
其中Json的name是 data
图片流的name是 file

import net.sf.json.JSONObject;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


public class UploadTest {

    /**
     *
     * @param args 此方法主要写上传的json数据以及图片文件的地址
     * @throws UnsupportedEncodingException
     */
    public static void main(String[] args) throws UnsupportedEncodingException {
        String url = "http://localhost:8080/upload";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("upload_name", "武汉光谷渍水");
        jsonObject.put("upload_type", "公众");
        jsonObject.put("longitude", 132.2);
        jsonObject.put("latitude", 68.58);
        jsonObject.put("upload_address", "武汉光谷");
        jsonObject.put("upload_time", new Date().getTime());
        jsonObject.put("upload_description", "描述");
        jsonObject.put("approval_status", 2);
        Map<String, String> params = new HashMap<>();
        //设置编码类型为utf-8
        params.put("data", String.valueOf(jsonObject));
        String filePath = "/home/coder/workspace/baidu.png";
        post(url, params, filePath);
    }


    /**
     * @param actionUrl 上传的地址
     * @param params    上传的键值对参数
     * @param filePath  上传的图片路径
     */
    static void post(String actionUrl, Map<String, String> params, String filePath) {

        //前面设置报头不需要更改
        try {
            String BOUNDARY = "--------------et567z"; //数据分隔线
            String MULTIPART_FORM_DATA = "Multipart/form-data";
            URL url = new URL(actionUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setDoInput(true);//允许输入
            conn.setDoOutput(true);//允许输出
            conn.setUseCaches(false);//不使用Cache
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("Charset", "UTF-8");
            conn.setRequestProperty("Content-Type", MULTIPART_FORM_DATA + ";boundary=" + BOUNDARY);

            //获取map对象里面的数据,并转化为string
            StringBuilder sb = new StringBuilder();
            System.out.println("上传名称:"+params.get("data"));
            //上传的表单参数部分,不需要更改
            for (Map.Entry<String, String> entry : params.entrySet()) {//构建表单字段内容
                sb.append("--");
                sb.append(BOUNDARY);
                sb.append("\r\n");
                sb.append("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"\r\n\r\n");
                sb.append(entry.getValue());
                sb.append("\r\n");
            }
            System.out.println(sb.toString());


            //上传图片部分
            DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());
            outStream.write(sb.toString().getBytes());//发送表单字段数据
            //调用自定义方法获取图片文件的byte数组
            byte[] content = readFileImage(filePath);
            //再次设置报头信息
            StringBuilder split = new StringBuilder();
            split.append("--");
            split.append(BOUNDARY);
            split.append("\r\n");


            //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!非常重要
            //此处将图片的name设置为file ,filename不做限制,不需要管
            split.append("Content-Disposition: form-data;name=\"file\";filename=\"temp.jpg\"\r\n");
            //这里的Content-Type非常重要,一定要是图片的格式,例如image/jpeg或者image/jpg
            //服务器端对根据图片结尾进行判断图片格式到底是什么,因此务必保证这里类型正确
            split.append("Content-Type: image/png\r\n\r\n");
            outStream.write(split.toString().getBytes());
            outStream.write(content, 0, content.length);
            outStream.write("\r\n".getBytes());
            byte[] end_data = ("--" + BOUNDARY + "--\r\n").getBytes();//数据结束标志
            outStream.write(end_data);
            outStream.flush();




            //返回状态判断
            int cah = conn.getResponseCode();
            //            if (cah != 200) throw new RuntimeException("请求url失败:"+cah);
            if (cah == 200)//如果发布成功则提示成功
            {
                System.out.println("上传成功");
            } else if (cah == 400) {
                System.out.println("400错误");
            } else {
                throw new RuntimeException("请求url失败:" + cah);
            }

            outStream.close();
            conn.disconnect();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static byte[] readFileImage(String filePath) throws IOException {

        BufferedInputStream bufferedInputStream = new BufferedInputStream(
                new FileInputStream(filePath));
        int len = bufferedInputStream.available();
        byte[] bytes = new byte[len];
        int r = bufferedInputStream.read(bytes);
        if (len != r) {
            bytes = null;
            throw new IOException("读取文件不正确");
        }
        bufferedInputStream.close();
        return bytes;
    }

}

服务器后台接受请求的处理代码

使用spring boot框架,采用注解形式获取参数

@PostMapping(value = "upload")
    @ResponseBody
    public String uploadAccident(@RequestParam(value = "data")String data,@RequestParam(value = "file")MultipartFile file) throws IOException {
        System.out.println(data);
        //解析数据
        Upload upload = null;
        logger.info("json为:"+data);
        JSONObject jsonObject = JSONObject.fromObject(data);
        String uploadName = jsonObject.getString("upload_name");
        String uploadType = jsonObject.getString("upload_type");
        float longitude = (float) jsonObject.getDouble("longitude");
        float latitude = (float) jsonObject.getDouble("latitude");
        String uploadAddress = jsonObject.getString("upload_address");
        Date uploadTime = new Date(Long.parseLong(jsonObject.getString("upload_time")));
        String uploadDescription = jsonObject.getString("upload_description");
        int approvalStatus = jsonObject.getInt("approval_status");

        logger.info("文件的大小:"+file.getSize());
        logger.info("文件的类型:"+file.getContentType());
        logger.info("文件的名称:"+file.getName());
        String [] contentType = file.getContentType().split("/");
        if (file.isEmpty()){
            System.out.println("文件空");
        }
        //文件不空
        if (!file.isEmpty()){
            File dir = new File(UploadFileUtil.IMAGE_DIR);
            //如果文件夹不存在,创建目录
            if (!dir.exists()){
                dir.mkdirs();
            }
            //设置上传的图片名称为日期+图片类型
            Date date = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            String fileName = sdf.format(date);
            byte [] imageBytes = file.getBytes();
            String filePath = UploadFileUtil.IMAGE_DIR + fileName +"." +contentType[1];
            File imageFile = new File(filePath);
            if (!imageFile.exists()){
                imageFile.createNewFile();
            }
            FileImageOutputStream imageOutput = new FileImageOutputStream(imageFile);
            //将bytes数组写成文件
            imageOutput.write(imageBytes,0,imageBytes.length);
            imageOutput.close();

            //构造一个upload上传实体
            upload = new Upload(uploadName,uploadType,filePath,longitude,latitude,uploadAddress,uploadTime,uploadDescription,approvalStatus);
        }

        try{
        //将实体信息存入数据库
//            uploadDao.save(upload);
        } catch (Exception e){
            e.printStackTrace();
            return "{\"result\":\"false\",\"msg\":"+e.getMessage()+"}";
        }
        return "{\"result\":\"true\",\"msg\":\"success\"}";
    }

这个接口写了很长时间,就卡在怎么接受参数的问题上了,如果有更好的方法,欢迎大家在下面回复。~

  • 8
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,对于这个问题,我可以给你提供一些思路和代码示例。 首先,你需要使用OkHttpClient发送POST请求将图片上传到Flask服务器。以下是一个简单的上传图片的示例代码: ```java OkHttpClient client = new OkHttpClient(); // 上传文件 File file = new File("/path/to/image.jpg"); RequestBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("file", "image.jpg", RequestBody.create(MediaType.parse("image/jpeg"), file)) .build(); // 发送请求 Request request = new Request.Builder() .url("http://yourflaskserver.com/upload") .post(requestBody) .build(); Response response = client.newCall(request).execute(); ``` 在Flask服务器,你可以使用Flask的`request`模块接收上传的文件,并保存到指定的目录中。以下是一个简单的保存图片的示例代码: ```python from flask import Flask, request import os app = Flask(__name__) @app.route('/upload', methods=['POST']) def upload(): file = request.files['file'] if file: filename = file.filename file.save(os.path.join('/path/to/save', filename)) return 'Upload success!' else: return 'Upload failed!' ``` 最后,你可以使用OkHttpClient从Flask服务器下载图片。以下是一个简单的下载图片的示例代码: ```java OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("http://yourflaskserver.com/images/image.jpg") .build(); Response response = client.newCall(request).execute(); if (response.isSuccessful()) { // 将图片保存到本地 File file = new File("/path/to/save/image.jpg"); BufferedSink sink = Okio.buffer(Okio.sink(file)); sink.writeAll(response.body().source()); sink.close(); } ``` 希望这些示例代码能够帮助你完成Android客户上传图片到Flask服务器,并下载图片的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值