Reputation: 9205
I have a java program that generates a valid BufferedImage bi based on parameters that are sent to the program. I want to call this program from a servlet, and have the servlet send the user a jsp containing an image that fits the parameters that the user inputs. The code that I wrote below generates a null message instead of the requested image.
I should add that get_bi() sometimes takes a few hundred milliseconds to produce the BufferedImage on my development computer. Not sure if part of the problem is a time delay thing.
Can anyone show me how to alter the code below so that it outputs an actual image in the user's web browser instead of a null message?
Here is the code for ImageServlet:
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//import org.apache.log4j.Logger;
import myownpackage.GetBI;
public class ImageServlet extends HttpServlet{
// private Logger logger = Logger.getLogger(this.getClass());
private RequestDispatcher jsp;
public void init(ServletConfig config) throws ServletException {
ServletContext context = config.getServletContext();
jsp = context.getRequestDispatcher("/WEB-INF/jsp/send-image-into-html.jsp");
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// logger.debug("doGet()");
String imageParams = req.getParameter("imageParams");
jsp.forward(req, resp);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException{
Map<String, String> errors = validate(req);
if (!errors.isEmpty()){
// logger.debug("validation errors");
jsp.forward(req, resp);
return;
}
resp.setContentType("image/gif");
BufferedImage bi = new BufferedImage(300, 300, BufferedImage.TYPE_INT_RGB);
GetBI fetchBI = new GetBI();
bi = fetchBI.get_bi(req.getParameter("imageParams"));
File imgFile = new File("imgFile");
ImageIO.write(bi, "gif", imgFile);
resp.sendRedirect("send-image-into-html");
}
public static Map<String, String> validate(HttpServletRequest req){
HashMap<String, String> errors = new HashMap<String, String>();
req.setAttribute("errors", errors);
String imageParams = req.getParameter("imageParams");
if (imageParams == null || imageParams.trim().length() == 0){
errors.put("imageParams", "imageParams required.");
}
return errors;
}
}
The code for send-image-into-html.jsp is:
<jsp:useBean id="errors" scope="request" type="java.util.Map" class="java.util.HashMap" />
<%@ include file="top.inc" %>
<%@ include file="middle.inc" %>
<table>
<tr>
<td width=350>
<%=request.getParameter("imgFile")%>
<img src="<%=request.getParameter("imgFile")%>">
</td>
<td>
<form method="post">
<table>
<tr>
<td>Image Parameters: </td>
<td><input type="text" name="imageParams" value="some parameters" size="50" />
<% if (errors.containsKey("imageParams")) {
out.println("<span class=\"error\">" + errors.get("imageParams") + "</span>");
}%>
</td>
</tr>
<tr>
<td>
<input type="submit" name="submit-button" value="Click Here" />
</td>
</tr>
</table>
</form>
</td>
</tr>
</table>
<%@ include file="bottom.inc" %>
EDIT:
I have edited my code based on what I understand of Joop's suggestions, but it still does not work. Can you show me how to further edit this so that it works?
Here is the code for FirstServlet:
public class FirstServlet extends HttpServlet{
// private Logger logger = Logger.getLogger(this.getClass());
private RequestDispatcher jsp;
public void init(ServletConfig config) throws ServletException {
ServletContext context = config.getServletContext();
jsp = context.getRequestDispatcher("/WEB-INF/jsp/send-image-into-html.jsp");
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {// logger.debug("doGet()");
jsp.forward(req, resp);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException{
Map<String, String> errors = validate(req);
if (!errors.isEmpty()){// logger.debug("validation errors");
jsp.forward(req, resp);
return;
}
resp.sendRedirect("/send-image-into-html");
}
public static Map<String, String> validate(HttpServletRequest req){
HashMap<String, String> errors = new HashMap<String, String>();
req.setAttribute("errors", errors);
String imageParam1 = req.getParameter("imageParam1");
if (imageParam1 == null || imageParam1.trim().length() == 0){
errors.put("imageParam1", "imageParam1 required.");
}
return errors;
}
}
Here is the code for SecondServlet:
public class GetGraphServlet extends HttpServlet{
// private Logger logger = Logger.getLogger(this.getClass());
private RequestDispatcher jsp;
public void init(ServletConfig config) throws ServletException {
ServletContext context = config.getServletContext();
jsp = context.getRequestDispatcher("/WEB-INF/jsp/send-image-into-html.jsp");
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {// logger.debug("doGet()");
// Create the BufferedImage, using any parameters and
// possibly the exact request URI:
String requestURI = req.getRequestURI();
String imageParam1 = req.getParameter("imageParam1");
resp.setContentType("image/gif");//256 colors
BufferedImage bi = new BufferedImage(300, 300, BufferedImage.TYPE_INT_RGB);
GetBI fetchBI = new GetBI();
bi = fetchBI.get_bi(req.getParameter(imageParam1));
ImageIO.write(bi,"gif",resp.getOutputStream());
resp.setContentType("image/gif"); // 256 colors.
ImageIO.write(bi, "gif", resp.getOutputStream());
jsp.forward(req, resp);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException{}
}
Here is the code for send-image-into-html.jsp
<jsp:useBean id="errors" scope="request" type="java.util.Map" class="java.util.HashMap" />
<%@ include file="top.inc" %>
<%@ include file="middle.inc" %>
<form method="post">
<table>
<tr>
<td width=350>
<img src="<%="/get-graph.gif?imageParam1="%>">
</td>
<td>
<table>
<tr>
<td>imageParam1: </td>
<td><input type="text" name="imageParam1" value="samplevalue" size="50" />
<%if (errors.containsKey("imageParam1")) {
out.println("<span class=\"error\">" + errors.get("imageParam1") + "</span>");}%>
</td>
</tr>
<tr>
<td>
<input type="submit" name="submit-button" value="CreateImage"/>
</td>
</tr>
</table>
</td>
</tr>
</table>
</form>
<%@ include file="bottom.inc" %>
Here are the relevant tags from web.xml:
<servlet>
<servlet-name>FirstServlet</servlet-name>
<servlet-class>mypackage.FirstServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FirstServlet</servlet-name>
<url-pattern>/html-page-url</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>SecondServlet</servlet-name>
<servlet-class>mypackage.SecondServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SecondServlet</servlet-name>
<url-pattern>/get-graph</url-pattern>
</servlet-mapping>
Upvotes: 0
Views: 4784
Reputation: 18559
It looks like you have 3 separate requests:
GET html-page-url
(respond with send-image-into-html.jsp (containing form)).
POST html-page-url with parameter imageParam1=...
(respond with send-image-into-html.jsp (containing image)).
GET get-graph.gif with parameter imageParam1=...
(respond with gif content-type and image data).
It's important to narrow down where the problems are and tackle them one by one. Add full logging to the servlets and use a tool like FireBug/Chrome DevTools to see exactly what's happening. Look at the requests, parameters and generated html. Which URLs are correct? Which parameters are correct? Which responses are correct?
I take it the first request is working fine.
Start with the third request. This can be tested by itself by entering the url directly in the browser. Check whether you need the .gif extension and the full path.
You'll need to at least remove the duplicated lines and the jsp.forward:
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// Create the BufferedImage, using any parameters and
// possibly the exact request URI:
String requestURI = req.getRequestURI();
String imageParam1 = req.getParameter("imageParam1");
BufferedImage bi = new BufferedImage(300, 300, BufferedImage.TYPE_INT_RGB);
GetBI fetchBI = new GetBI();
bi = fetchBI.get_bi(req.getParameter(imageParam1));
resp.setContentType("image/gif");//256 colors
ImageIO.write(bi,"gif",resp.getOutputStream());
}
When the image is displayed correctly, then test the page containing the image. You now know what the url should be so look at the generated html and compare it with what you expect. Is the image src correct?
<td width=350>
<img src="<%="/get-graph.gif?imageParam1="%>">
</td>
This looks like it uses an absolute path and extension, doesn't output any parameter value, and is displayed even when the user doesn't enter an imageParam.
So the value of the imageParam1 parameter needs to be output here, probably with an if statement around it. You can use a scriplet for now like you've done elsewhere but you should look into using tag libraries like jstl.
EDIT:
I don't have a GetBI class, but I've tested this example:
public class SecondServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String imageParam1 = request.getParameter("imageParam1");
BufferedImage bi = new BufferedImage(300, 300, BufferedImage.TYPE_INT_RGB);
// Try replacing with:
//GetBI fetchBI = new GetBI();
//BufferedImage bi = fetchBI.get_bi(req.getParameter("imageParam1"));
Graphics2D g = bi.createGraphics();
g.setColor(new Color(255, 255, 255));
g.drawString(imageParam1, 0, 150);
g.dispose();
response.setContentType("image/gif");
ImageIO.write(bi, "gif", response.getOutputStream());
}
}
This displays an image with the text of imageParam1 at:
http://127.0.0.1:8080/myapp/get-graph?imageParam1=Testing
Upvotes: 1
Reputation: 36
Try this...it works 100%
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
/**
*
* @author kites
*/
public class FileUpload extends HttpServlet {
File uploadFile;
/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
long fileSize;
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
boolean bb = upload(request);
} finally {
out.close();
}
}
// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
/**
* Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Returns a short description of the servlet.
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
private boolean upload(HttpServletRequest request) {
boolean bool = false;
try {
String fileName = "";
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (isMultipart) {
System.out.println("Inside fileupload.....");
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List items = upload.parseRequest(request);
Iterator iterator = items.iterator();
// System.out.println("File content" + request.getParameter("f1"));
while (iterator.hasNext()) {
FileItem item = (FileItem) iterator.next();
FileItem item1 = item;
System.out.println("Form field:::" + item.isFormField());
if (!item.isFormField()) {
fileName = item.getName();
fileSize = item.getSize();
File f = new File("C:\\"+fileName);
String filepath=f.getAbsolutePath();
System.out.println("fileName = " + fileName);
System.out.println("fileSize = " + fileSize);
if (!fileName.equals("")) {
item.write(filepath);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return bool;
}
}
Upvotes: 0
Reputation: 109613
Use a web application path to File conversion with getRealPath
.
File imgFile = req.getServletContext().getRealPath("/images/generated.gif");
<img src="/images/generated.gif?t=<%= imgFile.lastModified() %>">
The dummy parameter t=...
is added to prevent caching.
Because of the redirect (to HTML!) not this:
//resp.setContentType("image/gif");
//resp.setContentLength((int)imgFile.length());
You could alternatively also put in img.src the servlet URL to generate the image on-the-fly without file:
resp.setContentType("image/gif");
ImageIO.write(bi, "gif", resp.getOutputStream());
Make a separate image generating servlet that returns on the response's output stream the binary data of the image. The src URL of the <img src="...?imageParam1=...&">
is mapped on this servlet.
<img src=".../... .gif?imageParam1=...&imageParam2=...">
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// Create the BufferedImage, using any parameters and
// possibly the exact request URI:
String requestURI = req.getRequestURI();
String imageParam1 = req.getParameter("imageParam1");
String imageParam2 = req.getParameter("imageParam2");
BufferedImage bi = ...
resp.setContentType("image/gif"); // 256 colors.
ImageIO.write(bi, "gif", resp.getOutputStream());
}
Upvotes: 1