vickzhu

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  151 随笔 :: 0 文章 :: 34 评论 :: 0 Trackbacks

#

 

1.
tomcat5
jsp出现getOutputStream() has already been called for this response异常的原因和解决方法

tomcat5jsp中出现此错误一般都是在jsp中使用了输出流(如输出图片验证码,文件下载等),
没有妥善处理好的原因。
具体的原因就是
tomcatjsp编译成servlet之后在函数_jspService(HttpServletRequest request, HttpServletResponse response)的最后
有一段这样的代码
finally {
    if (_jspxFactory != null) _jspxFactory.releasePageContext(_jspx_page_context);
  }
这里是在释放在jsp中使用的对象,会调用response.getWriter(),因为这个方法是和
response.getOutputStream()
相冲突的!所以会出现以上这个异常。

然后当然是要提出解决的办法,其实挺简单的(并不是和某些朋友说的那样--
jsp内的所有空格和回车符号所有都删除掉),

在使用完输出流以后调用以下两行代码即可:
out.clear();
out = pageContext.pushBody();

最后这里是一个输出彩色验证码例子(这样的例子几乎随处可见)
imag.jsp

<%@ page import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" %>
<%@ page import="java.io.OutputStream" %>
<%!
Color getRandColor(int fc,int bc){
Random random = new Random();
if(fc>255) fc=255;
if(bc>255) bc=255;
int r=fc+random.nextInt(bc-fc);
int g=fc+random.nextInt(bc-fc);
int b=fc+random.nextInt(bc-fc);
return new Color(r,g,b);
}
%>
<%
try{
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires", 0);
int width=60, height=20;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
OutputStream os=response.getOutputStream();
Graphics g = image.getGraphics();
Random random = new Random();
g.setColor(getRandColor(200,250));
g.fillRect(0, 0, width, height);

g.setFont(new Font("Times New Roman",Font.PLAIN,18));
g.setColor(getRandColor(160,200));
for (int i=0;i<155;i++)
{
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(12);
int yl = random.nextInt(12);
g.drawLine(x,y,x+xl,y+yl);
}
String sRand="";
for (int i=0;i<4;i++){
String rand=String.valueOf(random.nextInt(10));
sRand+=rand;
g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));
g.drawString(rand,13*i+6,16);
}
session.setAttribute("rand",sRand);
g.dispose();

ImageIO.write(image, "JPEG",os);
os.flush();
os.close();
os=null;
response.flushBuffer();
out.clear();
out = pageContext.pushBody();
}
catch(IllegalStateException e)
{
System.out.println(e.getMessage());
e.printStackTrace();
}%>

2
getOutputStream() has already been called for this response
问题的解决
jsp向页面输出图片的时候,使用response.getOutputStream()会有这样的提示:java.lang.IllegalStateException:getOutputStream() has already been called for this response,会抛出Exception

原因一:
JSP
默认的输出流为PrintWriter ,<% %>以外的东西所默认的输出方式,如果你尝试在JSP中使用ServletOutputStream就会引起错误.要嘛直接改用Servlet输出(复写service方法),要嘛删除除%><%中的任何东西(包括HTML标签,空格,回车等东西)应该就可以。
对于这样的情况应该这样来解决,删除%><%之间的所有内容包括空格和换行符,最后也要消除空格和换行符,最好再加上一句response.reset()
原因二:
 
J2EEAPI参考里有这么个:

ServletResponse
getWriter()方法里会抛出这个异常,

IllegalStateException - if the getOutputStream method has already been called
for this response object

而它的getOutputStream()方法里会抛出这个异常.

IllegalStateException - if the getOutputStream method has already been called for this response object

并且两者的函数申明里都有这么样的一句
Either this method or getOutputStream() may be called to write the body, not both.
Either this method or getWriter() may be called to write the body, not both.

以上说明也解释了为什么在往页面中写入图片的时候要使用如下循环格式
OutputStream output=response.getOutputStream();
while((len=in.read(b)) >0)
{
output.write(b,0,len);

}
output.flush();
而不是把response.getOutputStream().write()放到循环体内

posted @ 2008-08-15 11:34 筱 筱 阅读(683) | 评论 (0)编辑 收藏

//document构造工厂,学过工厂模式的都知道
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
//document构造器
DocumentBuilder db=dbf.newDocumentBuilder();
//StringReader用来将字符串转化为流
StringReader sr=new StringReader("str");
InputSource is=new InputSource(sr);
//转换document
Document doc=db.parse(is);
posted @ 2008-08-14 17:54 筱 筱 阅读(1982) | 评论 (0)编辑 收藏

       我要抓取的页面的完整路径为:http://www.google.cn/language_tools?hl=zh-CN

       String strServer=
"www.google.cn";//这里同样可以用ip来访问:203.208.35.100

       String strPage="/language_tools?hl=zh-CN";

       try {

           String hostname = strServer;

           int port = 80;

           InetAddress addr = InetAddress.getByName(hostname);

           Socket socket = new Socket(addr, port);

           BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF8"));

           wr.write("GET " + strPage + " HTTP/1.0"r"n");

           wr.write("HOST:" + strServer + ""r"n");

           wr.write(""r"n");

           wr.flush();

           BufferedReader rd = new BufferedReader(new InputStreamReader(socket.getInputStream()));

           String line;

           while ((line = rd.readLine()) != null) {

              System.out.println(line);

           }

           wr.close();

           rd.close();

       } catch (Exception e) {

           System.out.println(e.toString());

       }

posted @ 2008-08-14 16:52 筱 筱 阅读(406) | 评论 (0)编辑 收藏

   一、<c:forEarch>
             

     <c:forEach items="${docList}"var="doc" varStatus="li">

        <tr>

           <td>

              <a href="doc.action?URL=<%=URLEncoder.encode("ID="+((Map)pageContext.getAttribute("doc")).get("ID")) >">${doc.title }</a>

           </td>

        </tr>

     </c:forEach>

            由此可见,forEarch中变量保存的范围为pageContext

    二、<ww:iterator>
             

      <ww:iterator value="#request['questions']" id="question" status="li">

          <div class="layer_con">

              <ul>

                  <li class="layer_p">

                      <a href="details.action?qstID=<%=((Question)request.getAttribute("question")).getID() %>"></a>

                  </li>

              </ul>

          </div>       

      </ww:iterator>

            webwork是将变量保存在request中的
    三、struts的迭代变量保存在pageContext里
posted @ 2008-08-13 15:57 筱 筱 阅读(1559) | 评论 (0)编辑 收藏

得到当前元素并改变背景色:
         <script type="text/javascript"> 
             function changeColor(src){
              var obj=document.getElementsByTagName("td");
              for (i=0;i<obj.length;i++ ) 
             { 
               obj[i].style.backgroundColor="white"; 
             }

            src.style.backgroundColor="red";
             src.children.tags('a')[0].style.backgroundColor="cyan";
             alert(src.parentElement.tagName);
             }
            </script>

        <table>
            <tr>
                <td onclick="javascript:changeColor(this)"><a>aaa</a></td>
                <td onclick="javascirpt:changeColor(this)"><a>bbb</a></td>
                <td onclick="javascirpt:changeColor(this)"><a>ccc</a></td>
            </tr>
        </table>
    

注:改变背景图片
        obj[i].style.background="url(http://localhost:8080/images/abcimg.gif)";
posted @ 2008-08-04 11:15 筱 筱 阅读(1738) | 评论 (0)编辑 收藏

仅列出标题
共9页: 上一页 1 2 3 4 5 6 7 8 9