如何将XML文本作为输入流

时间:2016-07-13 12:54:24

标签: java jaxb inputstream stax vtd-xml

我使用以下客户端来调用Jersey REST服务。

public class JerseyClient {
    public static void main(String[] args) {
        ClientConfig config   = new DefaultClientConfig();
        Client       client   = Client.create(config);
        WebResource  service  = client.resource(getBaseURI());
        String       response = service.accept(MediaType.TEXT_XML)
                                       .header("Content-Type", "text/xml; charset=UTF-8")
                                       .entity(new File("E:/postx.xml"))
                                       .post(String.class);

        System.out.println(response);
    }

    private static URI getBaseURI() {
        return UriBuilder.fromUri("http://localhost:8080/MyService/rest/xmlServices/doSomething").build();
    }
}

目前在服务器端我有以下内容:

@POST
    @Path("/doSomething")
    @Consumes(MediaType.TEXT_XML)
    @Produces(MediaType.TEXT_XML)
    public Response consumeXMLtoCreate(ProcessJAXBObject jaxbObject) {

如何更改上面的服务器端代码,以便我可以使用stAX并将一个特定元素流式传输到磁盘,而不是将所有对象转换为内存。我的目标是将包含二进制编码数据的元素流式传输到磁盘。

我收到的有效载荷是这样的:

<?xml version="1.0" encoding="utf-8"?> <ProcessRequest> <DeliveryDate>2015-12-13</DeliveryDate>  <AttachmentBinary>iVBORw0KGgoAAAANSUhEUgAAAFoA</AttachmentBinary> <AttachmentBinary>iVBORw0KGgoAAAANSUhEUgAAAFoA</AttachmentBinary> </ProcessRequest>

遵循@ vtd-xml-author

的建议

我现在有以下内容:

服务器端:

  @POST
    @Produces(MediaType.TEXT_XML)
    @Path("/doSomething")
    @Consumes(MediaType.APPLICATION_OCTET_STREAM)
    public Response consumeXMLtoCreate(@Context HttpServletRequest a_request,
            @PathParam("fileId") long a_fileId,
            InputStream a_fileInputStream) throws IOException {

        InputStream is;
        byte[] bytes = IOUtils.toByteArray(a_fileInputStream);

        VTDGen vg = new VTDGen();
        vg.setDoc(bytes);
        try {
            vg.parse(false);
        } catch (EncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (EOFException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (EntityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }//
        VTDNav vn = vg.getNav();
        AutoPilot ap = new AutoPilot(vn);
        try {
            ap.selectXPath("/ProcessRequest/BinaryAttachment/text()");
        } catch (XPathParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        int i=0;
        try {
            while((i=ap.evalXPath())!=-1){
               //i points to text node of 
               String s = vn.toRawString(i);
               System.out.println("HAHAHAHA:" + s);
              // you need to decode them 
            }
        } catch (XPathEvalException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NavException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

和客户端我有这个:

File file = new File("E:/postx.xml");
        FileInputStream fileInStream = null;

            fileInStream = new FileInputStream(file);

        ClientConfig config   = new DefaultClientConfig();
        Client       client   = Client.create(config);
        WebResource  service  = client.resource(getBaseURI());

         String tempImage = myfile.jpg;

        String sContentDisposition = "attachment; filename=\"" + tempImage+"\"";

        ClientResponse response = service.type(MediaType.APPLICATION_OCTET_STREAM)
                                       .header("Content-Disposition", sContentDisposition)
                                       .post(ClientResponse.class, fileInStream);

我有这个解决方案产生的问题,首先,如果我最终在堆中找到需要解码的String对象,我究竟能避免同样的内存问题吗?

其次,我可以在删除图像元素后使用vtd-xml重构对象或inputStream,因为我想使用JAXB处理它吗?

我相信XMLModifier的remove()方法应该允许我使用某种XML表示减去我现在写入磁盘的元素。

1 个答案:

答案 0 :(得分:1)

我假设您知道如何在代码中与HTTP协议进行交互。因此您知道如何将输入流中的字节读入字节缓冲区......以下代码将从该点开始接管...... < / p>

public void readBinaryAttachment(HTTPInputStream input) throws VTDException, IOException{
// first read xml bytes into XMLBytes
....
VTDGen vg = new VTDGen();
vg.setDoc(XMLBytes);
vg.parse(false);//
VTDNav vn = vg.getNav();
AutoPilot ap = new AutoPilot(vn);
ap.selectXPath("/ProcessRequest/BinaryAttachment/text()");
int i=0;
while((i=ap.evalXPath())!=-1){
   //i points to text node of 
   String s = vn.toRawString(i);
  // you need to decode them 
}

}