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) {java代码部分做文件资源同步。比如:应用系统将上传的文件备份或同步至文件服务器中。
位于java client相关代码部分,将文件流通过httpClient工具发送网络请求到服务器上。
将java.io.File对象添加到HttpEntity(org.apache.http.HttpEntity)对象中:
MultipartEntityBuilder mEntityBuilder = MultipartEntityBuilder.create();
mEntityBuilder.addBinaryBody("file", file);
httppost.setEntity(mEntityBuilder.build());
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;
}
}
/**
* 上传文件
* @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,问题解决,接着又出新问题
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,问题解决,
第一种方法: 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; }
注解是post方式,那么检查以下内容:
1. 你是否用了post请求
2. 请求是否发送了数据
3. 请求内容格式需要是 application/json 。jquery 设置 contentType,--这地方要注意,我就是application/text报错415
4. 客户端是否出现了服务器没有的字段,spring post 中,字段可少,不可多。