我正面临着球衣2文件上传的问题。输入流对服务器端是空的。使用jersey 2.21,jackson 2.5.4,弹簧4.1.6.RELEASE(仅适用于DI)& spring security 4.0.2.RELEASE用于安全性。使用JDK 1.8.0_25和Tomcat 8.0.26。
代码:
@POST
@Path("/upload")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.MULTIPART_FORM_DATA)
public SimpleResult categoryImageUpload(
@FormDataParam("file") InputStream file,
@FormDataParam("file") FormDataBodyPart bodyPart) {
return SimpleResult.success("File Uploaded successfully!!!");
}
文件详细信息将在FormDataBodyPart中出现,但InputStream将变为空(可用= 0)。
泽西岛配置:
@ApplicationPath("api-business")
public class BusinessApplicationConfig extends ResourceConfig {
public BusinessApplicationConfig() {
register(RequestContextFilter.class);
register(MultiPartFeature.class);
packages("com.smx.biz.api");
}
}
pom.xml中的依赖项:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.5.4</version>
</dependency>
<!--Jersey-->
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>2.21</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.21</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.21</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>2.21</version>
</dependency>
<!-- Jersey + Spring -->
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring3</artifactId>
<version>2.21</version>
</dependency>
有人可以帮忙解决这个问题吗?我错过了什么吗?
PS:Spring REST文件上传代码运行良好&amp; InputStream即将到来。但泽西岛代码不起作用。使用相同的客户端代码来测试apis。
使用Spring REST api代码:
@ResponseStatus(HttpStatus.OK)
@RequestMapping(value = "/business/upload", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
ImageItem categoryPhotoUpload(@RequestBody MultipartFile file) {
return uploadService.uploadFile(file);
}
我想将泽西用于apis&amp;我不想使用Spring REST。
有人可以帮忙解决这个问题吗?
答案 0 :(得分:1)
我发现当你使用@FormDataParam(&#34; file&#34;)InputStream文件方法时,参数永远不会被处理,因为jersey实际上正在寻找文件。会发生什么(至少从我到目前为止所读到的)是当请求进入泽西时,使用mimepull库进行一些mime检查,然后将传入的文件保存为临时文件。问题是,如果您的参数类型是InputStream,则jersey不会处理它,因为没有为InputStream注册ValueFactory。因此,为了实现这一点,您必须执行以下操作。
FormDataParamValueFactoryProvider内部
添加以下实现:
private final class InputStreamFactory extends ValueFactory<InputStream> {
private final String name;
public InputStreamFactory(final String name) {
this.name = name;
}
@Override
public InputStream provide() {
LOG.info("Processing paramaeter [" + name + "]");
final FormDataBodyPart part = getEntity().getField(name);
final BodyPartEntity entity = part != null ? part.getEntityAs(BodyPartEntity.class) : null;
if (entity != null) {
try {
// Create a temporary file.
final File file = Utils.createTempFile();
// Move the part (represented either via stream or file) to the specific temporary file.
entity.moveTo(file);
//Retreive file via a FileInputStream
return new FileInputStream(file);
} catch (final Exception ex) {
// Unable to create a temporary file or move the file.
LOG.warn("Error while processing InputStream. " + ex);
}
}
return null;
}
}
这将允许运动衫检测InputStream。
您还必须更改createValueFactory方法以反映新的ValueFactoryProvider。
@Override
protected Factory<?> createValueFactory(final Parameter parameter) {
final Class<?> rawType = parameter.getRawType();
if (Parameter.Source.ENTITY == parameter.getSource()) {
if (FormDataMultiPart.class.isAssignableFrom(rawType)) {
return new FormDataMultiPartFactory();
} else {
return null;
}
} else if (parameter.getSourceAnnotation().annotationType() == FormDataParam.class) {
final String paramName = parameter.getSourceName();
if (paramName == null || paramName.isEmpty()) {
// Invalid query parameter name
return null;
}
if (Collection.class == rawType || List.class == rawType) {
final Class clazz = ReflectionHelper.getGenericTypeArgumentClasses(parameter.getType()).get(0);
if (FormDataBodyPart.class == clazz) {
// Return a collection of form data body part.
return new ListFormDataBodyPartValueFactory(paramName);
} else if (FormDataContentDisposition.class == clazz) {
// Return a collection of form data content disposition.
return new ListFormDataContentDispositionFactory(paramName);
} else {
// Return a collection of specific type.
return new FormDataParamValueFactory(parameter, get(parameter));
}
} else if (FormDataBodyPart.class == rawType) {
return new FormDataBodyPartFactory(paramName);
} else if (FormDataContentDisposition.class == rawType) {
return new FormDataContentDispositionFactory(paramName);
} else if (File.class == rawType) {
return new FileFactory(paramName);
} else if (InputStream.class == rawType) {
return new InputStreamFactory(paramName);
} else {
return new FormDataParamValueFactory(parameter, get(parameter));
}
}
return null;
}
现在......在这里它变得很痛苦...如果你不从github拉出模块源并且用变化编译....你必须基本上重新创建以下类以便通过参考链引用新类。
类:
完成后,您可以使用@FormDataParam(&#34; file&#34;)InputStream,它将按预期工作。
答案 1 :(得分:0)
确保注释中的字符串
@FormDataParam("theSameStringUsedInAnnotation") InputStream file
与您要发布的资源的名称完全匹配。
在我的情况下,我使用的是ExtJs fileupload,当你定义一个文件上传时,如:
xtype: 'filefield',
name: 'theSameStringUsedInAnnotation',
你必须定义相同的字符串
答案 2 :(得分:-1)
在我的情况下,我将@FormDataParam("file") InputStream file
替换为@FormDataParam("file") File file
,然后它开始正常工作。