2015-09-18 4 views
2

У меня проблема с файлом PDF из нашего Restlet API.PDFbox with Restlet

Я использую код базового примера от Apache PDFBox documentation, он отлично работает за пределами контекста Restlet.

PDDocument document = new PDDocument(); 

System.err.println("before instantiating new PDPage"); 
// Create a new blank page and add it to the document 
PDPage page = new PDPage(); // LINE FAILING IN RESTLET 
System.err.println("after instantiating new PDPage"); 

document.addPage(page); 
document.save("pdf.pdf"); 
document.close(); 

Вот моя попытка использовать PDFBox в качестве ресурса, в конечном счете, я хочу вернуть OutputRepresentation и сохранить PDDcoument в поток.

Следующий код перестает работать с PDPage page = new PDPage();, я не получаю никаких исключений, сервер Restlet не возвращает никакого ответа. Текст "after instantiating new PDPage" никогда не печатается.

EDIT: Я упростил свой код так, как я могу, но я до сих пор этот вопрос

Вот мой основной маршрутизатор:

public class ApiRestletApplication extends Application { 

    @Override 
    public Restlet createInboundRoot() { 
    Router router = new Router(getContext()); 
    router.attach("/v1/myresource", MyResource.class); 
    return router; 
    } 
} 

Вот мой ресурс

public class MyResource extends ServerResource { 

    protected static final Logger logger = LoggerFactory.getLogger(MyResource.class); 

    @Get 
    public Representation toPDF() { 

    PDDocument document = new PDDocument(); 
    System.err.println("before instantiating new PDPage"); 
    PDPage page = new PDPage(); 
    System.err.println("after instantiating new PDPage"); //<= never printed 
    document.addPage(page); 

    return new PDFRepresentation(document); 
    } 
} 

вот мой web.xml

<!-- Restlet application --> 
<context-param> 
    <param-name>org.restlet.application</param-name> 
    <param-value>com.xxx.api.ApiRestletApplication</param-value> 
</context-param> 

<!-- Restlet adapter --> 
<servlet> 
    <servlet-name>RestletServlet</servlet-name> 
    <servlet-class> 
    org.restlet.ext.servlet.ServerServlet 
    </servlet-class> 
</servlet> 

<!-- Catch all requests --> 
<servlet-mapping> 
    <servlet-name>RestletServlet</servlet-name> 
    <url-pattern>/*</url-pattern> 
</servlet-mapping> 

Если я прокомментирую строку с декларацией PDPage и верну немного StringRepresentation, все будет хорошо. Я могу служить некоторым Json, xml и excel. Но этот PDF сводит меня с ума.

Вот версия Я использую:

[INFO] +- org.restlet.jee:org.restlet:jar:2.2.1:compile 
[INFO] +- org.restlet.jee:org.restlet.ext.crypto:jar:2.2.1:compile 
[INFO] +- org.restlet.jee:org.restlet.ext.servlet:jar:2.2.1:compile 

[INFO] | +- org.apache.pdfbox:pdfbox:jar:1.8.10:compile 
[INFO] | | +- org.apache.pdfbox:fontbox:jar:1.8.10:compile 
[INFO] | | \- org.apache.pdfbox:jempbox:jar:1.8.10:compile 
[INFO] | \- com.sun:tools:jar:jdk:system 

Вот завиток запрос:

curl "http://localhost:8889/v1/myresource" -H "Content-Type: application/pdf" -H "Accept: application/pdf" 

здесь регистрируется в затмении:

2015-09-21 15:08:15.933:INFO::Started [email protected]:8889 
2015-09-21 15:08:20.698:INFO:/:RestletServlet: [Restlet] Attaching application: [email protected] to URI: 
before instantiating new PDPage 
//then nothing 

Спасибо за вашу помощь ,

EDIT 2: следующий код работает, но я до сих пор понятия не имею, почему мой код не:

public class RestletServerTest extends Application { 

    @Override 
    public Restlet createInboundRoot() { 
    Router router = new Router(getContext()); 
    router.attach("/v1/myresource", MyResource.class); 
    return router; 
    } 

    public static void main(String[] args) throws Exception { 
    Component component = new Component(); 
    component.getServers().add(Protocol.HTTP, 8182); 

    component.getDefaultHost().attach("", new RestletServerTest()); 
    component.start(); 
    } 
} 

EDIT 3: проблема не кажется, связано с Restlet но PDFBox и сервлеты: PDFBox: Unable to save pdf while running on tomcat

EDIT 4: здесь решение https://stackoverflow.com/a/32706385/1039265

ответ

0

Фактически вы никогда не возвращаете содержимое созданного PDF в ответ. Возвращенное представление вашего аннотированного метода соответствует содержимому ответа.

В вашем случае это должно соответствовать двоичному. Вы также можете использовать заголовок для размещения контента, чтобы вызвать диалоговое окно загрузки в браузере.

Вы можете попытаться поместить это содержимое в массив байтов, а затем отправить его через Restlet с выделенным представлением (например, на основе OuputStream).

Надеюсь, это поможет вам. Thierry

+0

Привет Тьерри, это было просто ради примера. Я редактировал свой вопрос с кодом, который я использовал для воспроизведения проблемы. – dbaq

2

Я пробовал ваш образец кода, и это сработало для меня.

Я только что создал класс PDDocumentRepresentation, который оборачивает в PDDocument:

import org.apache.pdfbox.exceptions.COSVisitorException; 
import org.apache.pdfbox.pdmodel.PDDocument; 
import org.restlet.data.MediaType; 
import org.restlet.representation.OutputRepresentation; 

public class PDDocumentRepresentation extends OutputRepresentation { 

    private PDDocument document = new PDDocument(); 

    public PDDocumentRepresentation(PDDocument document) { 
     super(MediaType.APPLICATION_PDF); 
     this.document = document; 
    } 

    @Override 
    public void write(OutputStream outputStream) throws IOException { 
     try { 
      document.save(outputStream); 
      document.close(); 
     } catch (COSVisitorException e) { 
      throw new IOException(e); 
     } 
    } 
} 

Вот код ресурса:

public class MyResource extends ServerResource { 

    @Get 
    public Representation getPdf() { 
     PDDocument document = new PDDocument(); 
     PDPage page = new PDPage(); 
     document.addPage(page); 

     return new PDDocumentRepresentation(document); 
    } 
} 
+0

Привет Тьерри, спасибо за ваш ответ. К сожалению, у меня все еще есть проблема. Я отредактировал свой ответ, чтобы показать минимальный код, который я использовал. Спасибо за вашу помощь. – dbaq

+0

повторите попытку с помощью ServerServlet? Все работает отлично с автономным компонентом, но сбой при использовании ServerServlet. – dbaq

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