在Android中解析多部分响应

在Android中解析多部分响应,android,mime-types,Android,Mime Types,我正在将图像和json文本从android客户端发送到tomcat服务器,并使用多部分HttpPost以另一种方式发送。将多部分实体发送到服务器没有什么大不了的,因为您可以使用request.getPart()轻松地处理这些部分。但是在客户端,您只能以流的形式访问响应。因此,我最终将JSON字符串和图像都附加到同一个ServletOutputStream,并且必须在客户端手动解析它们。我在网上找到了apache-mime4j,但它几乎没有文档记录,我也找不到一个使用它的例子 在服务器端,我构建如

我正在将图像和json文本从android客户端发送到tomcat服务器,并使用多部分HttpPost以另一种方式发送。将多部分实体发送到服务器没有什么大不了的,因为您可以使用
request.getPart()
轻松地处理这些部分。但是在客户端,您只能以流的形式访问响应。因此,我最终将JSON字符串和图像都附加到同一个
ServletOutputStream
,并且必须在客户端手动解析它们。我在网上找到了apache-mime4j,但它几乎没有文档记录,我也找不到一个使用它的例子

在服务器端,我构建如下响应:

ServletResponse httpResponse = ctx.getResponse();
ResponseFacade rf = (ResponseFacade) httpResponse;
rf.addHeader("Access-Control-Allow-Origin", "*");
rf.addHeader("Access-Control-Allow-Methods", "POST");
rf.addHeader("content-type", "multipart/form-data");
httpResponse.setCharacterEncoding("UTF-8");

MultipartResponse multi = new MultipartResponse((HttpServletResponse) httpResponse);
ServletOutputStream out = httpResponse.getOutputStream();

multi.startResponse("text/plain");
out.println(CMD + "#" + content);
multi.endResponse();

multi.startResponse("image/jpeg");
out.write(data);
multi.endResponse();

multi.finish();

ctx.complete();
在Android的客户端,我想访问文本和图像数据:

InputStream is = response.getEntity().getContent();

MimeStreamParser parser = new MimeStreamParser();
MultipartContentHandler con = new MultipartContentHandler();
parser.setContentHandler(con);

try {
    parser.parse(is);
        String json = con.getJSON();        //get extracted json string
        byte[] imgBytes = con.getBytes();   //get extracted bytes

} catch (MimeException e) {
        e.printStackTrace();
} finally {
    is.close();
}

class MultipartContentHandler implements ContentHandler{

    public void body(BodyDescriptor bd, InputStream in) throws MimeException, IOException {
        //if MIME-Type is "text/plain"
        //   process json-part
        //else
        //   process image-part
    }

在方法
body(BodyDescriptor bd,InputStream In)
中,我的整个响应被视为
text\plain
mime类型。因此,我最终不得不再次手动解析每个字节,而整个apache-mime4j是无用的。你能告诉我我做错了什么吗?谢谢

好吧,我终于自己解决了。不,我是这样做的:

首先,我需要在服务器端创建一个
多部分/mixed
响应。可以使用
apache-mime-4j
API:

ServletResponse httpResponse = ctx.getResponse();    
ResponseFacade rf = (ResponseFacade) httpResponse;
httpResponse.setCharacterEncoding("UTF-8");
httpResponse.setContentType("multipart/mixed");
MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE, "SEPERATOR_STRING",Charset.forName("UTF-8"));
entity.addPart("json", new StringBody(CMD + "#" + content, "text/plain",  Charset.forName("UTF-8")));
entity.addPart("image", new ByteArrayBody(data, "image/jpeg", "file"));

httpResponse.setContentLength((int) entity.getContentLength());

entity.writeTo(httpResponse.getOutputStream());
ctx.complete();
现在,在客户端访问HttpResponse的MIME部分时,我使用javax.mailapi

ByteArrayDataSource ds = new ByteArrayDataSource(response.getEntity().getContent(), "multipart/mixed");
MimeMultipart multipart = new MimeMultipart(ds);    
BodyPart jsonPart = multipart.getBodyPart(0);
BodyPart imagePart = multipart.getBodyPart(1);
但是您不能使用本机API,而是使用这个API


现在,您可以继续处理各个部件。

使用apache-mime-4j也可以:

HttpURLConnection conn = ...;
final InputStream is = conn.getInputStream();
try {
    final StringBuilder sb = new StringBuilder();
    sb.append("MIME-Version: ").append(conn.getHeaderField("MIME-Version")).append("\r\n");
    sb.append("Content-Type: ").append(conn.getHeaderField("Content-Type")).append("\r\n");
    sb.append("\r\n");

    parser.parse(new SequenceInputStream(new ByteArrayInputStream(sb.toString().getBytes("US-ASCII")), is));
} catch (final MimeException e) {
    e.printStackTrace();
} finally {
    is.close();
}