2013-05-27 3 views
1

Я создаю веб-сервис SOAP. Я использую JAX-WS для создания этой службы и развертывания ее на сервере Glassfish 3.1.2.Потоковые пользовательские объекты

У меня нет проблем с тем, что эта служба возвращает строковое построение с представлением XML того, что я хочу. Я также могу получить его для возврата определенного объекта. У меня возникают проблемы с streaming этот ресурс.

Это то, что я до сих пор:

интерфейс:

@MTOM 
@WebService 
@XmlRootElement(name="root.element.class.location") 
@SOAPBinding(style = Style.RPC, use=Use.LITERAL) 
public interface ResultsServer { 

    @WebMethod 
    @XmlMimeType("text/xml") 
    public Test getResultDataAsXML(@WebParam(name="Id") Integer id) throws Exception; 
} 

Реализация:

---- Редактировать ----

Здесь я бы хотел мой ресурс. Предположим, мне нужен мой results объект становится чрезвычайно большим, я не хочу держать его в памяти и хотел бы начать его отправку, не удерживая его. (Комментировал это в коде)

@WebService(endpointInterface = "my.endpoint.class") 
@StreamingAttachment(parseEagerly=true, memoryThreshold=4000000L) 
public class ResultsServerImpl implements ResultsServer { 

    @Override 
    public Test getResultDataAsXML(Integer id) throws Exception { 
     Test results = new Test(); 
     for(int i=0; i<[very large number]; i++) { 
      results.getResults().add("here : " + i); 
      /**at one point, this is too large to hold in memory 
      I would like to be able to start returning the object here 
      so it is not taking up all available memory */ 
     } 
     return results; //or close the stream 
    } 
} 

---- Конец ---- Редактирование

И мой Test класс является простой класс вида:

public class Test { 

    private ArrayList<String> results; 

    public Test() { 
     results = new ArrayList<String>(); 
    } 

    public ArrayList<String> getResults() { 
     return results; 
    } 

    public void setResults(ArrayList<String> results) { 
     this.results = results; 
    } 
} 

Давайте предположим, что этот объект Test становится очень большим (и более сложным). Мне нужно иметь возможность передавать этот объект. Как бы я пошел, чтобы продолжить это.

В идеале, я хотел бы сохранить структуру этого объекта.

Из того, что я прочитал до сих пор, мне нужно было бы преобразовать этот объект в какой-то DataHandler и вернуть этот объект.

Любая помощь приветствуется! Спасибо.

+0

Реализация JAX-WS будет использовать реализацию JAXB маршалу объект (скорее всего к StAX 'XMLStreamWriter'), так что выход будет потоковом (там не быть XML документ, созданный в памяти). Вы ищете способ предотвратить возможность полной реализации экземпляра 'Test' в памяти? –

+0

@BlaiseDoughan Я думаю, вы сформулировали это так, как я искал. Да, это будет предотвращать полное сохранение экземпляра 'Test' в памяти. Есть ли способ сделать это? Также: Спасибо за информацию, касающуюся маршалинга JAXB. Это ответило на многие вопросы, которые у меня были. – blo0p3r

ответ

-1

Я бы порекомендовал использовать библиотеку xstream (http://x-stream.github.io/) из thinkworks для вашей потоковой передачи, поскольку она может быть установлена ​​с обеих сторон вашего сервиса и совместима с конвертами SOAP. На самом деле существует даже интеграция с ActiveSOAP.

Пример обернутого объекта xstream с конвертом SOAP можно увидеть на http://jira.codehaus.org/secure/attachment/19097/SoapEnvelopeTestCase.java. Полное использование от jboss можно увидеть на https://issues.jboss.org/secure/attachment/12325534/SOAPClient.java?_sscc=t.

XStream был использован для очень больших потоковых процессов (я использовал его для некоторых больших текстовых объектов более 100 МБ без проблем).

+0

Может ли кто-нибудь, кто меня пометил, прошу дать мне понять, что вы предпочтете увидеть. Я понимаю, что этот человек переживает, и большинство объектов Datahandler для SOAP при попытке получить XML-контент очень сложны и, как правило, имеют нечитаемые для чтения форматы. Я предлагаю очень хорошую библиотеку, у которой есть тонна власти, которая для этого. Я был бы рад изменить или удалить свой ответ, если понадобится, но просто проголосовать за меня не делает ни blo0p3r, ни я ничего хорошего. Благодарю. –

+0

Это интересно. Я ценю это предложение (а также думаю, что тот, кто проголосовал, должен объяснить причину, почему и предложить что-то лучшее/другое). Но это преобразует объект в объект XML. Это уже происходит. То, что вы предлагаете, будет преобразовывать этот объект в String, а затем передать эту строку? Я также замечаю, что типы помечены как 'class =" string "' вместо 'xsi: type =" xs: string "'. Который я предполагаю, что последний был бы лучше для совместимости с .NET-архитектурой (в конце концов, в моем случае). – blo0p3r

+0

На самом деле это не обязано быть ничейкой, поскольку он может использовать синтаксический анализатор sTax при его создании (используется для сериализации) 'XStream xstream = new XStream (новый StaxDriver());' и затем, когда вы захватываете объект, вы можете передать его прямо в выходной поток через http://xstream.codehaus.org/javadoc/com/thoughtworks/xstream/XStream.html#toXML(java.lang.Object, java.io.OutputStream). –

0

Реализация JAX-WS будет использовать реализацию JAXB для маршалирования объекта (скорее всего, для StAX XMLStreamWriter), поэтому вывод будет потоковым (в памяти не будет XML-документ, созданный в памяти).

@BlaiseDoughan Я думаю, вы сформулировали это так, как я искал. Да, это должно было бы предотвратить экземпляр теста полного сохранения в памяти. Есть ли способ сделать это?

Если вы хотите, чтобы данные отображались в сообщениях как XML (в отличие от приложения SOAP), вы могли бы использовать события маршала JAXB. В событии beforeMarshal вы можете загрузить данные в объект, а затем очистить его в методе afterUnmarshal. В конечном итоге все данные будут втянуты, но на все это не будут ссылаться одновременно.

+0

Это похоже на процесс, который я хочу принять. К сожалению, я не знаком с использованием событий маршала. Я изучаю это. Любые примеры использования, которые вы могли бы предоставить с точки зрения использования этого, получили бы большую оценку. – blo0p3r

+0

После того, как я поработал над этим, мой вопрос немного конкретнее: на каком объекте вы ссылаетесь, что я бы загрузил свои данные? У «Marshaller» и «Unmarshaller» есть свои «Listener», как данные этого объекта передаются от одного к другому? К сожалению, я думаю, что здесь может отсутствовать большой кусок головоломки. – blo0p3r

+0

@ blo0p3r - В вашу модель домена. –

Смежные вопросы