multipart上传文件
A. springboot多文件上传
MultipartFile提供了以下方法来获取上传文件的信息:
getOriginalFilename,获取上传的文件名字;
getBytes,获取上传文件内容,转为字节数组;
getInputStream,获取一个InputStream;
isEmpty,文件上传内容为空,或者根本就没有文件上传;
getSize,文件上传的大小。
transferTo(File dest),保存文件到目标文件系统;
同时上传多个文件,则使用MultipartFile数组类来接受多个文件上传:
//多文件上传 @RequestMapping(value = "/batch/upload", method = RequestMethod.POST)
@ResponseBody public String handleFileUpload(HttpServletRequest request){
List<MultipartFile> files = ((MultipartHttpServletRequest) request)
.getFiles("file");
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";
}
可以通过配置application.properties对SpringBoot上传的文件进行限定默认为如下配置:
spring.servlet.multipart.enabled=true
spring.servlet.multipart.file-size-threshold=0
spring.servlet.multipart.location=
spring.servlet.multipart.max-file-size=1MB
spring.servlet.multipart.max-request-size=10MB
spring.servlet.multipart.resolve-lazily=false
enabled默认为true,既允许附件上传。
file-size-threshold限定了当上传文件超过一定长度时,就先写到临时文件里。有助于上传文件不占用过多的内存,单位是MB或KB,默认0,既不限定阈值。
location指的是临时文件的存放目录,如果不设定,则web服务器提供一个临时目录。
max-file-size属性指定了单个文件的最大长度,默认1MB,max-request-size属性说明单次HTTP请求上传的最大长度,默认10MB.
resolve-lazily表示当文件和参数被访问的时候再被解析成文件。
B. php curl 模拟表单数据流multipart/form-data上传文件
在调用公众号接口https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=".$token."&type=".$type;
上传永久素材文件总是返回 "{\"errcode\":41005,\"errmsg\":\"media data missing\"}"
经过多次测试使用下面的方式,可以正常上传
//调用测试
protected static $url;
protected static $delimiter;
protected static $instance;
public function index()
{
static::$delimiter = uniqid();
$basename = Request::instance()->root();
if (pathinfo($basename, PATHINFO_EXTENSION) == 'php') {
$basename = dirname($basename);
}
$result=$this->wxAddMaterial($token,$basename.'/upload/images/gnlog.jpg','image');
}
// 新增其他类型永久素材
public function wxAddMaterial($token,$filename='',$type='') {
// 设置请求参数
static::$url = "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=".$token."&type=".$type;
$filePath = str_replace('\\', '/', $filename);
// 发送请求
$imginfo=pathinfo($filePath);
$fields = array(
'media'=>file_get_contents(".".$filePath),
'filename'=>$imginfo["basename"],
);
$res = $this->putPart( $fields);
// 发送请求
return $res;
}
//推送文件流
public function putPart($param) {
$post_data = static::buildData($param);
$curl = curl_init(static::$url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
"Content-Type: multipart/form-data; boundary=" . static::$delimiter,
"Content-Length: " . strlen($post_data)
]);
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
//编译请求头格式和数据流
private static function buildData($param){
$data = '';
$eol = "\r\n";
$upload = $param['media'];
unset($param['media']);
foreach ($param as $name => $content) {
$data .= "--" . static::$delimiter . "\r\n"
. 'Content-Disposition: form-data; name="' . $name . "\"\r\n\r\n"
. $content . "\r\n";
}
$data .= "--" . static::$delimiter . $eol
. 'Content-Disposition: form-data; name="media"; filename="' . $param['filename'] . '"' . "\r\n"
. 'Content-Type:application/octet-stream'."\r\n\r\n";
$data .= $upload . "\r\n";
$data .= "--" . static::$delimiter . "--\r\n";
return $data;
}
根据自己的实际情况稍作修改