REST的文件上传,好像是标准API并没有提供一种比较好的方式。
我用的是JBOSS WILDLFY服务器,它的rest实现是jboss resteasy。Resteasy的文件上传就比较方便了。
如果使用jboss resteasy,那么就可以使用
org.jboss.resteasy.annotations.providers.multipart.MultipartForm
注解来实现文件的上传。
那么这个注解为什么能实现文件上传呢?
REST EASY中有这么一个类:
org.jboss.resteasy.plugins.providers.multipart.MultipartFormAnnotationReader
它的源码是这样子的:
@Provider @Consumes("multipart/form-data") public class MultipartFormAnnotationReader implements MessageBodyReader<Object> {……}
@Provider注解是注册自定义MessageBodyReader必须要用到的一个注解。MessageBodyReader的作用就是将http请求转化了某个类的对象。@Consumes("multipart/form-data")表示只接收MIME TYPE为multipart/form-data的请求。MessageBodyReader<Object>泛型了Object表示可以接受任意类型为方法参数。但是我们在看看源代码。
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { return FindAnnotation.findAnnotation(annotations, MultipartForm.class) != null || type.isAnnotationPresent(MultipartForm.class); }
在isReadable方法中进行了判断,可以看到只有加了@MultipartForm注解的,这个方法才会返回true。这就是我们使用这个注解的原因。
当然@Consumes("multipart/form-data")的MessageBodyReader在jboss resteasy中还有许多。因为这个注解特别好用,所以我就讲了这一个。
下面写个demo。这是一个rest的资源类:
package restfile; import java.io.UnsupportedEncodingException; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import org.jboss.resteasy.annotations.providers.multipart.MultipartForm; @Path("upload.html") public class FileUpload { @POST @Produces("text/html;charset=utf-8") public String upload(@MultipartForm Form form) throws UnsupportedEncodingException { return new String(form.getFile(), "utf-8"); } }
在我的这个资源类里面,我仅仅是将上传的文件内容以html的形式发发送给浏览器,有兴趣的可以写一个html文件上传试一试。
至于那个Form是很简单的,代码如下:
package restfile; import javax.ws.rs.FormParam; public class Form { @FormParam("file") private byte[] file; public byte[] getFile() { return file; } public void setFile(byte[] file) { this.file = file; } }
用的是标准的@FormParam注解来告诉框架,要从请求中的file字段来取数据。Resteasy的这个技术可以将上传的东西直接转变为byte数组,用起来特别方便。