1. 程式人生 > >解決getOutputStream() has already been called for this response

解決getOutputStream() has already been called for this response

getOutputStream() has already been called for this response異常出現的原因和解決方法:

jsp中出現此錯誤一般都是在jsp中使用了輸出流(如輸出圖片驗證碼,檔案下載等),沒有妥善處理好的原因。


具體的原因:jsp編譯成servlet之後在函式

_jspService(HttpServletRequest request, HttpServletResponse response)

的最後
有一段這樣的程式碼

Java程式碼  收藏程式碼
  1. finally {  
  2.       if (_jspxFactory != null)   
  3.           _jspxFactory.releasePageContext(_jspx_page_context);  
  4. }  

這裡是在釋放在jsp中使用的物件,會呼叫response.getWriter(),因為這個方法是和response.getOutputStream()相沖突的!所以會出現以上這個異常。然後當然是要提出解決的辦法,其實挺簡單的,在使用完輸出流以後呼叫以下兩行程式碼即可:

Java程式碼  收藏程式碼
  1. out.clear();  
  2. out = pageContext.pushBody();  

最後這裡是一個輸出彩色驗證碼例子(這樣的例子幾乎隨處可見)。

Java程式碼  收藏程式碼
  1. <%@ page  import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" %>  
  2. <%@ page import="java.io.OutputStream" %>  
  3. <%!  
  4. Color getRandColor(int fc,int bc){  
  5. Random random = new Random();  
  6. if(fc>255) fc=255;  
  7. if(bc>255) bc=255;  
  8. int r=fc+random.nextInt(bc-fc);  
  9. int g=fc+random.nextInt(bc-fc);  
  10. int b=fc+random.nextInt(bc-fc);  
  11. return new Color(r,g,b);  
  12. }  
  13. %>  
  14. <%  
  15. try{  
  16. response.setHeader("Pragma","No-cache");  
  17. response.setHeader("Cache-Control","no-cache");  
  18. response.setDateHeader("Expires"0);  
  19. int width=60, height=20;  
  20. BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);  
  21. OutputStream os=response.getOutputStream();  
  22. Graphics g = image.getGraphics();  
  23. Random random = new Random();  
  24. g.setColor(getRandColor(200,250));  
  25. g.fillRect(00, width, height);  
  26. g.setFont(new Font("Times New Roman",Font.PLAIN,18));  
  27. g.setColor(getRandColor(160,200));  
  28. for (int i=0;i<155;i++)  
  29. {  
  30. int x = random.nextInt(width);  
  31. int y = random.nextInt(height);  
  32. int xl = random.nextInt(12);  
  33. int yl = random.nextInt(12);  
  34. g.drawLine(x,y,x+xl,y+yl);  
  35. }  
  36. String sRand="";  
  37. for (int i=0;i<4;i++){  
  38. String rand=String.valueOf(random.nextInt(10));  
  39. sRand+=rand;  
  40. g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));  
  41. g.drawString(rand,13*i+6,16);  
  42. }  
  43. session.setAttribute("rand",sRand);  
  44. g.dispose();  
  45. ImageIO.write(image, "JPEG",os);  
  46. //注意看以下幾句的使用  
  47. os.flush();  
  48. os.close();  
  49. os=null;  
  50. response.flushBuffer();  
  51. out.clear();  
  52. out = pageContext.pushBody();  
  53. }  
  54. catch(IllegalStateException e)  
  55. {  
  56. System.out.println(e.getMessage());  
  57. e.printStackTrace();  
  58. }%>  

如果寫檔案是在java類中實現,可參考如下程式碼:

Java程式碼  收藏程式碼
  1. FileOutputStream out = new FileOutputStream(file,true);  
  2. out.write(new byte[]{(byte)0xEF, (byte)0xBB, (byte)0xBF});//utf-8 bom  
  3. out.write(content.getBytes(charset));  
  4. out.close();  

原文地址:http://qify.iteye.com/blog/747842