Reputation: 65
I try to put image generate in dynamic way using Spring mvc controller.
@Controller
@RequestMapping("/")
public String generateMik(final HttpServletResponse response){
...
BufferdImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
...
response.setContentType("image/png");
try {
OutputStream os = response.getOutputStream();
ImageIO.write(buffer, "png", os);
os.flush();
os.close();
...
}
And i show this picture in .jsp :
<img src="picture" id="picture">
All works fine, picture show in my browser, but i got a exception and i don't have any idea to resolve this problem in normal why (i don't wanna to catch this exception).
org.apache.catalina.core.ApplicationDispatcher invoke
SEVERE: Servlet.service() for servlet jsp threw exception
java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:626)
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:215)
at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118)
at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:190)
...
And my question is: how i can generate dynamic picture in possibly simples way? I don't wanna to temporary save picture. Maybe put to model outputStream and show in somehow magic way in jsp?
Upvotes: 0
Views: 4421
Reputation: 139931
You need to annotate the @RequestMapping
method that is writing the image to the stream with @ResponseBody
to tell Spring MVC not to try to find a view to use to render the response. You use @ResponseBody
on any methods where you are handling writing to the output stream yourself.
Since your @RequestMapping
method returns a String
, Spring interprets the response value of your method as the name of the view it should use in rendering the response.
You are seeing the exception because you are writing (and closing) the response stream, and then Spring MVC tries to invoke a view class to write to the same response stream.
Upvotes: 3
Reputation: 6273
i think this is due to you have return parameter in controller method which ask spring to forward request to particular view.
you should have return type as void.
public void generateMik(final HttpServletResponse response)
Upvotes: 3
Reputation: 3070
This one works fine for me:
@RequestMapping(value = "/img", method = RequestMethod.GET)
public @ResponseBody void getImage(HttpServletResponse response)
{
BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
response.setContentType("image/png");
OutputStream out;
try
{
out = response.getOutputStream();
ImageIO.write(image, "png", out);
out.close();
}
catch (IOException ex)
{
Logger.getLogger(IndexController.class.getName()).log(Level.SEVERE, null, ex);
}
}
BUT, I'm 99,8% sure there's a smarter way to do it.
Upvotes: 1