httpclient文件上传

测试client

package com.tnb.user;

import java.io.File;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Test test = new Test();
        test.upload1();
    }
    
    public void upload1() {  
        CloseableHttpClient httpclient = HttpClients.createDefault();  
        System.out.println("executing request start" );
        try {  
            HttpPost httppost = new HttpPost("http://localhost:9501/users/change_avatar?token=1526369728694ed006c9e8277d4a3db1bd2271a9e1cab");  
        
            FileBody avatar = new FileBody(new File("C:\\Users\\qsf\\Pictures\\logo.png"));  
            StringBody token = new StringBody("1526369728694ed006c9e8277d4a3db1bd2271a9e1cab", ContentType.TEXT_PLAIN);  
 
            HttpEntity reqEntity = MultipartEntityBuilder.create().addPart("avatar", avatar).addPart("token", token).build();  
 
            httppost.setEntity(reqEntity);  
 
            System.out.println("executing request " + httppost.getRequestLine());  
            CloseableHttpResponse response = httpclient.execute(httppost);  
            try {  
                System.out.println("----------------------------------------");  
                System.out.println(response.getStatusLine());  
                HttpEntity resEntity = response.getEntity();  
                if (resEntity != null) {  
                    System.out.println("Response content length: " + resEntity.getContentLength());  
                }  
                EntityUtils.consume(resEntity);  
            } finally {  
                response.close();  
            }  
        } catch (ClientProtocolException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        } finally {  
            try {  
                httpclient.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
    }  
    
    public void upload() {  
        CloseableHttpClient httpclient = HttpClients.createDefault();  
        System.out.println("executing request start" );
        try {  
            HttpPut httppost = new HttpPut("http://localhost:9501/users/update_avatar?token=1526369728694ed006c9e8277d4a3db1bd2271a9e1cab");  
        
            FileBody avatar = new FileBody(new File("C:\\Users\\qsf\\Pictures\\logo.png"));  
            StringBody token = new StringBody("1526369728694ed006c9e8277d4a3db1bd2271a9e1cab", ContentType.TEXT_PLAIN);  
 
            HttpEntity reqEntity = MultipartEntityBuilder.create().addPart("file", avatar).addPart("token", token).build();  
 
            httppost.setEntity(reqEntity);  
 
            System.out.println("executing request " + httppost.getRequestLine());  
            CloseableHttpResponse response = httpclient.execute(httppost);  
            try {  
                System.out.println("----------------------------------------");  
                System.out.println(response.getStatusLine());  
                HttpEntity resEntity = response.getEntity();  
                if (resEntity != null) {  
                    System.out.println("Response content length: " + resEntity.getContentLength());  
                }  
                EntityUtils.consume(resEntity);  
            } finally {  
                response.close();  
            }  
        } catch (ClientProtocolException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        } finally {  
            try {  
                httpclient.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
    }  
}

pom修改,增加

   
          commons-fileupload
          commons-fileupload
          1.3.3
        

        
        
          commons-io
          commons-io
          2.6

        

spring boot application增加

@Bean(name = "multipartResolver")
    public MultipartResolver multipartResolver(){
     CommonsMultipartResolver resolver = new CommonsMultipartResolver();
     resolver.setDefaultEncoding("UTF-8");
     resolver.setResolveLazily(true);//resolveLazily属性启用是为了推迟文件解析,以在在UploadAction中捕获文件大小异常
     resolver.setMaxInMemorySize(40960);
     resolver.setMaxUploadSize(50*1024*1024);//上传文件大小 50M 50*1024*1024
     return resolver;
 }  


服务端

@ResponseBody

    @PutMapping("/update_avatar")

    public String handleFileUpload(@RequestParam("file") MultipartFile file) {      
        if (!file.isEmpty()) {      
            try {      
                /*    
                 * 这段代码执行完毕之后,图片上传到了工程的跟路径; 大家自己扩散下思维,如果我们想把图片上传到    
                 * d:/files大家是否能实现呢? 等等;    
                 * 这里只是简单一个例子,请自行参考,融入到实际中可能需要大家自己做一些思考,比如: 1、文件路径; 2、文件名;    
                 * 3、文件格式; 4、文件大小的限制;    
                 */      
                BufferedOutputStream out = new BufferedOutputStream(      
                        new FileOutputStream(new File(      
                                file.getOriginalFilename())));      
                System.out.println(file.getName());    
                out.write(file.getBytes());      
                out.flush();      
                out.close();      
            } catch (FileNotFoundException e) {      
                e.printStackTrace();      
                return "上传失败," + e.getMessage();      
            } catch (IOException e) {      
                e.printStackTrace();      
                return "上传失败," + e.getMessage();      
            }      
      
            return "上传成功";      
      
        } else {      
            return "上传失败,因为文件是空的.";      
        }      
    }  
    
    @ResponseBody
    @PostMapping("/change_avatar1")
    public Object changeAvatar1(HttpServletRequest request) {//@RequestParam(name = "token", required = true) String token,@RequestParam(name = "avatar") MultipartFile avatar

         MultipartHttpServletRequest params=((MultipartHttpServletRequest) request);    
        
         List files = ((MultipartHttpServletRequest) request)      
                 .getFiles("avatar");     
         String name=params.getParameter("token");    
         System.out.println("name:"+name);    
    
         MultipartFile file = null;      
         BufferedOutputStream stream = null;      
         for (int i = 0; i < files.size(); ++i) {      
             file = files.get(i);      
             if (!file.isEmpty()) {      
                 try {      
                     byte[] bytes = file.getBytes();      
                     stream = new BufferedOutputStream(new FileOutputStream(      
                             new File(file.getOriginalFilename())));      
                     stream.write(bytes);      
                     stream.close();      
                 } catch (Exception e) {      
                     stream = null;      
                     return "You failed to upload " + i + " => "      
                             + e.getMessage();    
                 }      
             } else {      
                 return "You failed to upload " + i      
                         + " because the file was empty.";      
             }    
         }      
         return "upload successful";    
     }     

https://blog.csdn.net/ahuyangdong/article/details/54343608

应用场景:

java代码部分做文件资源同步。比如:应用系统将上传的文件备份或同步至文件服务器中。

代码位置

位于java client相关代码部分,将文件流通过httpClient工具发送网络请求到服务器上。

关键代码

将java.io.File对象添加到HttpEntity(org.apache.http.HttpEntity)对象中:

MultipartEntityBuilder mEntityBuilder = MultipartEntityBuilder.create();
mEntityBuilder.addBinaryBody("file", file);
httppost.setEntity(mEntityBuilder.build());
  • 1
  • 2
  • 3

Client完整代码

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.ParseException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

public class FileClient {
    /**
     * 将文件提交至文件服务器
     * @param file 文件对象
     * @return FileStatus 上传结果
     */
    public static String postFile(File file) {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String result = null;
        try {
            HttpPost httpPost = new HttpPost(ServerURL.URL_FILE_POST);
            MultipartEntityBuilder mEntityBuilder = MultipartEntityBuilder.create();
            mEntityBuilder.addBinaryBody("file", file);
            httpPost.setEntity(mEntityBuilder.build());
            response = httpclient.execute(httpPost);

            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == HttpStatus.SC_OK) {
                HttpEntity resEntity = response.getEntity();
                result =EntityUtils.toString(resEntity);
                // 消耗掉response
                EntityUtils.consume(resEntity);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            HttpClientUtils.closeQuietly(httpclient);
            HttpClientUtils.closeQuietly(response);
        }
        return result;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

Server代码

    /**
     * 上传文件
     * @param fileRequest
     */
    @RequestMapping("/postFile")
    public void postFile(HttpServletRequest request, HttpServletResponse response) {
        String result = "error";
        Map map = new HashMap();
        // 创建一个通用的多部分解析器
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession()
                .getServletContext());
        // 判断 request 是否有文件上传,即多部分请求
        if (multipartResolver.isMultipart(request)) {
            // 转换成多部分request
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            // 取得request中的所有文件名
            Iterator iter = multiRequest.getFileNames();
            while (iter.hasNext()) {
                // 取得上传文件
                MultipartFile multipartFile = multiRequest.getFile(iter.next());
                if (multipartFile != null) {
                    // 取得当前上传文件的文件名称
                    String fileName = multipartFile.getOriginalFilename();
                    if (fileName.trim() != null && fileName.trim().length() > 0) {
                        CommonsMultipartFile cf = (CommonsMultipartFile) multipartFile;
                        DiskFileItem fi = (DiskFileItem) cf.getFileItem();
                        File tempFile = fi.getStoreLocation();
                        // 拿到文件,存储
                        ...
                        result = "success";
                    }
                }
            }
        }
    }
    map.put("result", result);
    this.renderJson(response, map);
}

问题1:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.ClassCastException: org.apache.catalina.connector.RequestFacade 
 程序刚一运行访问就抛出了上面的类型转换异常信息,根据提示信息,找到了导致该异常的代码行:
MultipartHttpServletRequest multipartRequest=(MultipartHttpServletRequest)request;
MultipartFile file=multipartRequest.getFile("upload");
这个问题花费了我很多时间和精力,查找了很多相关资料之后,发现我的配置文件里少了对multipart解析器的配置:

     
       
  
添加上之后,运行,访问,上面的异常终于没有再出现,但是新的问题又来了

问题2:

org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'multipartResolver' defined in ServletContext resource [/WEB-INF/dispatcher-servlet.xml]: Instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: org/apache/commons/fileupload/FileItemFactory
这次的问题很明确,缺少文件包,添加commons-fileupload-1.2.jar,问题解决,接着又出新问题

问题3:
org.springframework.web.util.NestedServletException: Handler processing failed; 

nested exception is java.lang.NoClassDefFoundError: org/apache/commons/io/output/DeferredFileOutputStream
添加commons-io-1.3.1,问题解决,
至此,整个程序终于可以完整的运行,正常上传

springmvc 中将MultipartFile转为file,springboot 注入CommonsMultipartResolver


第一种方法:

     MultipartFile file = xxx; 
        CommonsMultipartFile cf= (CommonsMultipartFile)file; 
        DiskFileItem fi = (DiskFileItem)cf.getFileItem(); 

        File f = fi.getStoreLocation();

  会在项目的根目录的临时文件夹下生成一个文件;

第二种方法:

    transferTo(File dest);

  会在项目中生成一个新文件;

第三种方法:   

  File f = (File) xxx 强转即可。前提是要配置multipartResolver,要不然会报类型转换失败的异常。

    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="104857600"/>
        <property name="maxInMemorySize" value="4096"/>
    bean>
  没试过;
第四种方法:
  Workbook wb = Workbook.getWorkbook(xxx .getInputStream());
  转换为输入流,直接读取;
第五种方法:
  byte[] buffer = myfile.getBytes();
  先转换为字节数组,没试过;
复制代码

 

复制代码
 //显示声明CommonsMultipartResolver为mutipartResolver
    @Bean(name = "multipartResolver")
       public MultipartResolver multipartResolver(){
        CommonsMultipartResolver resolver = new CommonsMultipartResolver();
        resolver.setDefaultEncoding("UTF-8");
        resolver.setResolveLazily(true);//resolveLazily属性启用是为了推迟文件解析,以在在UploadAction中捕获文件大小异常
        resolver.setMaxInMemorySize(40960);
        resolver.setMaxUploadSize(50*1024*1024);//上传文件大小 50M 50*1024*1024
        return resolver;
    }   
复制代码

记录下httpclient 发送请求 服务端用@RequestBody 自动接收参数 报415

注解是post方式,那么检查以下内容:
1. 你是否用了post请求
2. 请求是否发送了数据
3. 请求内容格式需要是 application/json 。jquery 设置 contentType,--这地方要注意,我就是application/text报错415
4. 客户端是否出现了服务器没有的字段,spring post 中,字段可少,不可多。

http://www.javased.com/index.php?api=org.apache.http.entity.mime.content.FileBody



你可能感兴趣的:(java)