接口post请求上传文件,文件以流的形式post进去,接口接收文件流

  • Post author:
  • Post category:其他


import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.*;

public class GjjHttpUtil {
    private static Logger log = LoggerFactory.getLogger(GjjHttpUtil.class);
    private final static String BOUNDARY = UUID.randomUUID().toString()
            .toLowerCase().replaceAll("-", "");// 边界标识
    private final static String PREFIX = "--";// 必须存在
    private final static String LINE_END = "\r\n";

    /**
     * http Get请求
     *
     * @param url
     * @param map
     * @return
     */
    public static JSONObject httpGet(String url, Map<String, String> map) {
        JSONObject jsonResult = null;
        // 获取连接客户端工具
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        try {
            URIBuilder uriBuilder = new URIBuilder(url);
            List<NameValuePair> nvps = new ArrayList<NameValuePair>();
            if (null != map) {
                for (String key : map.keySet()) {
                    nvps.add(new BasicNameValuePair(key, map.get(key)));
                }
            }
            uriBuilder.setParameters(nvps);
            // 根据带参数的URI对象构建GET请求对象
            HttpGet httpGet = new HttpGet(uriBuilder.build());
            /*
             * 添加请求头信息
             */

            httpGet.addHeader("token", "9999");

            // 执行请求
            response = httpClient.execute(httpGet);
            // 获得响应的实体对象
            if (response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                // 使用Apache提供的工具类进行转换成字符串
                String entityStr = EntityUtils.toString(entity, "UTF-8");
                jsonResult = JSONObject.parseObject(entityStr);
            } else {
                jsonResult.put("msg", "连接异常");
            }
        } catch (ClientProtocolException e) {
            System.err.println("Http协议出现问题");
            e.printStackTrace();
        } catch (ParseException e) {
            System.err.println("解析错误");
            e.printStackTrace();
        } catch (URISyntaxException e) {
            System.err.println("URI解析异常");
            e.printStackTrace();
        } catch (IOException e) {
            System.err.println("IO异常");
            e.printStackTrace();
        } finally {
            // 释放连接
            if (null != response) {
                try {
                    response.close();
                    httpClient.close();
                } catch (IOException e) {
                    System.err.println("释放连接出错");
                    e.printStackTrace();
                }
            }
        }

        // 打印响应内容
        System.out.println(jsonResult);

        return jsonResult;
    }


    /**
     * Post请求
     * 发送http协议,通过post传参数并返回数据
     **/
    public static String httpPost(String urlStr, Map<String, String> params) {
        URL connect;
        StringBuffer data = new StringBuffer();
        try {
            connect = new URL(urlStr);
            HttpURLConnection connection = (HttpURLConnection) connect.openConnection();
            connection.setRequestMethod("POST");
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setUseCaches(false);// post不能使用缓存
            connection.setConnectTimeout(15000);
            connection.setReadTimeout(15000);
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            connection.connect();
            OutputStreamWriter paramout = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");

            String paramsStr = ""; // 拼接Post 请求的参数
            for (String param : params.keySet()) {
                if (isNotBlank(params.get(param))) {
                    paramsStr += "&" + param + "=" + URLEncoder.encode(params.get(param), "utf-8");
                }
            }

            if (!paramsStr.isEmpty()) {
                paramsStr = paramsStr.substring(1);
            }
            System.out.println("====容量" + paramsStr.getBytes().length);
            paramout.write(paramsStr);
            paramout.flush();
            InputStream is = connection.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
            String line;
            while ((line = reader.readLine()) != null) {
                data.append(line);
            }

            paramout.close();
            reader.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return data.toString();
    }

    private static boolean isNotBlank(String string) {
        return string != null && !"".equals(string);
    }

    /**
     * POST Multipart Request
     *
     * @param requestUrl  请求url
     * @param requestText 请求参数
     * @param requestFile 请求上传的文件
     * @return
     * @throws Exception
     * @Description:
     */
    public static String sendRequest(String requestUrl,
                                     Map<String, String> requestText, Map<String, MultipartFile> requestFile) throws Exception {
        HttpURLConnection conn = null;
        InputStream input = null;
        OutputStream os = null;
        BufferedReader br = null;
        StringBuffer buffer = null;
        try {
            URL url = new URL(requestUrl);
            conn = (HttpURLConnection) url.openConnection();

            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            conn.setConnectTimeout(1000 * 10);
            conn.setReadTimeout(1000 * 10);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Accept", "*/*");
            conn.setRequestProperty("Connection", "keep-alive");
            conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
            conn.setRequestProperty("Charset", "UTF-8");
            conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
            conn.connect();

            // 往服务器端写内容 也就是发起http请求需要带的参数
            os = new DataOutputStream(conn.getOutputStream());
            // 请求参数部分
            writeParams(requestText, os);
            // 请求上传文件部分
            writeFile(requestFile, os);
            // 请求结束标志
            String endTarget = PREFIX + BOUNDARY + PREFIX + LINE_END;
            os.write(endTarget.getBytes());
            os.flush();

            // 读取服务器端返回的内容
            System.out.println("======================响应体=========================");
            System.out.println("ResponseCode:" + conn.getResponseCode()
                    + ",ResponseMessage:" + conn.getResponseMessage());
            if (conn.getResponseCode() == 200) {
                input = conn.getInputStream();
            } else {
                input = conn.getErrorStream();
            }

            br = new BufferedReader(new InputStreamReader(input, "UTF-8"));
            buffer = new StringBuffer();
            String line = null;
            while ((line = br.readLine()) != null) {
                buffer.append(line);
            }
            //......
            System.out.println("返回报文:" + buffer.toString());

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new Exception(e);
        } finally {
            try {
                if (conn != null) {
                    conn.disconnect();
                    conn = null;
                }

                if (os != null) {
                    os.close();
                    os = null;
                }

                if (br != null) {
                    br.close();
                    br = null;
                }
            } catch (IOException ex) {
                log.error(ex.getMessage(), ex);
                throw new Exception(ex);
            }
        }
        return buffer.toString();
    }

    /**
     * 对post参数进行编码处理并写入数据流中
     *
     * @throws Exception
     * @throws IOException
     */
    private static void writeParams(Map<String, String> requestText,
                                    OutputStream os) throws Exception {
        try {
            String msg = "请求参数部分:\n";
            if (requestText == null || requestText.isEmpty()) {
                msg += "空";
            } else {
                StringBuilder requestParams = new StringBuilder();
                Set<Map.Entry<String, String>> set = requestText.entrySet();
                Iterator<Map.Entry<String, String>> it = set.iterator();
                while (it.hasNext()) {
                    Map.Entry<String, String> entry = it.next();
                    requestParams.append(PREFIX).append(BOUNDARY).append(LINE_END);
                    requestParams.append("Content-Disposition: form-data; name=\"")
                            .append(entry.getKey()).append("\"").append(LINE_END);
                    requestParams.append("Content-Type: text/plain; charset=utf-8")
                            .append(LINE_END);
                    requestParams.append("Content-Transfer-Encoding: 8bit").append(
                            LINE_END);
                    requestParams.append(LINE_END);// 参数头设置完以后需要两个换行,然后才是参数内容
                    requestParams.append(entry.getValue());
                    requestParams.append(LINE_END);
                }
                os.write(requestParams.toString().getBytes());
                os.flush();

                msg += requestParams.toString();
            }

            //System.out.println(msg);
        } catch (Exception e) {
            log.error("writeParams failed", e);
            throw new Exception(e);
        }
    }

    /**
     * 对post上传的文件进行编码处理并写入数据流中
     *
     * @throws IOException
     */
    private static void writeFile(Map<String, MultipartFile> requestFile,
                                  OutputStream os) throws Exception {
        InputStream is = null;
        try {
            String msg = "请求上传文件部分:\n";
            if (requestFile == null || requestFile.isEmpty()) {
                msg += "空";
            } else {
                StringBuilder requestParams = new StringBuilder();
                Set<Map.Entry<String, MultipartFile>> set = requestFile.entrySet();
                Iterator<Map.Entry<String, MultipartFile>> it = set.iterator();
                while (it.hasNext()) {
                    Map.Entry<String, MultipartFile> entry = it.next();
                    if (entry.getValue() == null) {//剔除value为空的键值对
                        continue;
                    }
                    requestParams.append(PREFIX).append(BOUNDARY).append(LINE_END);
                    requestParams.append("Content-Disposition: form-data; name=\"")
                            .append(entry.getKey()).append("\"; filename=\"")
                            .append(entry.getValue().getName()).append("\"")
                            .append(LINE_END);
                    requestParams.append("Content-Type:")
                            .append(entry.getValue().getContentType())
                            .append(LINE_END);
                    requestParams.append("Content-Transfer-Encoding: 8bit").append(
                            LINE_END);
                    requestParams.append(LINE_END);// 参数头设置完以后需要两个换行,然后才是参数内容

                    os.write(requestParams.toString().getBytes());
                    os.write(entry.getValue().getBytes());

                    os.write(LINE_END.getBytes());
                    os.flush();

                    msg += requestParams.toString();
                }
            }
            //System.out.println(msg);
        } catch (Exception e) {
            log.error("writeFile failed", e);
            throw new Exception(e);
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
            } catch (Exception e) {
                log.error("writeFile FileInputStream close failed", e);
                throw new Exception(e);
            }
        }
    }

    /**
     * ContentType(这部分可忽略,MultipartFile有对应的方法获取)
     *
     * @param file
     * @return
     * @throws IOException
     * @Description:
     */
    public static String getContentType(MultipartFile file) throws Exception {
        String streamContentType = "application/octet-stream";
        String imageContentType = "";
        ImageInputStream image = null;
        try {
            image = ImageIO.createImageInputStream(file);
            if (image == null) {
                return streamContentType;
            }
            Iterator<ImageReader> it = ImageIO.getImageReaders(image);
            if (it.hasNext()) {
                imageContentType = "image/" + it.next().getFormatName();
                return imageContentType;
            }
        } catch (IOException e) {
            log.error("method getContentType failed", e);
            throw new Exception(e);
        } finally {
            try {
                if (image != null) {
                    image.close();
                }
            } catch (IOException e) {
                log.error("ImageInputStream close failed", e);
                ;
                throw new Exception(e);
            }

        }
        return streamContentType;
    }
//    MockMultipartFile是单元测试的类,故需要单元测试的包
//    ContentType是org.apache.http.entity.ContentType
//    ContentType.APPLICATION_OCTET_STREAM.toString()可用字符串application/octet-stream代替
    public static void main(String[] args) throws Exception {
        /**
         * 方式一、只能测试用,正式打包不能用
         */
//        String requestURL = "http://127.0.0.1:8080/api/uploadFile";
//        GjjHttpUtil httpReuqest = new GjjHttpUtil();
//
//        Map<String,String> requestText = new HashMap<>();
//        requestText.put("token","123456");//传的参数
//        Map<String,MultipartFile> requestFile = new HashMap<>();
//        File file = new File("D:\\save\\provide\\demo.png");//文件
//        FileInputStream fileInputStream = new FileInputStream(file);
//        //传文件以流的方式,MockMultipartFile是测试的,打包的时候是不会打包进去的
//        MultipartFile multipartFile = new MockMultipartFile(file.getName(),
//                file.getName(), ContentType.APPLICATION_OCTET_STREAM.toString(),
//                fileInputStream);
//        requestFile.put("image",multipartFile);
//        //得到返回值
//        String data = httpReuqest.sendRequest(requestURL, requestText, requestFile);

        /**
         * 方式二、正式环境可以用
         */
        //content是base64
        //想要完整获取一个base64的测试数据,可以https://www.sojson.com/image2base64.html这边拿
        String content = "";
        String token = "123456";
        String requestURL = "http://127.0.0.1:8080/api/uploadFile";
        GjjHttpUtil httpReuqest = new GjjHttpUtil();

        Map<String,String> requestText = new HashMap<>();
        requestText.put("access_token",token);
        Map<String, MultipartFile> requestFile = new HashMap<>();
        String fileName = Utils.buildMallOrderSn()+".jpg";
        MultipartFile multipartFile = BASE64DecodedMultipartFile.base64ToMultipart(content);
        requestFile.put(fileName,multipartFile);
        String data = httpReuqest.sendRequest(requestURL, requestText, requestFile);
  /**
         * 多个文件的情况
         */
        //content是base64
        //想要完整获取一个base64的测试数据,可以https://www.sojson.com/image2base64.html这边拿
        String content = "";
        List<String> str = new ArrayList<>();
        str.add(content);
        str.add(content);
        str.add(content);
        String token = "123456";
        String requestURL = "http://127.0.0.1:8080/api/uploadFile";
        GjjHttpUtil httpReuqest = new GjjHttpUtil();

        Map<String,String> requestText = new HashMap<>();
        requestText.put("access_token",token);
        Map<String, MultipartFile> requestFile = new HashMap<>();
        List<String> list = new ArrayList<>();
        for(String con:str){
            //随机生成文件名
            String fileName = Utils.buildMallOrderSn();
            list.add(fileName);
            MultipartFile multipartFile = BASE64DecodedMultipartFile.base64ToMultipart(con);
            requestFile.put(fileName,multipartFile);
        }
        //用来保存文件的名字,后续方便根据文件名获取文件
        requestText.put("imgNames",list.toString());
        String data = httpReuqest.sendRequest(requestURL, requestText, requestFile);




    }
}

BASE64DecodedMultipartFile类:


import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;

import java.io.*;

public class BASE64DecodedMultipartFile implements MultipartFile {

    private final byte[] imgContent;
    private final String header;

    public BASE64DecodedMultipartFile(byte[] imgContent, String header) {
        this.imgContent = imgContent;
        this.header = header.split(";")[0];
    }

    @Override
    public String getName() {
        return System.currentTimeMillis() + Math.random() + "." + header.split("/")[1];
    }

    @Override
    public String getOriginalFilename() {
        return System.currentTimeMillis() + (int) Math.random() * 10000 + "." + header.split("/")[1];
    }

    @Override
    public String getContentType() {
        return header.split(":")[1];
    }

    @Override
    public boolean isEmpty() {
        return imgContent == null || imgContent.length == 0;
    }

    @Override
    public long getSize() {
        return imgContent.length;
    }

    @Override
    public byte[] getBytes() throws IOException {
        return imgContent;
    }

    @Override
    public InputStream getInputStream() throws IOException {
        return new ByteArrayInputStream(imgContent);
    }

    @Override
    public void transferTo(File dest) throws IOException, IllegalStateException {
        new FileOutputStream(dest).write(imgContent);
    }

    public static MultipartFile base64ToMultipart(String base64) {
        try {
            String[] baseStrs = base64.split(",");

            BASE64Decoder decoder = new BASE64Decoder();
            byte[] b = new byte[0];
            b = decoder.decodeBuffer(baseStrs[1]);

            for (int i = 0; i < b.length; ++i) {
                if (b[i] < 0) {
                    b[i] += 256;
                }
            }
            return new BASE64DecodedMultipartFile(b, baseStrs[0]);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

}

utils工具类

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 工具类
 * @author zhn
 *
 */
public class Utils {
    private static final char[] digits = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
	/** 
     * 把字节数组转换成16进制字符串 
     *  
     * @param bArray 
     * @return 
     */  
    public static String bytesToHexString(byte[] bArray) {  
        StringBuffer sb = new StringBuffer(bArray.length);  
        String sTemp;  
        for (int i = 0; i < bArray.length; i++) {  
            sTemp = Integer.toHexString(0xFF & bArray[i]);  
            if (sTemp.length() < 2)  
                sb.append(0);  
            sb.append(sTemp.toUpperCase());  
        }  
        return sb.toString();  
    } 
    /** 
     * 把字符串转换成字节数组 
     *  
     * @param hex 
     * @return 
     */  
    public static byte[] hexStringToByte(String hex) {
        int len = (hex.length() / 2);  
        byte[] result = new byte[len];  
        char[] achar = hex.toCharArray();  
        for (int i = 0; i < len; i++) {  
            int pos = i * 2;  
            result[i] = (byte) (toByte(achar[pos]) << 4 | toByte(achar[pos + 1]));  
        }  
        return result;  
    }
    /** 
     * 字符串转换为16进制字符串 
     *  
     * @param s 
     * @return 
     */  
    public static String stringToHexString(String s) {  
        String str = "";  
        for (int i = 0; i < s.length(); i++) {  
            int ch = (int) s.charAt(i);  
            String s4 = Integer.toHexString(ch);  
            str = str + s4;  
        }  
        return str;  
    }  
    private static byte toByte(char c) {  
        byte b = (byte) "0123456789ABCDEF".indexOf(c);  
        return b;  
    } 
    /**
     * appId+appkey+timestamp+nonce按字典顺序升序排列
     * @param appId
     * @param appkey
     * @param timestamp
     * @param nonce
     * @return 排列后相加得到的字符串
     */
    public static String sortData(String appId, String appkey, String timestamp, String nonce){
    	List<String> list = new ArrayList<String>();
    	list.add(appId);
    	list.add(appkey);
    	list.add(timestamp);
    	list.add(nonce);
    	Collections.sort(list);
    	String newStr = "";
    	for(int i = 0 ; i < list.size() ; i++ ){
    		newStr += list.get(i);
    	}
    	return newStr;
    }
    // 随机生成16位字符串
 	public static String getRandomStr() {
 		String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
 		Random random = new Random();
 		StringBuffer sb = new StringBuffer();
 		for (int i = 0; i < 16; i++) {
 			int number = random.nextInt(base.length());
 			sb.append(base.charAt(number));
 		}
 		return sb.toString();
 	}


    /**
     * 随机生成日期加字母的字符串
     * @return
     */
    public static String buildMallOrderSn() {
        String dateStr = (new SimpleDateFormat("yyyyMMdd")).format(new Date());
        StringBuffer shortBuffer = new StringBuffer();
        String uuid = UUID.randomUUID().toString().replace("-", "");

        for(int i = 0; i < 8; ++i) {
            String str = uuid.substring(i * 4, i * 4 + 4);
            int x = Integer.parseInt(str, 16);
            shortBuffer.append(digits[x % 62]);
        }

        return dateStr + shortBuffer.toString();
    }
}



接口获取上面接口传的文件流文件


import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;

import java.util.List;



@RestController
@RequestMapping("/test")
//跨域注解
@CrossOrigin
public class demo {

    /**
     * 接收流信息
     *
     * @param request
     * @return
     */
    @PostMapping("/receiveStream")
    public String receiveStream(HttpServletRequest request) {
        //参数一
        String materialsName = request.getParameter("access_token");
        //参数一
        String code = request.getParameter("imgNames");
        MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
        //请求里key为File的元素(即文件元素)
        List<MultipartFile> list = multiRequest.getFiles("img");
        MultipartFile file = list.get(0);
        System.out.println(code);
        System.out.println(materialsName);
        return null;


    }
}


参考链接



版权声明:本文为weixin_43085797原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。