java发送post请求,使用multipart/form-data的方式传递参数

简介: java发送post请求,使用multipart/form-data的方式传递参数

/**

 * 测试上传图片
 * 
 */
public static void testUploadImage(){
    String url = "http://xxxtest/Api/testUploadModelBaking";
    String fileName = "e:/username/textures/antimap_0017.png";
    Map<String, String> textMap = new HashMap<String, String>();
    //可以设置多个input的name,value
    textMap.put("name", "testname");
    textMap.put("type", "2");
    //设置file的name,路径
    Map<String, String> fileMap = new HashMap<String, String>();
    fileMap.put("upfile", fileName);
    String contentType = "";//image/png
    String ret = formUpload(url, textMap, fileMap,contentType);
    System.out.println(ret);
    //{"status":"0","message":"add succeed","baking_url":"group1\/M00\/00\/A8\/CgACJ1Zo-LuAN207AAQA3nlGY5k151.png"}
}

/**
 * 上传图片
 * @param urlStr
 * @param textMap
 * @param fileMap
 * @param contentType 没有传入文件类型默认采用application/octet-stream
 * contentType非空采用filename匹配默认的图片类型
 * @return 返回response数据
 */
@SuppressWarnings("rawtypes")
public static String formUpload(String urlStr, Map<String, String> textMap,
        Map<String, String> fileMap,String contentType) {
    String res = "";
    HttpURLConnection conn = null;
    // boundary就是request头和上传文件内容的分隔符
    String BOUNDARY = "---------------------------123821742118716"; 
    try {
        URL url = new URL(urlStr);
        conn = (HttpURLConnection) url.openConnection();
        conn.setConnectTimeout(5000);
        conn.setReadTimeout(30000);
        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.setUseCaches(false);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Connection", "Keep-Alive");
        // conn.setRequestProperty("User-Agent","Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)");
        conn.setRequestProperty("Content-Type","multipart/form-data; boundary=" + BOUNDARY);
        OutputStream out = new DataOutputStream(conn.getOutputStream());
        // text
        if (textMap != null) {
            StringBuffer strBuf = new StringBuffer();
            Iterator iter = textMap.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry entry = (Map.Entry) iter.next();
                String inputName = (String) entry.getKey();
                String inputValue = (String) entry.getValue();
                if (inputValue == null) {
                    continue;
                }
                strBuf.append("\r\n").append("--").append(BOUNDARY).append("\r\n");
                strBuf.append("Content-Disposition: form-data; name=\"" + inputName + "\"\r\n\r\n");
                strBuf.append(inputValue);
            }
            out.write(strBuf.toString().getBytes());
        }
        // file
        if (fileMap != null) {
            Iterator iter = fileMap.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry entry = (Map.Entry) iter.next();
                String inputName = (String) entry.getKey();
                String inputValue = (String) entry.getValue();
                if (inputValue == null) {
                    continue;
                }
                File file = new File(inputValue);
                String filename = file.getName();
                
                //没有传入文件类型,同时根据文件获取不到类型,默认采用application/octet-stream
                contentType = new MimetypesFileTypeMap().getContentType(file);
                //contentType非空采用filename匹配默认的图片类型
                if(!"".equals(contentType)){
                    if (filename.endsWith(".png")) {
                        contentType = "image/png"; 
                    }else if (filename.endsWith(".jpg") || filename.endsWith(".jpeg") || filename.endsWith(".jpe")) {
                        contentType = "image/jpeg";
                    }else if (filename.endsWith(".gif")) {
                        contentType = "image/gif";
                    }else if (filename.endsWith(".ico")) {
                        contentType = "image/image/x-icon";
                    }
                }
                if (contentType == null || "".equals(contentType)) {
                    contentType = "application/octet-stream";
                }
                StringBuffer strBuf = new StringBuffer();
                strBuf.append("\r\n").append("--").append(BOUNDARY).append("\r\n");
                strBuf.append("Content-Disposition: form-data; name=\"" + inputName + "\"; filename=\"" + filename + "\"\r\n");
                strBuf.append("Content-Type:" + contentType + "\r\n\r\n");
                out.write(strBuf.toString().getBytes());
                DataInputStream in = new DataInputStream(new FileInputStream(file));
                int bytes = 0;
                byte[] bufferOut = new byte[1024];
                while ((bytes = in.read(bufferOut)) != -1) {
                    out.write(bufferOut, 0, bytes);
                }
                in.close();
            }
        }
        byte[] endData = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();
        out.write(endData);
        out.flush();
        out.close();
        // 读取返回数据
        StringBuffer strBuf = new StringBuffer();
        BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String line = null;
        while ((line = reader.readLine()) != null) {
            strBuf.append(line).append("\n");
        }
        res = strBuf.toString();
        reader.close();
        reader = null;
    } catch (Exception e) {
        System.out.println("发送POST请求出错。" + urlStr);
        e.printStackTrace();
    } finally {
        if (conn != null) {
            conn.disconnect();
            conn = null;
        }
    }
    return res;
}

以上是网上可以搜到显示最多的代码:

实际使用中发现有部分接口无法调通,后来发现是在

strBuf.append("\r\n").append("--").append(BOUNDARY).append("\r\n");

多了换行符,应改为:

strBuf.append("--").append(BOUNDARY).append("\r\n");

完整代码如下:

OutputStream out = new DataOutputStream(conn.getOutputStream());

        if (fileMap != null) {
            String filename = fileMap.get("filename");
            String upload = fileMap.get("upload");
            StringBuffer strBuf = new StringBuffer();
            strBuf.append("--").append(BOUNDARY).append("\r\n");
            strBuf.append("Content-Disposition: form-data;name=\"filename\"\r\n\r\n" + filename + "\r\n"); 
            strBuf.append("--").append(BOUNDARY).append("\r\n");
            strBuf.append("Content-Disposition: form-data;name=\"upload\";filename=\"" + upload + "\"\r\n"); 
            strBuf.append("\r\n");
           // strBuf.append("test:ai\n");
            out.write(strBuf.toString().getBytes());
            logger.debug(strBuf.toString());
            DataInputStream in = new DataInputStream(new FileInputStream(file));
            int bytes = 0;
            byte[] bufferOut = new byte[1024];
            while ((bytes = in.read(bufferOut)) != -1) {
                out.write(bufferOut, 0, bytes);
            }
            in.close();
            
            byte[] endData = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();
            out.write(endData);
            out.flush();
            out.close();
        }
        
        // 读取返回数据
        StringBuffer strBuf = new StringBuffer();
        BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String line = null;
        while ((line = reader.readLine()) != null) {
            strBuf.append(line).append("\n");
        }
        res = strBuf.toString();
        reader.close();
        reader = null;
        logger.info("上传完成:"+res);

这个要根据接收者的接收协议来确定使用哪一种方式。

相关文章
|
17天前
|
设计模式 Java Spring
Java 设计模式之责任链模式:优雅处理请求的艺术
责任链模式通过构建处理者链,使请求沿链传递直至被处理,实现发送者与接收者的解耦。适用于审批流程、日志处理等多级处理场景,提升系统灵活性与可扩展性。
134 2
|
7月前
|
Java
java中一个接口A,以及一个实现它的类B,一个A类型的引用对象作为一个方法的参数,这个参数的类型可以是B的类型吗?
本文探讨了面向对象编程中接口与实现类的关系,以及里氏替换原则(LSP)的应用。通过示例代码展示了如何利用多态性将实现类的对象传递给接口类型的参数,满足LSP的要求。LSP确保子类能无缝替换父类或接口,不改变程序行为。接口定义了行为规范,实现类遵循此规范,从而保证了多态性和代码的可维护性。总结来说,接口与实现类的关系天然符合LSP,体现了多态性的核心思想。
150 0
|
8月前
|
Java Linux 定位技术
Minecraft配置文件参数说明(JAVA服务器篇)
Minecraft JAVA版服务器启动后会生成server.properties配置文件,位于minecraft_server/根目录下。该文件包含多项关键设置,如游戏模式(gamemode)、最大玩家数(max-players)、难度(difficulty)等。此文档详细说明了各配置项的功能与默认值,帮助用户高效管理服务器环境。
1855 60
|
8月前
|
运维 Cloud Native Java
postman发起post请求遇到报错:java.io.FileNotFoundException (文件名、目录名或卷标语法不正确。)
遇到bug报错,多猜可能的原因,控制变量反复测试,直至找到问题的关键,然后再思考如何解决或者回避。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来
|
10月前
|
Java
java代码优化:判断内聚到实体对象中和构造上下文对象传递参数
通过两个常见的java后端实例场景探讨代码优化,代码不是优化出来的,而是设计出来的,我们永远不可能有专门的时间去做代码优化,优化和设计在平时
100 15
|
11月前
|
安全 Java API
java如何请求接口然后终止某个线程
通过本文的介绍,您应该能够理解如何在Java中请求接口并根据返回结果终止某个线程。合理使用标志位或 `interrupt`方法可以确保线程的安全终止,而处理好网络请求中的各种异常情况,可以提高程序的稳定性和可靠性。
182 6
|
11月前
|
JSON Java 数据格式
java操作http请求针对不同提交方式(application/json和application/x-www-form-urlencoded)
java操作http请求针对不同提交方式(application/json和application/x-www-form-urlencoded)
231 25
java操作http请求针对不同提交方式(application/json和application/x-www-form-urlencoded)
|
12月前
|
Java
实现java执行kettle并传参数
实现java执行kettle并传参数
212 1
|
12月前
|
Java
在Java中定义一个不做事且没有参数的构造方法的作用
Java程序在执行子类的构造方法之前,如果没有用super()来调用父类特定的构造方法,则会调用父类中“没有参数的构造方法”。因此,如果父类中只定义了有参数的构造方法,而在子类的构造方法中又没有用super()来调用父类中特定的构造方法,则编译时将发生错误,因为Java程序在父类中找不到没有参数的构造方法可供执行。解决办法是在父类里加上一个不做事且没有参数的构造方法。
|
存储 算法 Java
java制作海报六:Graphics2D的RenderingHints方法参数详解,包括解决文字不清晰,抗锯齿问题
这篇文章是关于如何在Java中使用Graphics2D的RenderingHints方法来提高海报制作的图像质量和文字清晰度,包括抗锯齿和解决文字不清晰问题的技术详解。
409 0
java制作海报六:Graphics2D的RenderingHints方法参数详解,包括解决文字不清晰,抗锯齿问题