zoukankan      html  css  js  c++  java
  • Java模拟http上传文件请求(HttpURLConnection,HttpClient4.4,RestTemplate)

    先上代码:

        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("
    ");
                sb.append("Content-Disposition: form-data;name="file";filename="" + fileName + ""
    ");
                if(!fileName.endsWith("mp4")){
                    sb.append("Content-Type:image/jpeg
    
    ");
                }else if(){
                    sb.append("Content-Type:video/mp4
    
    ");
                }
    //未知文件类型,以流的方式上传
    //sb.append("Content-Type:application/octet-stream
    
    ");
                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 = ("
    --" + BOUNDARY + "--
    ").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("
    ");  
                }  
                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<String, Object> param = new LinkedMultiValueMap<>();
            param.add("file", resource);
            //param.add("fileName", "问题.mp4");
            org.springframework.http.HttpEntity<MultiValueMap<String, Object>> httpEntity = new org.springframework.http.HttpEntity<MultiValueMap<String, Object>>(param);
            ResponseEntity<String> responseEntity = template.exchange(uri, HttpMethod.POST, httpEntity, String.class);
            System.out.println("文件上传成功,返回:" + responseEntity.getBody());
        }

     上传大文件设置请求工厂类是否应用缓冲请求正文内部,默认值为true,当post或者put大文件的时候会造成内存溢出情况,设置为false将数据直接流入底层HttpURLConnection。

    public int uploadFile(String url, File file) {
    
            RestTemplate template = new RestTemplate();
            //ClientHttpRequestFactory clientFactory = new HttpComponentsClientHttpRequestFactory();
            SimpleClientHttpRequestFactory clientFactory = new SimpleClientHttpRequestFactory();
            clientFactory.setBufferRequestBody(false);
            template.setRequestFactory(clientFactory);
    
            URI uri = UriComponentsBuilder.fromUriString(url).build().encode().toUri();
    
            FileSystemResource resource = new FileSystemResource(file);
            MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
            param.add("file", resource);
            // param.add("fileName", "问题.mp4");
            org.springframework.http.HttpEntity<MultiValueMap<String, Object>> httpEntity = new org.springframework.http.HttpEntity<MultiValueMap<String, Object>>(
                    param);
            ResponseEntity<String> responseEntity = template.exchange(uri, HttpMethod.POST, httpEntity, String.class);
            logger.debug("文件上传成功,返回:{},状态码:{}",responseEntity.getBody(),responseEntity.getStatusCodeValue());
            return responseEntity.getStatusCodeValue();
        }

    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<String, Object> 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<MultiValueMap<String, Object>> httpEntity = 
                    new org.springframework.http.HttpEntity<MultiValueMap<String, Object>>(param,headers);
        
             List<HttpMessageConverter<?>> 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<String> 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;
        }
    }

    以上!

  • 相关阅读:
    js获取下拉框的值
    根据SNP的位置从基因组提取上下游序列
    PCA分析的疑问
    os删除文件或者文件夹
    python scipy包进行GO富集分析p值计算
    生物信息等级的划分
    docker笔记
    GATK4注意事项
    centos7修改yum源为阿里镜像
    idea如何通过数据库生成实体类
  • 原文地址:https://www.cnblogs.com/liangblog/p/7878065.html
Copyright © 2011-2022 走看看