If you have plenty of memory in your server, and not too much images, simply preload everything in memory, but I must acknowledge it may not be a real option.
But your problem is really a question of caching the accesses to the database. It is easy to use one single query for the whole page, with the option of caching it for the duration of the session, depending on the disponible memory and the expected number of concurrent sessions.
Princips : in this answer, I will not separate the controller, service and database layers for brevity. As you get listaNews
form the request attributes, I assume that you allready have a servlet that calculate this list put it in a request attribute and forward to your JSP.
This servlet will load all the images from listaNews
from database, and store them in session. Then ShowImage
searches the image in session (if it is not there for any reason it should load it from database) and returns it. Optionaly, it removes it from session if saving memory is a concern.
I would implement it that way, using a count to send for evicting cached images from session - if <0, never evict, if >0 number of send before cache evict (1 for normal case) :
CachedImage
: keeps image bytes and the number of times it can be sent
public class CachedImage {
private static final int BUFFER_SIZE = 32768; // 32k buf
byte[] data;
int toSend;
public CachedImage(int toSend, InputStream is) throws IOException {
byte[] buffer = new byte[BUFFER_SIZE];
ByteArrayOutputStream os = new ByteArrayOutputStream();
while (is.read(buffer) != -1) {
os.write(buffer);
}
data = os.toByteArray();
}
}
Modification in the servlet that prepares the page :
@Override
protected void service(HttpServletRequest hsr, HttpServletResponse hsr1) throws ServletException, IOException {
final int TO_SEND = 1; //number of time each image should be downloaded before purge (-1 = no purge)
HashMap<String, CachedImage> images = new HashMap<String, CachedImage>();
...
// calculates listaNews
// loads all the images from database and store them in session
for(...) { // loops for the images key id , InputStream is
images.put(id, new CachedImage(TO_SEND, is));
}
HttpSession session = hsr.getSession();
session.setAttribute("cachedImages", images);
}
ShowImage :
@Override
protected void service(HttpServletRequest hsr, HttpServletResponse hsr1) throws ServletException, IOException {
String id = hsr.getParameter("idI");
HttpSession session = hsr.getSession();
Map<String,CachedImage> images = (Map<String,CachedImage>) session.getAttribute("cachedImages");
if (images != null) { // Ok map is in session
CachedImage cached = images.get(id);
if (cached != null) { // ok image is in cache
if (cached.toSend > 0) { // if relevant, evict image from session cache
if (--cached.toSend == 0) {
images.remove(id);
}
}
}
//send cached image : cached.data
}
// load image from database and send it
}