将多部分表单数据发布到seam + RESTeasy会导致无法编组到InputStream

时间:2012-06-28 21:40:46

标签: post jboss resteasy multipartform-data

我正在尝试将图像数据发布到seam + RESTeasy端点,并且在JBoss启动期间我遇到了一个非常神秘的错误。我发送的HTTP请求有一个内容类型的multipart / form-data,它有一个名为“attachment”的图像/ jpeg部分。我的服务方法如下:

@POST
@Path("uploadSymptomsImage/{appointmentGUID}")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces("application/json")
public String uploadSymptomsImage( @FormParam("attachment") InputStream fileInputStream,
                                   @PathParam("appointmentGUID") String strAppointmentGUID )
{ ...

我得到的错误是在启动期间:

Caused by: java.lang.RuntimeException: Unable to find a constructor that takes a String param or a valueOf() or fromString() method for javax.ws.rs.FormParam("attachment") on public java.lang.String com....AppointmentRestService.uploadSymptomsImage(java.io.InputStream,java.lang.String) for basetype: java.io.InputStream
at org.jboss.resteasy.core.StringParameterInjector.initialize(StringParameterInjector.java:206) [:]
at org.jboss.resteasy.core.StringParameterInjector.<init>(StringParameterInjector.java:57) [:]
at org.jboss.resteasy.core.FormParamInjector.<init>(FormParamInjector.java:22) [:]

我的理解是媒体类型可以自动编组到InputStream。我也尝试过java.io.File,java.io.Reader - 两者都有相同的错误。当我用byte []或String替换时,我得到一个零长度数组,或者作为参数值为null。

你会如何调试这个?此外,是否可以访问原始请求或预先编组的值?

这里的任何建议都将不胜感激。

1 个答案:

答案 0 :(得分:0)

您应该使用MultipartFormDataInput检索内容。请参阅以下示例:

@POST
@Path("uploadSymptomsImage/{appointmentGUID}")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces("application/json")
public String uploadSymptomsImage(@PathParam("appointmentGUID") String strAppointmentGUID,
                               MultipartFormDataInput formData) {

    Map<String, List<InputPart>> formDataMap = formData.getFormDataMap();

   List<InputPart> attachments = formDataMap.get("attachment");
   for(InputPart attachment : attachments) {
        String fileName = extractFilename(attachment);
        if(fileName.isEmpty()) continue;
        InputStream in = attachment.getBody(new GenericType<InputStream>() {});
        // Interact with stream
   }

    // Respond
}

extractFilename方法是一个帮助方法I wrote

private static String extractFilename(final InputPart attachment) {
    Preconditions.checkNotNull(attachment);
    MultivaluedMap<String, String> headers = attachment.getHeaders();
    String contentDispositionHeader = headers.getFirst("Content-Disposition");
    Preconditions.checkNotNull(contentDispositionHeader);

    for(String headerPart : contentDispositionHeader.split(";(\\s)+")) {
        String[] split = headerPart.split("=");
        if(split.length == 2 && split[0].equalsIgnoreCase("filename")) {
            return split[1].replace("\"", "");
        }
    }

    return null;
}