博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java模拟http上传文件请求(HttpURLConnection,HttpClient4.4,RestTemplate)
阅读量:6466 次
发布时间:2019-06-23

本文共 10671 字,大约阅读时间需要 35 分钟。

先上代码:

public void uploadToUrl(String fileId, String fileSetId, String formUrl) throws Throwable {        String urlStr = MyServiceConfig.getUrl() + UPLOAD_URL;        String fileName = FileUtils.getFileName(formUrl);        long fileSize = getFileSize(formUrl);        String uri = UriComponentsBuilder.fromUriString(urlStr).queryParam("fileId", fileId).build().encode().toString();        logger.debug("文件上传请求路径:{}", uri);        // 获取文件输入流        InputStream in = getFileInputString(formUrl);        if (null != in) {            URL urlObj = new URL(uri);             HttpURLConnection con = (HttpURLConnection) urlObj.openConnection();            con.setRequestMethod("POST"); // 设置关键值,以Post方式提交表单,默认get方式            con.setDoInput(true);            con.setDoOutput(true);            con.setUseCaches(false); // post方式不能使用缓存            // 设置请求头信息            con.setRequestProperty("Connection", "Keep-Alive");            con.setRequestProperty("Charset", "UTF-8");            // 设置边界            String BOUNDARY = "----------" + System.currentTimeMillis();            con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);            // 请求正文信息            // 第一部分:            StringBuilder sb = new StringBuilder();            sb.append("--"); // 必须多两道线            sb.append(BOUNDARY);            sb.append("\r\n");            sb.append("Content-Disposition: form-data;name=\"file\";filename=\"" + fileName + "\"\r\n");            if(!fileName.endsWith("mp4")){                sb.append("Content-Type:image/jpeg\r\n\r\n");            }else if(){                sb.append("Content-Type:video/mp4\r\n\r\n");            }//未知文件类型,以流的方式上传//sb.append("Content-Type:application/octet-stream\r\n\r\n");            byte[] head = sb.toString().getBytes("utf-8");            // 获得输出流            OutputStream out = new DataOutputStream(con.getOutputStream());            // 输出表头            out.write(head);            // 文件正文部分            // 把文件已流文件的方式 推入到url中            DataInputStream dataIn = new DataInputStream(in);            int bytes = 0;            byte[] bufferOut = new byte[1024];            while ((bytes = dataIn.read(bufferOut)) != -1) {                out.write(bufferOut, 0, bytes);            }            in.close();            // 结尾部分            byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");// 定义最后数据分隔线            out.write(foot);            out.flush();            out.close();            // 读取返回数据                StringBuffer strBuf = new StringBuffer();              BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream()));              String line = null;              while ((line = reader.readLine()) != null) {                  strBuf.append(line).append("\n");              }              logger.debug("文件上传返回信息{}",strBuf.toString());              reader.close();              con.disconnect();              con = null;          } else {            throw new Throwable("获取文件流失败,文件下载地址url=" + formUrl);        }    }    // 获取文件大小    public InputStream getFileInputString(String formUrl) throws Throwable {        URL urlPath = new URL(formUrl);        HttpURLConnection conn = (HttpURLConnection) urlPath.openConnection();        conn.setConnectTimeout(5000);        conn.setRequestMethod("GET");        int status = conn.getResponseCode();        if (status == 200) {            return conn.getInputStream();        }        return null;    }        //获取文件大小        public long getFileSize(String formUrl) throws Throwable{              URL urlPath = new URL(formUrl);              HttpURLConnection conn = (HttpURLConnection)urlPath.openConnection();              conn.setConnectTimeout(downloadTimeout);              conn.setRequestMethod("GET");              int status = conn.getResponseCode();               if(status==200){                  return conn.getContentLengthLong();              }              return 0;        }

    

public static String getFileName(String fileFullPath) {

fileFullPath = fileFullPath.replace("/", "\\");
return fileFullPath.substring(fileFullPath.lastIndexOf("\\") + 1,
fileFullPath.length());
}
public static String getFileNameWithoutSuffix(String fileFullPath) {
fileFullPath = fileFullPath.replace("/", "\\");
return fileFullPath.substring(fileFullPath.lastIndexOf("\\") + 1,
fileFullPath.lastIndexOf("."));
}

 

 代码逻辑:

1、从访问文件的url中获取文件流和文件大小;

2、模拟http上传文件post请求;

   1》.打开httpurlconnection连接,设置关键值:重点是设置请求方法post和设置不缓存;

   2》.设置请求头,设置边界;重点是Content-Type;

   3》.设置请求正文,比较复杂,参照代码;

   4》.获取返回值;

 二、使用httpClient4.4上传文件:

//上传实体文件    public static void upload(String url,String filePath) throws Exception{        HttpPost httpPost = new HttpPost(url);        httpPost.setHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) "                + "AppleWebKit/537.36 (KHTML, like Gecko) "                + "Chrome/62.0.3202.89 Safari/537.36");        httpPost.setHeader("Accept-Language","zh-cn,zh;q=0.5");        httpPost.setHeader("Accept-Charset","GBK,utf-8;q=0.7,*;q=0.7");        httpPost.setHeader("Connection","keep-alive");                 MultipartEntityBuilder mutiEntity = MultipartEntityBuilder.create();        File file = new File(filePath);        //File file = new File("C:\\Users\\\\Desktop\\20171002中士.mp4");        //mutiEntity.addTextBody("filename","1问题.mp4");        mutiEntity.addPart("file", new FileBody(file));                CloseableHttpClient httpClient = HttpClients.createDefault();         httpPost.setEntity(mutiEntity.build());        HttpResponse  httpResponse = httpClient.execute(httpPost);        HttpEntity httpEntity =  httpResponse.getEntity();        String content = EntityUtils.toString(httpEntity);        System.out.println(content);            }

上传文件流: 重点是mode的设置,这里卡了半天;

//上传文件流    public static void upload(String url,InputStream in) throws Exception{        HttpPost httpPost = new HttpPost(url);        httpPost.setHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) "                + "AppleWebKit/537.36 (KHTML, like Gecko) "                + "Chrome/62.0.3202.89 Safari/537.36");        httpPost.setHeader("Accept-Language","zh-cn,zh;q=0.5");        httpPost.setHeader("Accept-Charset","GBK,utf-8;q=0.7,*;q=0.7");        httpPost.setHeader("Connection","keep-alive");                 MultipartEntityBuilder mutiEntity = MultipartEntityBuilder.create();        //mutiEntity.addTextBody("filename","16有问题.mp4");        mutiEntity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);        mutiEntity.addBinaryBody("uploadFile", in, ContentType.create("multipart/form-data"), "16有问题.mp4");                 CloseableHttpClient httpClient = HttpClients.createDefault();         httpPost.setEntity(mutiEntity.build());        HttpResponse  httpResponse = httpClient.execute(httpPost);        HttpEntity httpEntity =  httpResponse.getEntity();        String content = EntityUtils.toString(httpEntity);        System.out.println(content);            }

 

使用RestTemplate:

public static void uploadFile(String url,File file){        RestTemplate template = new RestTemplate();        ClientHttpRequestFactory clientFactory = new HttpComponentsClientHttpRequestFactory();        template.setRequestFactory(clientFactory);        URI uri = UriComponentsBuilder.fromUriString(url).build().encode().toUri();        FileSystemResource resource = new FileSystemResource(file);        MultiValueMap
param = new LinkedMultiValueMap<>(); param.add("file", resource); //param.add("fileName", "问题.mp4"); org.springframework.http.HttpEntity
> httpEntity = new org.springframework.http.HttpEntity
>(param); ResponseEntity
responseEntity = template.exchange(uri, HttpMethod.POST, httpEntity, String.class); System.out.println("文件上传成功,返回:" + responseEntity.getBody()); }

 

RestTemplate上传文件流:不建议用

这个比较麻烦,先看代码吧;

public static void uploadFile(String url,InputStream in){        RestTemplate template = new RestTemplate();        ClientHttpRequestFactory clientFactory = new HttpComponentsClientHttpRequestFactory();        template.setRequestFactory(clientFactory);        URI uri = UriComponentsBuilder.fromUriString(url).build().encode().toUri();//        InputStreamResource resource = new InputStreamResource(in);                MultiValueMap
param = new LinkedMultiValueMap<>(); param.add("file", new MultipartFileResource(in, "test")); //param.add("fileName", "问题.mp4"); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); org.springframework.http.HttpEntity
> httpEntity = new org.springframework.http.HttpEntity
>(param,headers); List
> messageConverters = template.getMessageConverters(); for (int i = 0; i < messageConverters.size(); i++) { HttpMessageConverter
messageConverter = messageConverters.get(i); if ( messageConverter.getClass().equals(ResourceHttpMessageConverter.class) ) messageConverters.set(i, new ResourceHttpMessageConverterHandlingInputStreams()); } ResponseEntity
responseEntity = template.exchange(uri, HttpMethod.POST, httpEntity, String.class); System.out.println("文件上传成功,返回:" + responseEntity.getBody()); }

这是修改后的,添加了转换器,因为添加之前会报错,文件流读了两次,其中一次是读取文件大小contentLength;

package com.my.upload;import java.io.IOException;import java.io.InputStream;import org.springframework.core.io.InputStreamResource;public class MultipartFileResource extends InputStreamResource {          private final String filename;          public MultipartFileResource(InputStream inputStream, String filename) {         super(inputStream);         this.filename = filename;     }     @Override     public String getFilename() {         return this.filename;     }     @Override     public long contentLength() throws IOException {         return -1; // we do not want to generally read the whole stream into memory ...     }}package com.my.upload;import java.io.IOException;import org.springframework.core.io.Resource;import org.springframework.http.MediaType;import org.springframework.http.converter.ResourceHttpMessageConverter;public class ResourceHttpMessageConverterHandlingInputStreams extends ResourceHttpMessageConverter {     @Override    protected Long getContentLength(Resource resource, MediaType contentType) throws IOException {        Long contentLength = super.getContentLength(resource, contentType);         return contentLength == null || contentLength < 0 ? null : contentLength;    }}

以上!

转载于:https://www.cnblogs.com/liangblog/p/7878065.html

你可能感兴趣的文章
生活杂事--度过十一中秋
查看>>
Pyrex也许是一个好东西
查看>>
Java内部类总结
查看>>
NeHe OpenGL第二课:多边形
查看>>
WINFORM WPF字体颜色相互转换
查看>>
能力不是仅靠原始积累(三)
查看>>
实战:使用终端服务网关访问终端服务
查看>>
彻底学会使用epoll(一)——ET模式实现分析
查看>>
路由器的密码恢复
查看>>
【Android 基础】Android中全屏或者取消标题栏
查看>>
Xilinx 常用模块汇总(verilog)【03】
查看>>
脱离标准文档流(2)---定位
查看>>
IO流之字符流
查看>>
集合异常之List接口
查看>>
Softmax回归
查看>>
紫书 习题11-11 UVa 1644 (并查集)
查看>>
App工程结构搭建:几种常见Android代码架构分析
查看>>
使用openssl进行证书格式转换
查看>>
ZOJ 3777 Problem Arrangement
查看>>
HTML中动态生成内容的事件绑定问题【转载】
查看>>