上传文件后端获取不到信息
今天遇到了一个bug,前端传递一个表单 里面包含了一个文件 和 一个 json字符串
ContentType 为 multipart/form-data 前端没啥问题
但是后端想获取请求参数shopStr的时候死活获取不到值。。。。
Controller的代码是按照视频敲的(有时候视频挺害人的)
public Map<String,Object> regeisterShop(HttpServletRequest request){
Map<String,Object> map = new HashMap<>();
//接收前端的json信息 保存着店铺的各种信息
String json = RequestUtil.getStringValue(request,"shopStr");
//利用jackson把json数据转化为entity对象
ObjectMapper mapper = new ObjectMapper();
Shop shop = null;
try{
shop = mapper.readValue(json, Shop.class);
}catch (Exception e){
map.put("success",false);
map.put("error_msg",e.getMessage());
return map;
}
CommonsMultipartFile shopImg = null;
CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver();
if(commonsMultipartResolver.isMultipart(request)){
MultipartHttpServletRequest multipartHttpServletRequest =
commonsMultipartResolver.resolveMultipart(request);
shopImg = (CommonsMultipartFile) multipartHttpServletRequest.getFile("shopImg");
}else{
map.put("success",false);
map.put("error_msg","上传图片不能为空");
return map;
}
遇到的坑如下
- 在网上查了要添加依赖的jar包才可以解析这种类型的请求,于是添加了comons-fileupload,并且配置了springmvc的multipartresolver。成功获取了字符串类型的参数,但是文件为null了。。。。。。
- 如果去掉配置的multipartresolver 就不能获取到shopStr这个请求参数
解决办法
首先,我去查了网上的资料,发现这种类型的表单不能通过request.getparameter的方式来获取这样的请求
这种请求的编码类型为 multipart/form-data 它需要一些辅助的组件才能解析。
一种是利用apache的commons-fileupload组件解析
一种是利用servlet3.0及其以上版本的容器内置支持来解析
这里我们选择第一种方式
springmvc中上传代码的编写
编写springmvc的上传文件又面临两种方式,
- 第一个是在配置文件中配置multipartresolver,但是代码跟第二个方法不同
- 第二个是不用配置multipartresolver,由我们自己将request转换
第一种配置multipartResolver
首先配置文件中配置multipartResolver
<!--文件上传解析器-->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="2000000" />
<property name="defaultEncoding" value="utf-8"/>
<property name="resolveLazily" value="true"/>
</bean>
Controller写法
public Map<String, Object> regeisterShop(
@RequestParam(value="shopImg",required = false) MultipartFile shopImg,
@RequestParam(value = "shopStr",required = false) String shopStr
) {
Map<String, Object> map = new HashMap<>();
//利用jackson把json数据转化为entity对象
ObjectMapper mapper = new ObjectMapper();
Shop shop = null;
try {
shop = mapper.readValue(shopStr, Shop.class);
} catch (Exception e) {
map.put("success", false);
map.put("error_msg", e.getMessage());
return map;
}
if (shopImg == null) {
map.put("success", false);
map.put("error_msg", "上传图片不能为空");
return map;
}
直接利用注解@RequestParam让框架帮咱们封装好
第二种不用配置multipartResolver
public Map<String,Object> regeisterShop(HttpServletRequest request){
Map<String,Object> map = new HashMap<>();
CommonsMultipartFile shopImg = null;
CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver();
if(commonsMultipartResolver.isMultipart(request)){
MultipartHttpServletRequest multipartHttpServletRequest =
commonsMultipartResolver.resolveMultipart(request);
shopImg = (CommonsMultipartFile) multipartHttpServletRequest.getFile("shopImg");
}else{
map.put("success",false);
map.put("error_msg","上传图片不能为空");
return map;
}
String shopStr = multipartHttpServletRequest.getParameter("shopStr");
原理 用resolver检测request是否为multipart的,然后把request转换为MultipartHttpServletRequest,在利用转换后的request获取请求参数