2009-01-29 8 views
4

Cela peut être un peu déroutant mais j'ai des problèmes. Mon but est de prendre un document HTML en entrée, puis de traiter ce document et d'utiliser les données HTML pour sortir un document image. Par exemple, un utilisateur demandera une URL, avec un peu d'action = png dans la chaîne de requête, puis le filtre sera appelé pour l'URL et le document d'image de sortie.Comment sortir un document binaire basé sur un document HTML en utilisant des filtres en Java

J'ai tout essayé mais dans mon environnement (Websphere), je ne peux sortir que d'un seul type. Si le type d'entrée est text/html alors je ne peux sortir qu'un document texte, je n'arrive pas à sortir un document binaire. Pourquoi? Parce que j'obtiens une exception d'état illégale à chaque fois.

[29/01/09 17: 59: 57: 576 EST] 00000020 SystemErr R java.lang.IllegalStateException: SRVE0209E: Writer déjà obtenu [29/01/09 17: 59: 57: 576 EST] 00000020 SystemErr R à com.ibm.ws.webcontainer.srt.SRTServletResponse.getOutputStream (SRTServletResponse.java:505)

J'utilise le code pseudo ne pas révéler tout mon code:

<filter> 
    <filter-name>TestFilter</filter-name> 
    <filter-class> 
     com.util.TestFilter 
    </filter-class> 
</filter> 

<filter-mapping> 
    <filter-name>TestFilter</filter-name> 
    <url-pattern>/index_test2.html</url-pattern> 
</filter-mapping> 

La classe wrapper le code est essentiellement ceci:

public class ContentCaptureServletResponse extends HttpServletResponseWrapper { 
    private ByteArrayOutputStream contentBuffer; 
    private PrintWriter writer; 
    public PrintWriter getWriter() throws IOException { 
     if (writer == null) { 
      contentBuffer = new ByteArrayOutputStream(); 
      writer = new PrintWriter(contentBuffer); 
     }  
     return writer; 
    } 
    public String getContent(){ 
     try { 
      writer = getWriter(); 
     } catch (IOException e) {   
      e.printStackTrace(); 
     } 
     writer.flush(); 
     String xhtmlContent = new String(contentBuffer.toByteArray());     
     System.out.println(xhtmlContent);     
     return xhtmlContent; 
    } 
} 

Et le code de filtre est le suivant:

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException { 

     HttpServletRequest request = (HttpServletRequest) req; 
     HttpServletResponse response = (HttpServletResponse) resp; 
     final String renderType = request.getParameter("R"); 
     final String renderClassName = request.getParameter("C"); 
     if ((renderType != null) && (renderClassName != null)) { 
      try { 
       this.setFilterChain(filterChain); 
       response.setContentType("image/png"); 
       PrintWriter out = response.getWriter();        
       // I call getWriter but not BOTH! 
       //response.getOutputStream();    
       response.getWriter(); 

       // Build up the HTML document into a string. 
        CaptureResponse capContent = new CaptureResponse(response);    
       this.mainFilterChain.doFilter(req,); 
       String myString = capHtmlContent.getContent(); 

       // What I really want to do here is output an output stream 
       // so I can write a binary image 
       processStr(myString); 
       response.getOutputStream();    
       response.write(binaryimage) 

      } catch (Exception e) {    
       e.printStackTrace(); 
      } 
      // No data will be output to the user. 
     } else { 
      filterChain.doFilter(request, response); 
     } // End of if-else   
    } // End of the method. 

Le code fonctionne si je veux prendre un document texte html d'entrée. Je suppose en raison du flux de l'éditeur libre. Mais j'ai du mal à passer à un format différent. Fondamentalement, parce que je ne peux pas appeler response.getOutputStream()

+0

Je pense que je l'ai compris. Je peux utiliser 'response.getOutputstream'. Mais j'avais un code dans lequel le navigateur ne reconstruisait pas la page, il semblait donc que je recevais une réponse nulle. Fondamentalement, mon approche va fonctionner. –

+0

Pouvez-vous expliquer pourquoi vous avez besoin d'utiliser response.getWriter()? –

+0

En fait, je peux être un peu perdu. Il semble que cela puisse être un bug avec Websphere 6.1/RAD7. Sur response.getWriter(), j'ai pensé que j'en avais besoin parce que quand je l'utilise, le code a fonctionné correctement. –

Répondre

3

La question ne semble être que vous ouvrez la réponse Writer avant envelopper la réponse.

Il semble que vous devriez être en mesure de le faire:

this.setFilterChain(filterChain); 
CaptureContent capContent = new CaptureResponse(response); 
doFilter() 
process(); 
response.setContentType("image/png"); 
response.getOutputStream().write(imagedata); 

Vous pouvez certainement pas ouvrir à la fois en toute sécurité l'écrivain et le OutputStream

+0

Oui, j'ai essayé ça. Et c'est ce que je pensais. Mais pour une raison quelconque avec Websphere, pour que les choses fonctionnent correctement, j'ai dû «ouvrir l'éditeur d'impression» avant d'appeler chain.doFilter (wrapper). Je suppose qu'un écrivain d'impression doit être ouvert pour rejoindre le contenu html. J'ai fini par utiliser une session attr et rediriger. –

+0

Parce que je ne voudrais pas 'collecter/joindre' le contenu html dans la même requête. Donc, je viens de transférer à une servlet simple qui à son tour la sortie du fichier binaire. c'est étrange, mais ça a marché. –

0

Je n'ai aucune expérience avec Websphere, mais un problème commun est que vous essayez de manipuler l'en-tête HTTP après que vous avez déjà commis à l'envoi du corps - une fois le serveur web commencé à livrer le contenu, vous ne pouvez plus mettre à jour les en-têtes car ils ont déjà été envoyés.

Vous avez peut-être besoin de revoir votre documentation et vos exemples. Par exemple, je ne vois pas pourquoi vous appelez response.get *() sans réellement regarder le résultat. Êtes-vous sûr que c'est nécessaire ou est-ce parce que vous avez réduit votre code?

Cheers, Volker

Questions connexes