网上一般都是使用测试的maven包中的MockMultipartFile这个类,就是下边这个maven包:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>RELEASE</version>
</dependency>
但是,使用这个包,有一个大坑,就是你在本地测试的时候还好,但是一旦发布到生产环境,或者你跳过测试打包的话。就会报错说找不到这个类。所以提醒大家,测试包中的类不要写到生产代码中去。
那如何去解决这个问题呢。看下边这个例子。完美解决。
工具类:MockMultipartFile
package com.didichuxing.ep.bpm.common.utils ;
import java.io.ByteArrayInputStream ;
import java.io.File ;
import java.io.IOException ;
import java.io.InputStream ;
import org.springframework.util.Assert ;
import org.springframework.util.FileCopyUtils ;
import org.springframework.web.multipart.MultipartFile ; /**
* 根据二进制流和数组 * 创建 MultipartFile 对象的工具类 */ public class MockMultipartFile implements MultipartFile {
private final String name ;
private String originalFilename ;
private String contentType ;
private final byte [] content ;
public MockMultipartFile (String name , byte [] content) {
this (name , "" , (String) null, ( byte []) content) ;
}
public MockMultipartFile (String name , InputStream contentStream) throws IOException {
this (name , "" , (String) null, ( byte []) FileCopyUtils.copyToByteArray (contentStream)) ;
}
public MockMultipartFile (String name , String originalFilename , String contentType , byte [] content) {
Assert.hasLength (name , "Name must not be null" ) ;
this . name = name ;
this . originalFilename = originalFilename != null ? originalFilename : "" ;
this . contentType = contentType ;
this . content = content != null ? content : new byte [ 0 ] ;
}
public MockMultipartFile (String name , String originalFilename , String contentType , InputStream contentStream) throws IOException {
this (name , originalFilename , contentType , FileCopyUtils.copyToByteArray (contentStream)) ;
}
public String getName () {
return this . name ;
}
public String getOriginalFilename () {
return this . originalFilename ;
}
public String getContentType () {
return this . contentType ;
}
public boolean isEmpty () {
return this . content . length == 0 ;
}
public long getSize () {
return ( long ) this . content . length ;
}
public byte [] getBytes () throws IOException {
return this . content ;
}
public InputStream getInputStream () throws IOException {
return new ByteArrayInputStream( this . content ) ;
}
public void transferTo (File dest) throws IOException , IllegalStateException {
FileCopyUtils.copy ( this . content , dest) ;
}
}
转换示例:
/**
* 更新上传的流程模型 XMl 的 key
*
* @param mFile 导入的 MultipartFile 对象 * @param key 流程模型的 key
* @return newXmlString 新的 xmlString
*/ public MultipartFile updateFile (MultipartFile mFile , String key) {
if (StringUtils.isBlank (key) || Objects.isNull (mFile)) {
return null;
}
SAXReader saxReader = new SAXReader() ;
org.dom4j.Document doc = null;
XMLWriter writer = null;
MultipartFile file = null;
try {
doc = saxReader.read(mFile.getInputStream()) ;
// 查询 xml 根节点下的 process 标签
Element process = doc.getRootElement().element( "process" ) ;
// 得到 process 标签下的属性 id 对象
Attribute processIdAttr = process.attribute( "id" ) ;
// 修改属性值
processIdAttr.setValue(key) ;
Element bpmnDiagram = doc.getRootElement().element( "BPMNDiagram" ) ;
Attribute bpmnDiagramIdAttr2 = bpmnDiagram.attribute( "id" ) ;
bpmnDiagramIdAttr2.setValue( "BPMNDiagram_" + key) ;
// 查询 xml 中 BPMNDiagram 节点下的 BPMNPlane 标签
Element bpmnPlane = bpmnDiagram.element( "BPMNPlane" ) ;
Attribute bpmPlaneBpmnElementAttr = bpmnPlane.attribute( "bpmnElement" ) ;
Attribute bpmPlaneIdAttr = bpmnPlane.attribute( "id" ) ;
bpmPlaneBpmnElementAttr.setValue(key) ;
bpmPlaneIdAttr.setValue( "BPMNPlane_" + key) ;
// 格式化 xml 输出格式
OutputFormat format = OutputFormat.createCompactFormat () ;
format.setEncoding( "UTF-8" ) ;
format.setIndent( true ) ; // 设置是否缩进
format.setIndent( " " ) ; // 设置空格缩进
format.setNewlines( true ) ; // 设置是否换行 // 将修改后的二进制数据流,通过 ByteArrayOutputStream 转成 MultipartFile 返回
ByteArrayOutputStream baos = new ByteArrayOutputStream() ;
writer = new XMLWriter(baos , format) ;
writer.write(doc) ;
ByteArrayInputStream in = new ByteArrayInputStream(baos.toByteArray()) ;
file = new MockMultipartFile(mFile.getName() , mFile.getOriginalFilename() , ContentType. APPLICATION_OCTET_STREAM .toString() , in) ;
} catch (Exception e) {
e.printStackTrace() ;
} finally {
try {
writer.flush() ;
writer.close() ;
} catch (IOException e) {
e.printStackTrace() ;
}
}
return file ; }