在我的 JSP/HTML 文件中,我使用以下 servlet 从 MySQL 数据库中获取 blob 图像。
<img src="/image?id=1" />
图像 servlet
这被映射到一个 imageservlet,他:
- 获取无状态 session bean 注入(inject)
- 使用 session bean 查找产品,基于传递给 servlet 的 id
- 将此图像作为响应流出
public class Image extends HttpServlet {
@EJB
private ProductLocal productBean;
protected void processRequest(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
long id = 0;
Product product = null;
String possibleID = request.getParameter("id");
if(possibleID == null){
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
// Try to parse id
try{
id = Long.parseLong(possibleID);
product = productBean.getById(id);
if(product == null) throw new NullPointerException("Product not found");
} catch(NumberFormatException e){
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
} catch(NullPointerException e){
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
// Serve image
byte[] image = product.getImage();
response.setContentType(product.getImageContentType());
response.setContentLength(image.length);
ServletOutputStream output = response.getOutputStream();
for(int i = 0; i < image.length; i++){
output.write(image[i]);
}
output.flush();
output.close();
}
}
产品 bean :
@Stateless
public class ProductBean implements ProductLocal {
@PersistenceContext(unitName="xxx")
private EntityManager em;
public Product getById(long id) {
return em.find(Product.class, id);
}
}
产品(实体bean)
@Entity
public class Product implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Lob
private byte[] image;
private String imageContentType;
/* getters and setters */
}
问题
当迭代一页产品时,比如 15,servlet 被调用 15 次,因此我得到相同的结果(尽管 ID 的顺序不同):
有些图像总是挂起,直到它们超时(15 秒。在上面的 Firebug 中显示)。服务器是 Glassfish v2.1(集成在 Netbeans 6.7.1 中)。起初超时是 30 秒,所以我开始在 Glassfish 中设置不同的超时值来缩小问题范围。其中一个超时是 HttpService -> Keep Alive -> Timeout,我(作为唯一的)坐了 15 秒。重新启动 GF 后,firebug 现在会在 15 秒后报告超时。而不是默认的 30。由于我在 GF 中设置了不同的超时,我很确定问题与 Keep-Alive 有关。这是我在此选项卡中的其余设置:
这是与 NetBeans 捆绑在一起的版本的开箱即用配置,除了更改超时值外我没有做任何事情。我的问题:这是由 Glassfish 中的错误设置引起的,还是我的 ImageServlet 或其他代码的问题引起的?
最佳答案
这可能与以下事实有关:您在 Servlet 中检索到的 EJB 实例以某种方式锁定了向同一 servlet 发出请求的其他线程。我有几个建议:
1) 要知道确切的答案,您应该进行线程转储,然后您将看到哪个线程阻碍了其他线程或哪些线程正在忙着做什么。
2) 另一个想法是尝试在每个请求上检索 EJB 实例。当然,这不是完美的解决方案,但也许它会让您免于遇到一些锁定问题。如果有帮助,那么您可以在后面引入一个 EJB 池。但在任何情况下,我都建议走第一条路,以获取有关正在发生的事情的更多信息。
关于java - 当从 imageservlet 提供多个 blob 图像时,Glassfish 挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1817706/