2011-01-10 11 views
1

EDIT:この問題の原因は、サーブレットとは無関係のバグが原因でした。サーブレット経由でJSFを使用してデータベースから画像を表示する際の問題

私はユーザーが自分の写真をアップロードしてデータベースに保存できるようにするJSF2/JPA/EJB3プロジェクトに取り組んでいます。データベースからのイメージのロードは、サーブレットで可能になります。しかし、問題があります。画像を変更してページを投稿すると、画像は空白になります。サーブレットは呼び出されていないようです。

Webページ:

<h:form> 
    <h:graphicImage value="image?fileId=#{bean.currentUser.photo.id}"/> 
    <3rd party file upload component (primeFaces)/> 
    <h:commandButton value="post"/> 
</h:form> 

サーブレットマッピング:

<servlet> 
    <servlet-name>imageServlet</servlet-name> 
    <servlet-class>com.xdin.competence.jsf.util.ImageServlet</servlet-class> 
</servlet> 
<servlet-mapping> 
    <servlet-name>imageServlet</servlet-name> 
    <url-pattern>/image/*</url-pattern> 
</servlet-mapping> 

サーブレット:

@ManagedBean 
public class ImageServlet extends HttpServlet { 
    private static final int DEFAULT_BUFFER_SIZE = 10240; // 10KB. 
    @EJB private UserBean userBean; 

    @Override 
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException 
    { 
     Long fileId = Long.parseLong(request.getParameter("fileId")); 
     if (fileId == null) { 
      response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404. 
     return; 
     } 
     UserFile photo = userBean.findUserFile(fileId); 
     // Init servlet response. 
     response.reset(); 
     response.setBufferSize(DEFAULT_BUFFER_SIZE); 
     response.setContentType("image/png"); 
     response.setHeader("Content-Length", String.valueOf(photo.getFileData().length)); 
     response.setHeader("Content-Disposition", "inline; filename=\"" + photo.getFilename() + "\""); 

     // Prepare streams. 
     BufferedInputStream input = null; 
     BufferedOutputStream output = null; 

     try { 
      // Open streams. 
      input = new BufferedInputStream(new ByteArrayInputStream(photo.getFileData()), DEFAULT_BUFFER_SIZE); 
      output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE); 

      // Write file contents to response. 
      byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; 
      int length; 
      while ((length = input.read(buffer)) > 0) { 
       output.write(buffer, 0, length); 
      } 
     } finally { 
      // Gently close streams. 
      close(output); 
      close(input); 
     } 
    } 

    private static void close(Closeable resource) { 
     if (resource != null) { 
      try { 
       resource.close(); 
      } catch (IOException e) { 
       // Do your thing with the exception. Print it, log it or mail it. 
       e.printStackTrace(); 
      } 
     } 
    } 

私の推測ではImageServlet内のdoGetは、取得のみで呼び出されていることです。 faces-redirect = trueで強制的に新しいGETが動作しますが、サーブレットをPOSTでも動作させることは可能ですか?

答えて

4

画像は、<img>要素を含むHTMLページを含むHTTP応答の一部としてダウンロードされると考えられます。本当じゃない。ブラウザはHTMLページを取得し、HTML構造を解析し、<img>要素を検出し、別々の HTTP要求をそれぞれ発します。 常に GETです。同じことがCSS/JSや他のリソースにも当てはまります。 FirebugのようなHTTPリクエストデバッガーツールをインストールし、ネットパネルを確認してください。

実際には、src属性で定義されているURLが間違っている可能性があります。コンテキスト相対パスを使用しています(src属性にはスラッシュとドメインがありません。ブラウザのアドレスバーにある現在のリクエストURLに完全に依存しています)。おそらく、HTMLページが別のコンテキスト/フォルダに投稿され、画像がその場所から到達不能になっている可能性があります。絶対パスまたはドメイン相対パスを使用してみてください。

<h:graphicImage value="#{request.contextPath}/image?fileId=#{bean.currentUser.photo.id}" /> 

Firebugの分析を詳しく見てみましょう。

+0

私のコントローラのバグで、currentUserが古くなりました。 value = "image?fileId = ..."は、Webページがルートにあるため、この特定の場合に機能します。答えをありがとう、私はポストの後にイメージが取り込まれた方法について混乱したabitでした。 –

関連する問題