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