Jersey 在 multipart/form-data 请求中上传文件时抛出 ParseException
Jersey throws ParseException when uploading file in multipart/form-data request
我正在尝试将一个 mp3 文件连同一些元数据发送到我的 Jersey REST 服务。为此,我尝试使用 multipart/form-data 内容类型,但是当我发送请求时,我总是得到 java.text.ParseException: Next event is not a Separator。整个回复:
{"restResponse":{
"responseCode":"INVALID_PARAMETER",
"i18nMessage":"Invalid Parameter: Next event is not a Separator",
"responseDescription":"The request contains an invalid parameter"}}
如果我从请求中删除 mp3 文件,它可以正常工作,所以我认为我的请求的构造方式存在问题。我正在使用 Paw,它生成这样的请求:
POST /rest/myapi/recording/multipart HTTP/1.1
Accept: application/json
Accept-Language: en-US
Content-Type: multipart/form-data; boundary=EI6FArOacJKf5JCY5BAA2sbl2IAfN8ty
Cookie: JSESSIONID=a5f5cfa7329142158766a6182645; JSESSIONIDSSO=BAFA3371F6D14A179B0BA6216DD6C119
Host: localhost:8181
Connection: close
User-Agent: Paw/2.2.2 (Macintosh; OS X/10.10.5) GCDHTTPRequest
Content-Length: 44504
--EI6FArOacJKf5JCY5BAA2sbl2IAfN8ty
Content-Disposition: form-data; name="queue"
qMultipart
--EI6FArOacJKf5JCY5BAA2sbl2IAfN8ty
Content-Disposition: form-data; name="datetime"
20151029-021807
--EI6FArOacJKf5JCY5BAA2sbl2IAfN8ty
Content-Disposition: form-data; name="recording"; filename="test4_multiform.mp3"
Content-Type: audio/mpeg
ID3ETT2test4_multiformCOMengiTunPGAP0TENiTunes 12.3.0.44COMhengiTunNORM 00000152 00000152 000013BE 000013BE 0000023E 0000023E 00003F10 00003F10 000002A7 000002A7COMengiTunSMPB 00000000 00000210 00000A30 0000000000015BC0 00000000 0
--- the rest of the recording ---
服务器端处理程序:
@Path(value = "multipart")
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public Response receiveFileAndMetadataAsMultipart(
@FormDataParam(RECORDING) InputStream recordingIinputStream,
@FormDataParam(RECORDING) FormDataContentDisposition callRecordingDispositionHeader,
@FormDataParam(QUEUE) String queue,
@FormDataParam(DATETIME) String datetime) throws JSONException, ParseException, IOException {
//do stuff with my recording and metadata
//...
JSONObject response = new JSONObject();
return Response.status(Response.Status.OK).entity(response).build();
}
当我尝试只发送文件并且内容类型不是 multipart/form-data 而是 application/octet-stream 时,它工作正常。 (我的意思不是这个处理程序,而是一个接受八位字节流的处理程序)尽管请求非常相似。我也会 post 八位字节流的请求和代码,也许它有帮助:
PUT /rest/myapi/recording HTTP/1.1
Accept: application/json
Accept-Language: en-US
Content-Type: application/octet-stream
Cookie: JSESSIONID=a5f5cfa7329142158766a6182645; JSESSIONIDSSO=BAFA3371F6D14A179B0BA6216DD6C119
Host: localhost:8181
Connection: close
User-Agent: Paw/2.2.2 (Macintosh; OS X/10.10.5) GCDHTTPRequest
Content-Length: 55414
ID3BTT2test3_2callsCOMengiTunPGAP0TENiTunes 12.3.0.44COMhengiTunNORM 0000038A 0000038A 00001B3D 00001B3D
--- the rest of the recording ---
方法:
@Path(value = "recording")
@PUT
@Consumes(MediaType.APPLICATION_OCTET_STREAM)
@Produces(MediaType.APPLICATION_JSON)
public Response receiveRecording(InputStream callRecordingInputStream) throws IOException, JSONException {
//do stuff with my recording
//...
JSONObject response = new JSONObject();
return Response.status(Response.Status.OK).entity(response).build();
}
有谁知道哪里出了问题?我在网上的几个地方发现了这种 multipart 方法,所以我想它应该像那样工作。
顺便说一句,我也尝试删除所有元数据并只发送录音,但问题是一样的。
感谢@peeskillet 的评论,我发现了这个问题,以防万一同样的事情发生在其他人身上:
我对 FormDataContentDisposition 的导入有误。
错误:
import com.sun.jersey.core.header.FormDataContentDisposition;
正确:
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
我正在尝试将一个 mp3 文件连同一些元数据发送到我的 Jersey REST 服务。为此,我尝试使用 multipart/form-data 内容类型,但是当我发送请求时,我总是得到 java.text.ParseException: Next event is not a Separator。整个回复:
{"restResponse":{
"responseCode":"INVALID_PARAMETER",
"i18nMessage":"Invalid Parameter: Next event is not a Separator",
"responseDescription":"The request contains an invalid parameter"}}
如果我从请求中删除 mp3 文件,它可以正常工作,所以我认为我的请求的构造方式存在问题。我正在使用 Paw,它生成这样的请求:
POST /rest/myapi/recording/multipart HTTP/1.1
Accept: application/json
Accept-Language: en-US
Content-Type: multipart/form-data; boundary=EI6FArOacJKf5JCY5BAA2sbl2IAfN8ty
Cookie: JSESSIONID=a5f5cfa7329142158766a6182645; JSESSIONIDSSO=BAFA3371F6D14A179B0BA6216DD6C119
Host: localhost:8181
Connection: close
User-Agent: Paw/2.2.2 (Macintosh; OS X/10.10.5) GCDHTTPRequest
Content-Length: 44504
--EI6FArOacJKf5JCY5BAA2sbl2IAfN8ty
Content-Disposition: form-data; name="queue"
qMultipart
--EI6FArOacJKf5JCY5BAA2sbl2IAfN8ty
Content-Disposition: form-data; name="datetime"
20151029-021807
--EI6FArOacJKf5JCY5BAA2sbl2IAfN8ty
Content-Disposition: form-data; name="recording"; filename="test4_multiform.mp3"
Content-Type: audio/mpeg
ID3ETT2test4_multiformCOMengiTunPGAP0TENiTunes 12.3.0.44COMhengiTunNORM 00000152 00000152 000013BE 000013BE 0000023E 0000023E 00003F10 00003F10 000002A7 000002A7COMengiTunSMPB 00000000 00000210 00000A30 0000000000015BC0 00000000 0
--- the rest of the recording ---
服务器端处理程序:
@Path(value = "multipart")
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public Response receiveFileAndMetadataAsMultipart(
@FormDataParam(RECORDING) InputStream recordingIinputStream,
@FormDataParam(RECORDING) FormDataContentDisposition callRecordingDispositionHeader,
@FormDataParam(QUEUE) String queue,
@FormDataParam(DATETIME) String datetime) throws JSONException, ParseException, IOException {
//do stuff with my recording and metadata
//...
JSONObject response = new JSONObject();
return Response.status(Response.Status.OK).entity(response).build();
}
当我尝试只发送文件并且内容类型不是 multipart/form-data 而是 application/octet-stream 时,它工作正常。 (我的意思不是这个处理程序,而是一个接受八位字节流的处理程序)尽管请求非常相似。我也会 post 八位字节流的请求和代码,也许它有帮助:
PUT /rest/myapi/recording HTTP/1.1
Accept: application/json
Accept-Language: en-US
Content-Type: application/octet-stream
Cookie: JSESSIONID=a5f5cfa7329142158766a6182645; JSESSIONIDSSO=BAFA3371F6D14A179B0BA6216DD6C119
Host: localhost:8181
Connection: close
User-Agent: Paw/2.2.2 (Macintosh; OS X/10.10.5) GCDHTTPRequest
Content-Length: 55414
ID3BTT2test3_2callsCOMengiTunPGAP0TENiTunes 12.3.0.44COMhengiTunNORM 0000038A 0000038A 00001B3D 00001B3D
--- the rest of the recording ---
方法:
@Path(value = "recording")
@PUT
@Consumes(MediaType.APPLICATION_OCTET_STREAM)
@Produces(MediaType.APPLICATION_JSON)
public Response receiveRecording(InputStream callRecordingInputStream) throws IOException, JSONException {
//do stuff with my recording
//...
JSONObject response = new JSONObject();
return Response.status(Response.Status.OK).entity(response).build();
}
有谁知道哪里出了问题?我在网上的几个地方发现了这种 multipart 方法,所以我想它应该像那样工作。
顺便说一句,我也尝试删除所有元数据并只发送录音,但问题是一样的。
感谢@peeskillet 的评论,我发现了这个问题,以防万一同样的事情发生在其他人身上:
我对 FormDataContentDisposition 的导入有误。
错误:
import com.sun.jersey.core.header.FormDataContentDisposition;
正确:
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;