OkHttp上传文件及可能出现的问题

这篇具有很好参考价值的文章主要介绍了OkHttp上传文件及可能出现的问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在开发过程中用的是http请求,但是响应流一直为空,获取到的响应流{"n_a_s":1,"atts":[]},最终修改用okhttp方法。http请求方法也放在文章最后,大家如果有类似的问题欢迎一起讨论。

    /**
     * OA附件生成接口
     * @param urlstr   上传地址
     * @param filename  路径
     * @param token
     * @return
     * @throws BusinessException
     * @throws IOException 
     */
    public static String filePost(String urlstr, String filename, String token) throws BusinessException, IOException {

        try {
        OkHttpClient client = new OkHttpClient().newBuilder().build();
                MediaType mediaType = MediaType.parse("text/plain");
                RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
                  .addFormDataPart("file",filename,
                    RequestBody.create(MediaType.parse("application/octet-stream"),
                    new File(filename)))
                  .build();
                Request request = new Request.Builder()
                  .url("http://192.168.1.15:8090/seeyon/rest/attachment?token="+token)
                  .method("POST", body)
                  .addHeader("Cookie", "JSESSIONID=7144DE4003B79E88839BF28F5E89A171")
                  .build();
                Response response = client.newCall(request).execute();
                if (!response.isSuccessful())
                    throw new IOException("Unexpected code " + response);
                return response.body().string();
            } catch (IOException e) {
                throw new BusinessException(e.getMessage(), e);
            }
    }
public static String sendFiles(String urlstr, String filename,String token) throws BusinessException {
        
        DataOutputStream dos = null;
        OutputStream os = null;
        //生成一个文件,把文件转换成流对象FileBody
        File file = new File(filename);
        
        JSONObject json = new JSONObject();
        String BOUNDARY = "----WebKitFormBoundary7MA4YWxkTrZu0gW";
        //前缀
        String PREFIX = "--";
        //换行符
        String ROW = "\r\n";
        //产生一个边界
//        String BOUNDARY = UUID.randomUUID().toString().replaceAll("-" , "");

        try {
            URL url = new URL(urlstr.toString());
            //打开和url之间的连接
            HttpURLConnection hc = (HttpURLConnection) url.openConnection();
            //请求头
            //设置超时时间
            hc.setConnectTimeout(10000);
            //允许输入流
            hc.setDoInput(true);
            //允许输出流
            hc.setDoOutput(true);
            //不允许使用缓存
            hc.setUseCaches(false);
            //请求方式
            hc.setRequestMethod("POST");
            //设置通用的请求属性
            hc.setRequestProperty("accept", "*/*");
            //设置编码 utf-8
            hc.setRequestProperty("Charset", "utf-8");
            //设置为长连接
            hc.setRequestProperty("Connection", "Keep-Alive");
            //设置浏览器代理
            hc.setRequestProperty("User-Agent","Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36");
            hc.setRequestProperty("token", token);
            //边界标识
//            String boundary = Long.toHexString(System.currentTimeMillis());
            
            //这里设置请求方式以及boundary的内容,即上面生成的随机字符串
//            hc.setRequestProperty("Content-Type", CONTENT_TYPE+"; boundary=----" + boundary);
            hc.setRequestProperty("Content-Type","multipart/form-data; boundary=" + BOUNDARY);
            hc.connect();
            
            StringBuilder contentBody1 = new StringBuilder();
 
            DataOutputStream out =new DataOutputStream(hc.getOutputStream());
            
            os = hc.getOutputStream();
            dos = new DataOutputStream(os);
            
            String result = "";
            if (file != null) {
            //当文件不为空,把文件包装并且上传
            //这里定义输出流,用于之后向服务器发起请求
            
                //第一部分参数:excel文件
//                contentBody1.append("Content-Type:").append("multipart/form-data; boundary=" + BOUNDARY).append(ROW);
                contentBody1.append(ROW).append(BOUNDARY).append(ROW);
                //拼接文件名称
                contentBody1.append("Content-Disposition: form-data; name=\"file\"; filename=\"").append(file.getName())
                .append("\"")
                .append(ROW)
                //设置内容类型为流及编码为UTF-8
                .append("Content-Type: application/octet-stream; charset=UTF-8");
                //Todo 这两个换行很重要 标识文件信息的结束 后面的信息为文件流
                contentBody1.append(ROW).append(ROW);

                out.write(contentBody1.toString().getBytes(StandardCharsets.UTF_8));
            
              //写入文件流

                InputStreamReader reader=new InputStreamReader(new FileInputStream(file),"UTF-8");
                //读入缓冲区
                char[] buffer = new char[1024];
                //读入结果
                StringBuffer sb = new StringBuffer();
                //每次读入缓冲区的长度
                int len;
                //从读入流中读取文件内容并形成结果
                while ((len = reader.read(buffer)) != -1) {
                     sb.append(buffer, 0, len);
                }
                byte[] data = sb.toString().getBytes();
                // 向文件写入内容
                out.write(data);

                out.write(ROW.getBytes(StandardCharsets.UTF_8));
                
              //写入边界结束符
                out.write((BOUNDARY+PREFIX).getBytes(StandardCharsets.UTF_8));
                out.close();
                out.flush();//可以理解为发送请求
                
              //从服务器获得回答的内容
                /**
                 * 获取响应码 200=成功
                 * 当响应成功,获取响应的流
                 */
                int res = hc.getResponseCode();
                //获取后台返回的数据
                if (res == 200) {
                    BufferedReader bufferedReader = new BufferedReader(
                    new InputStreamReader(hc.getInputStream()));
                    String line;
                    StringBuffer sb_result = new StringBuffer();
                    while ((line = bufferedReader.readLine()) != null) {
                        sb_result.append(line);
                    }
                    return sb_result.toString();
//                    out.close(); 
         }else {
                BufferedReader bReader = new BufferedReader(new InputStreamReader(hc.getErrorStream(), "UTF-8"));
                int ch;
                while ((ch = bReader.read()) != -1) {
                    result += String.valueOf((char) ch);
                }
                throw new BusinessException(result, res + "");
            }    }    
        } catch (Exception e) {
            Logger.error("发送 POST 请求出现异常!" + e);
            throw new BusinessException("发送 POST 请求出现异常:" + e.getMessage(), e);
        } finally {
            if (dos != null) {
                try {
                    dos.close();
                } catch (Exception e2) {
                    Logger.error(e2.getMessage(), e2);
                }
            }
            if (os != null) {
                try {
                    os.close();
                } catch (Exception e2) {
                    Logger.error(e2.getMessage(), e2);
                }
            }
            if(!"".equals(json)&&json!=null) {
                JSONObject parseObject = JSONObject.parseObject(json.toString());
                Object object = parseObject.get("fileUrl");
                if(!"".equals(object)&&object!=null) {
                    return object.toString();
                }
//                log.writesendlog(url1+";;type:"+type+";;;数据:"+param, entityName+"error","");
            }
        }
        return FAILURE;
    }

PS:okhttp方法需要okhttp3和okio两个jar包,需要可以私信。


今天代码打到测试环境发现上传附件还是获取不到fileurl这个值,在postman测试时发送正常,我将postman中的代码取出(如下),怀疑是Cookie引发的问题,仔细查看Cookie获取的是JSESSIONID,这个id是从哪里获取到的呢?

OkHttpClient client = new OkHttpClient().newBuilder().build();
MediaType mediaType = MediaType.parse("text/plain");
RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
                  .addFormDataPart("file","/C:/Users/86177/Desktop/发起OA流程表单接口.doc",
                  RequestBody.create(MediaType.parse("application/octet-stream"),
                  new File("/C:/Users/86177/Desktop/发起OA流程表单接口.doc")))
                  .build();
Request request = new Request.Builder()
                  .url("https://127.0.0.1:80/seeyon/rest/attachment?token=391ed45d-798a-4a08-b0cd-6631ac2173b6")
                  .method("POST", body)
                  .addHeader("Cookie", "JSESSIONID=FC05529B631B89C2F1B9F21DDC845A50; route=d9b669d27408c3f4e55a50b632da8fb2")
                  .build();
Response response = client.newCall(request).execute();

让我们先看一下用postman获取到的附件上传的截图,图中可以看出此时可以附件已经发送成功,Cookie的值是187EC412AF0F028ACFA24BDB59FEF602,我询问了OA的老师,老师说token要获取登录名,建议我看看有没有获取到,我才想起来之前发送HTTP请求是我并没有绑定登录名,我用postman再次查看之前获取token的信息。

okhttp3 上传文件,用友,http,开发语言,后端,Powered by 金山文档

此时可以看到绑定登录者的token返回时会带回sessionid,这个值就是我们想要的,请求的url地址应该是http://IP:端口/seeyon/rest/token/用户名/密码?loginName=登录名

okhttp3 上传文件,用友,http,开发语言,后端,Powered by 金山文档

在HTTP请求获取token返回时还遇到了中文乱码问题,一并指出,在下文得到输入流时进行utf-8转码,最后从result结果中获取到发送成功的id,不需要sessionid,因为绑定了用户名的id可以在发送附件时自动存储在cookie。以上就是我在开发中遇到的问题,希望对你有所帮助。文章来源地址https://www.toymoban.com/news/detail-693861.html

    /**
     * 获取token
     * @return
     */
    public static String getToken2() {
        String result = "";
        String id = "";
        
        try{
            String oAURL = SysInitQuery.getParaString("GLOBLE00000000000000", "OAURL");
            String oAusername = SysInitQuery.getParaString("GLOBLE00000000000000", "OAuser");
            String oAPassword = SysInitQuery.getParaString("GLOBLE00000000000000", "OApassword");
            StringBuilder lasturl = new StringBuilder(oAURL+"/seeyon/rest/token/"+oAusername+"/"+oAPassword+"?loginName=tianxiang");
            URL url = new URL(lasturl.toString());
            //打开和url之间的连接
            HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
            //请求头
            urlConn.setRequestProperty("Content-Type", "application/json");
            urlConn.setRequestProperty("Accept", "application/json;charset=UTF-8");
            
            urlConn.setDoOutput(true);
            urlConn.setDoInput(true);
            urlConn.setRequestMethod("GET");//GET和POST必须全大写
            urlConn.connect();

            int code = urlConn.getResponseCode();//获得响应码
            if(code == 200) {//响应成功,获得响应的数据
//                InputStream is = urlConn.getInputStream();//得到数据流(输入流)
                InputStreamReader is = new InputStreamReader(urlConn.getInputStream(),"UTF-8");
                BufferedReader bufferedReader = new BufferedReader(is);
                StringBuffer stringBuffer = new StringBuffer();
                String line = null;
                while ((line = bufferedReader.readLine()) != null) {
                    stringBuffer.append(line);
                }
                result = stringBuffer.toString();

                if(!"".equals(result)&&result!=null){
                    JSONObject parseObject = JSONObject.parseObject(result);
                    Object object = parseObject.get("id");
                    if(object != null && !"".equals(object)) {
                         urlConn.disconnect();   //断开连接
                        return object.toString();
                    }
                }
            }
            urlConn.disconnect();   //断开连接

        }catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

到了这里,关于OkHttp上传文件及可能出现的问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring boot 使用 Okhttp3

    Spring boot 集成 okhttp3, 使用 http,https 在项目调用第三方服务是在所难免的,运用传统类型的Http调用,封装繁琐,代码量多还不简洁,避免一次一次的 找 度娘, 小记一下。 引入jar OkRestClient 工具类 OkHttp动态配置 使用 OkHttp 使用OkHttp 时 只需要注入 @AutoWired OkRestClient okRestC

    2024年02月11日
    浏览(48)
  • Java之okhttp3请求方式

    在java开发中,发起http请求是非常常见的需求,常用的有HttpClient,下面聊一下okhttp3的请求方式。 1、引入okhttp3依赖 2、提供springboot工程及http接口 3、http请求 4、请求结果 get请求 post请求 form表单请求 可见发起http请求还是挺方便的,感兴趣的小伙伴可以试试~~~///( v )~~~

    2024年02月13日
    浏览(39)
  • Android Okhttp3 分发器源码解析

    在 OkHttp 中,分发器(Dispatcher)是负责调度和执行网络请求的组件。它 管理 着 并发 的 请求数量 以及请求的 优先级 ,确保合理地使用底层的连接池和线程池,从而 提高 网络请求的 效率 和 性能 。 默认情况下,OkHttp 使用一个单例的分发器,它可以处理同时进行的最大请求

    2024年02月12日
    浏览(45)
  • Android okhttp3.0配置https信任所有证书

    参考: Android okhttp3.0配置https的自签证书和信任所有证书

    2024年02月19日
    浏览(43)
  • SpringBoot集成websocket(4)|(使用okhttp3实现websocket)

    章节 第一章链接: SpringBoot集成websocket(1)|(websocket客户端实现) 第二章链接: SpringBoot集成websocket(2)|(websocket服务端实现以及websocket中转实现) HTTP是现代应用常用的一种交换数据和媒体的网络方式,高效地使用HTTP能让资源加载更快,节省带宽。OkHttp是一个高效的HTTP客户

    2024年02月10日
    浏览(41)
  • 在Java版的OkHttp3 中 RequestBody.create() 过时解决方案

    当使用下面的代码时会提示 RequestBody.create() 已过时。 如下图: 解决办法: 如下图:

    2024年02月16日
    浏览(39)
  • Android Okhttp3添加https自签名证书以及Glide4

    没有得到安卓认可的证书颁发机构颁发的证书. 自己颁发的证书, 分临时性的(在开发阶段使用)或在发布的产品中永久性使用的两种. 而只有Android系统认可的机构办法的证书,在使用过程中才不会出现安全提示。 为什么会有人使用自签名的证书呢? (重要的事重复三遍)免费

    2024年04月16日
    浏览(78)
  • Android OKhttp使用(下载和上传文件)

    首先在build.gradle中引入okhttp 下面是demo(用okthttp下载网络上的资源) 用okthttp将资源上传至网络

    2024年02月11日
    浏览(50)
  • Android Okhttp3添加https自签名证书以及Glide4,Android高级工程师进阶学习—Android热修复原理

    二、自签名证书 什么是自签名证书(self-signed certicates)? 自签名证书就是没有通过受信任的证书颁发机构, 自己给自己颁发的证书. SSL 证书大致分三类: 由安卓认可的证书颁发机构CA(Certificate Authority)(如: VeriSign、DigiCert), 或这些机构的下属机构颁发的证书. 没有得到安卓认可的

    2024年04月17日
    浏览(41)
  • okhttp下载文件 Java下载文件 javaokhttp下载文件 下载文件 java下载 okhttp下载 okhttp

    示例 http客户端 用的是 okhttp,也可以用 UrlConnetcion或者apache okhttp官网 也可以下载 okhttp jar方式引入 1.1、okhttp发起请求官网Demo 3.1读写内容

    2024年02月12日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包