使用场景
在使用Dubbo时,如果需要上传文件或下载文件,可以使用RestEasy。
不过RestEasy有个坑,就是文件名称使用中文时会乱码,需要添加过滤器处理。后文会说明。
Dubbo上传文件,传输效率比较低,不是很好的方案。
如果有时间创建一个新的非dubbo的项目,比如新建一个 spring、springBoot的模块,去上传文件比较好。
如果有其他更好的方案,不建议使用RestEasy。
Maven依赖
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson-provider</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxb-provider</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-multipart-provider</artifactId>
<version>3.0.9.Final</version>
</dependency>
postman请求格式
使用 form-data 传输文件。
RestEasy在上传文件时,最好将文件名跟文件分开,不然解析文件名称比较麻烦。
接口方法
@POST
@Path("upload")
@Consumes({ MediaType.MULTIPART_FORM_DATA, MediaType.APPLICATION_OCTET_STREAM})
@Produces({MediaType.APPLICATION_JSON + "; " + MediaType.CHARSET_PARAMETER + "=UTF-8",
MediaType.TEXT_XML + "; " + MediaType.CHARSET_PARAMETER + "=UTF-8"})
NormalResponse<Object> uploadFile(@MultipartForm MultipartFormDataInput formDataInput) ;
MultipartFormDataInput 可以传输多个文件,更通用一些。
注意,上传文件时使用的MediaType是 APPLICATION_OCTET_STREAM
NormalResponse类替换成项目里控制层的响应类即可。
接口实现
public NormalResponse<Object> uploadFile(MultipartFormDataInput formDataInput) {
Map<String, List<InputPart>> uploadForm = formDataInput.getFormDataMap();
InputPart inputPart = uploadForm.get("fieldName").get(0);
inputPart.setMediaType(MediaType.TEXT_PLAIN_TYPE);
//获取文件的名称
String fileNmae = inputPart.getBodyAsString();
//以下的inputStream就是文件的流数据
InputPart inputPartData = uploadForm.get("fieldData").get(0);
InputStream inputStream = inputPartData.getBody(InputStream.class, null);
}
添加过滤器
不管是使用RestEasy的 @MultipartForm乱码,还是MultipartFormDataInput乱码,都可以通过过滤器解决。
乱码的原因,详情见: https://blog.csdn.net/HackerSaillen/article/details/64470926
Dubbo添加过滤器的步骤,详情见:https://www.cnblogs.com/expiator/p/14557091.html
过滤器的内容如下:
public class ContainerContextFilter implements Filter {
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
try {
HttpServletRequest request= (HttpServletRequest)RpcContext.getContext()
.getRequest();
request.setCharacterEncoding("UTF-8");
//设置属性,避免中文乱码
request.setAttribute(InputPart.DEFAULT_CHARSET_PROPERTY, "UTF-8");
} catch (UnsupportedEncodingException e) {
log.error("catch invoke error.", e);
}
try {
return invoker.invoke(invocation);
} finally {
RpcContext.getContext().clearAttachments();
}
}
}