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

来源:互联网 发布:cx域名不值钱吗 编辑:程序博客网 时间:2024/06/16 00:22

(更简单的方法,点击安卓端同时上传图片和文字,服务器接收并处理(二))
之前看了很多博客,找到的无非就是要么只上传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\"}";    }

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

原创粉丝点击