Гобелен, как обслуживать динамически сгенерированный файл XML?

У меня проблемы, связанные с Tapestry в моем проекте последнего года (Maven + Hibernate + Spring + Tapestry). Я надеюсь, что кто-то может помочь в этом. Я создаю XML-файл (его содержимое — мои данные базы данных MySql в специальном формате, который я создал) на своем сервисном уровне (я попробовал, и он правильно сгенерирован: он работает). Я проверил это из своих тестов Junit. Проблема в том, что я не могу заставить его работать из слоя просмотра, используя Tapestry.

Я пытался это сделать, но безуспешно Я думаю, что это потому, что файл уже не существует: он генерируется динамически, когда пользователь нажимает ссылку "Загрузить XML".

Вот мой исходный код (пользователь нажимает на ссылку, которая ведет на эту страницу). POJO для страницы (xmlService.exportXml — это метод моего сервисного уровня, который создает XML-файл):

public class DownloadAll {
    @Component
    private Form xmlDownloadForm;

    @Property
    private File xmlFile;

    @Property
    @SessionState(create=false)
    private UserSession userSession;

    @Inject
    private XmlService xmlService;

    public StreamResponse onSubmit() {
      xmlFile = xmlService.exportXml(userSession.getUserProfileId());
      String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(Calendar.getInstance().getTime());
      InputStream input = DownloadAll.class.getResourceAsStream("exportedData-"
          + userSession.getLoginName() + timeStamp + ".xml");
      return new XMLAttachment(input);
    }
}

А это шаблон страницы:

<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"
    t:type="Layout" t:pageTitle="title"
    xmlns:p="tapestry:parameter"
    t:menuExplanation="menuExplanation">
      <form t:type="Form" t:id="xmlDownloadForm">
    <input type="submit" value="${message:download}"/>
  </form>
</html>

Кто-нибудь знает, как заставить его работать? Спасибо и привет.

Редактировать: Файл создается (я вижу его в папке), когда я отправляю форму, но файл не обслуживается. Вместо этого я получаю эту ошибку:

org.apache.tapestry5.runtime.ComponentEventException Класс es.udc.decompras.web.pages.xml.util.XMLAttachment был преобразован и не может быть создан напрямую.

XMLAttachment совпадает с JPEGAttachment.java из этой ссылки Вот исходный код:

public class XMLAttachment extends AttachmentStreamResponse {

    public XMLAttachment(InputStream is, String args) {
      super(is, args);
      this.contentType = "application/xml";
      this.extension = "xml";
    }

    public XMLAttachment(InputStream is) {
      super(is);
      this.contentType = "application/xml";
      this.extension = "xml";
    }
}

person Alberto    schedule 10.06.2013    source источник


Ответы (1)


В вашем пакете "pages" могут быть только страницы. Переместите класс XMLAttachment в любой пакет, не управляемый гобеленом (например, НЕ в базу, компоненты или страницы).

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

person Community    schedule 10.06.2013
comment
Спасибо за ответ @uklance. У меня есть XMLAttachment в вспомогательном пакете (es.udc.decompras.web.pages.xml.util). Подпакет тоже недействителен? - person Alberto; 10.06.2013
comment
Нет, все подпакеты также управляются. Для страниц подпакет будет частью URL. - person lance-java; 10.06.2013
comment
Большое спасибо @uklance! Это действительно решило мою проблему :). Я прочитал это (из моих поисков Google), но я понял, что этот класс Java не должен быть в пакете страниц: я не понял, что этот класс Java не должен быть в подпакете страниц. - person Alberto; 11.06.2013
comment
единственная проблема, которая у меня есть сейчас, заключается в том, что я не могу обслуживать файл, используя InputStream input = DownloadAll.class.getResourceAsStream(exportedData- + userSession.getLoginName() + timeStamp + .xml), но он работает отлично если вместо этого я использую InputStream input = new FileInputStream (xmlFile):/ - person Alberto; 11.06.2013
comment
Попробуйте SomeNonComponentClass.class.getClassLoader().getResourceAsStream(...), поскольку Class.getResourceAsStream(...) требует, чтобы ресурс находился в той же папке пакета, что и класс. Это не связано с гобеленом. - person lance-java; 11.06.2013
comment
Еще раз спасибо @uklance, но я создаю файл в папке xml/exported/, которая находится в корневой папке моего проекта (так что он находится в той же папке, что и мой файл pom.xml, папка src и целевая папка). Даже если я попытаюсь получить его с помощью класса, который генерирует файл, я его не получу: InputStream input = XmlService.class.getResourceAsStream(fullFilenamePath); где fullFilenamePath равно xml/exported + filename . То же самое с fullFilename вместо fullFilenamePath. Если я напечатаю XmlService.class.getResource(fullFilename) или если я напечатаю XmlService.class.getResource(fullFilenamePath), я получу ноль. - person Alberto; 11.06.2013
comment
Это уже совсем от темы уходит. Если вы используете maven, ваш файл должен войти в src/main/resources, если вы хотите, чтобы он был включен в вашу банку/войну и т. д. Как я уже сказал, вы должны использовать XmlService.class.getClassloader().getResource(fullFilenamePath). Попробуйте заглянуть внутрь вашего jar-файла с помощью winzip и т. д., чтобы увидеть, включен ли файл. - person lance-java; 11.06.2013