网上一般都是使用测试的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 ; }