bianbian coding life

便便代码人生: 关注技术, 翻译文档, 偶尔动动手

bianbian.org

[原]利用HttpServletResponseWrapper获取jsp输出内容

Posted by bianbian on 2006-08-29 19:17


本文Tags:

有时候我们需要得到某个jsp的输出内容。比如说在servlet里处理了Module Controller后,需要不同的jsp页面来展示view;又或者得到不同的模板内容(jsp本身可以作为模板语言)并将其缓冲到内存里。
利用 javax.servlet.http.HttpServletResponseWrapper 可以很好地实现我们所需要的功能。下面是使用方法:

  1. ....
  2. public static String getJspOutput(String jsppath, HttpServletRequest request, HttpServletResponse response)
  3.     throws Exception
  4. {
  5.     WrapperResponse wrapperResponse = new WrapperResponse(response);
  6.     request.getRequestDispatcher(jsppath).include(request, wrapperResponse);
  7.     return wrapperResponse.getContent();
  8. }

可以看到,使用起来还是挺方便的。getJspOutput(”/view/header.jsp”, request, response) 就完成了对”/view/header.jsp”的输出内容获取,之后可以进行其他操作。
附WrapperResponse类代码:

  1. import java.io.ByteArrayOutputStream;
  2. import java.io.IOException;
  3. import java.io.PrintWriter;
  4. import java.io.UnsupportedEncodingException;
  5.  
  6. import javax.servlet.ServletOutputStream;
  7. import javax.servlet.http.HttpServletResponse;
  8. import javax.servlet.http.HttpServletResponseWrapper
  9. /**
  10. * @see http://bianbian.sunshow.net/
  11. * @author dannyzhu, bianbian
  12. * @version 1.0
  13. */
  14. public class WrapperResponse extends HttpServletResponseWrapper
  15. {
  16.     private PrintWriter tmpWriter;
  17.     private ByteArrayOutputStream output;
  18.     private ByteArrayServletOutputStream servletOutput;
  19.  
  20.     public WrapperResponse(HttpServletResponse httpServletResponse)
  21.     {
  22.         super(httpServletResponse);
  23.         output = new ByteArrayOutputStream();
  24.         tmpWriter = new PrintWriter(output);
  25.         servletOutput = new ByteArrayServletOutputStream(output);
  26.     }
  27.  
  28.     public void finalize() throws Throwable
  29.     {
  30.         super.finalize();
  31.         servletOutput.close();
  32.         output.close();
  33.         tmpWriter.close();
  34.     }
  35.  
  36.     public String getContent()
  37.     {
  38.         try{
  39.             String s = output.toString("UTF-8");
  40.             reset();
  41.             return s;
  42.         } catch(UnsupportedEncodingException e) {
  43.             return "UnsupportedEncoding";
  44.         }
  45.     }
  46.  
  47.     public PrintWriter getWriter() throws IOException
  48.     {
  49.         // return servletResponse.getWriter();
  50.         return tmpWriter;
  51.     }
  52.  
  53.     public ServletOutputStream getOutputStream() throws IOException
  54.     {
  55.         return servletOutput;
  56.     }
  57.  
  58.     public byte[] toByteArray()
  59.     {
  60.         return output.toByteArray();
  61.     }
  62.  
  63.     public void flushBuffer() throws IOException
  64.     {
  65.         tmpWriter.flush();
  66.         servletOutput.flush();
  67.     }
  68.  
  69.     public void reset()
  70.     {
  71.         output.reset();
  72.     }
  73.  
  74.     public void close() throws IOException
  75.     {
  76.         tmpWriter.close();
  77.     }
  78.  
  79.     private static class ByteArrayServletOutputStream extends ServletOutputStream
  80.     {
  81.  
  82.         ByteArrayOutputStream baos;
  83.  
  84.         public ByteArrayServletOutputStream(ByteArrayOutputStream baos)
  85.         {
  86.             this.baos = baos;
  87.         }
  88.  
  89.         public void write(int i) throws IOException
  90.         {
  91.             baos.write(i);
  92.         }
  93.  
  94.     }
  95. }
标签:

遵守创作共用协议,转载请链接形式注明来自http://bianbian.org 做人要厚道

相关日志

Posted in Java, Technology | No Comments »

[原]利用JavaScript解析UBB标签生成HTML

Posted by bianbian on 2006-08-27 18:11


本文Tags: , ,

UBB标签作为HTML标签的安全替代,在网络上应用已经十分广泛。常规的做法是服务器端解析,这类代码几乎泛滥,我就不贴了。唯一的问题是比较耗服务器的CPU(字符串匹配、正则匹配),其实这种活我都喜欢让客户端做。

作为演示,我下面的代码将解析[b]、[i]、[url]、[img]、[color]、[wma]、[flash]这几个常见的UBB标签。主要利用了JavaScript的正则表达式。正则表达式语法可以察看:正则表达式语法,下面代码的测试可以察看:测试UBB标签解析

  1. function text2html(s)
  2. {
  3.     if(s.indexOf("://") > 0)
  4.     {
  5.         //url
  6.         s = s.replace(/(^|[^\"\'\]])(http|ftp|mms|rstp|news|https)\:\/\/([^\s\033\[\]\"\']+)/gi, "$1[url]$2://$3[/url]");
  7.         //img
  8.         s = s.replace(/\[url\](http\:\/\/\S+\.)(gif|jpg|jpeg|png)\[\/url\]/gi, "[img]$1$2[/img]");
  9.     }
  10.     //ubb: 匹配[UBB]...[/UBB]形式
  11.     if(s.match(/\[(\w+)([^\[\]\s]*)\].*\[\/\1\]/))
  12.     {
  13.         s = s.replace(/\[url\](.+?)\[\/url\]/gi,"<a href=$1 target=_blank>$1</a>");
  14.         s = s.replace(/\[img\](.+?\.(?:gif|jpg|jpeg|png))\[\/img\]/gi, "<img src='$1' alt='$1'>");
  15.         s = s.replace(/\[flash\](.+?\.swf)\[\/flash\]/gi, "<embed src='$1' quality=high wmode=transparent type='application/x-shockwave-flash' width=400 height=300></embed><br> FLASH: <a href='$1' target=_blank>$1</a><br>");
  16.         s = s.replace(/\[wma\](.+?\.(?:wma|mp3))\[\/wma\]/gi, "<embed src='$1' height=40 AutoStart=0></embed><br> WMA: <a href='$1' target=_blank>$1</a><br>");
  17.         s = s.replace(/\[color=([#0-9a-zA-Z]{1,10})\](.+?)\[\/color\]/gi, "<font color='$1'>$2</font>");
  18.         s = s.replace(/\[b\](.+?)\[\/b\]/gi, "<b>$1</b>");
  19.         s = s.replace(/\[i\](.+?)\[\/i\]/gi, "<i>$1</i>");
  20.     }
  21.     return s;
  22. }

接下来的问题是怎样把文本传递到函数里,一个自己的经验是把待解析的文本放到textarea里,这样可以避免<和>等特殊符号的转义(即&lt;、&gt;),放到textarea里转义的工作就自动被浏览器做了。

唯一的也是比较严重的问题是待解析的文本里不能有“</textarea>”,否则浏览器会认为本文已经结束,其后的文本将被浏览器当成HTML代码——这是很危险的,想想看,用户输入“</textarea>”之后就可以插入任何HTML代码!解决的办法是服务器端输出文本内容的时候,将“</textarea”拆开,比如输出“< /textarea”或“</text area”都是可以的。要注意,不能整个搜寻替换“</textarea>”,因为有可能别有用心的用户会输入“</textarea >”,这会带来同样的问题(最近部分小百合用户的说明档被改就是因为这个漏洞)。也许你会问,这样不是服务器端每次生成页面的时候又进行字符串匹配了吗?对性能有什么提高呢?OK,我们可以在用户提交数据的时候进行这样的替换,“绝对不要相信客户端”,这是一个web程序员应该具有的基本观念。

标签: , ,

遵守创作共用协议,转载请链接形式注明来自http://bianbian.org 做人要厚道

相关日志

Posted in JavaScript, Technology | 1 Comment »

[原]小心使用JavaScript的局部和全局变量

Posted by bianbian on 2006-08-26 22:44


本文Tags: ,

一直以为自己对JavaScript已经很精通了,这次却犯了一个低级错误。这个错误带来的后果就是:如果你最近用浏览器上小百合的话,发现点击左边导航菜单的链接都会打开新窗口。。。其次的后果是害我调试了一下午加晚上。。。

先是这样的,为了DOM设置属性的方便,我自己写了个方法,省得每次都setAttribute:

  1. Net = {};
  2. Net.Dom = {};
  3. Net.Dom.setProperties = function(obj)
  4. {
  5.     for(var i=1; i<arguments.length; i++)
  6.     {
  7.         if(typeof arguments[i]=="object")
  8.         {
  9.             for(name in arguments[i])
  10.                 obj[name] = arguments[i][name];
  11.         }
  12.     }
  13. }
  14.  
  15. //这样原来:
  16. div.setAttribute("width", "100px");
  17. div.setAttribute("height", "100%");
  18. ......
  19. //就可以写成:
  20. Net.Dom.setProperties(div, {width:"100px", height: "100%"});

上面的setProperties代码里面有个错误,会导致改变window的name属性。因为window是可以省略的(直接打document其实是window.document),而“for(name in arguments[i])”的表示方法浏览器会解析成“for(window.name in arguments[i])”。也就是框架的name变了,这样左边设的target自然就失效了,导致链接都以新窗口打开。改成“for(var name in arguments[i])”就好了。

因为JavaScript相对比较自由,写变量一定要注意,而且这种错误比较隐蔽,难以发现。局部变量一定要以var申明,否则是全局变量;要用全局变量时候也要注意一下命名方法,以”g_”开头或者全大写都是可行的办法。

最后我们一起复习一下JavaScript的局部变量和全局变量:
Read the rest of this entry »

标签: ,

遵守创作共用协议,转载请链接形式注明来自http://bianbian.org 做人要厚道

相关日志

Posted in JavaScript, Technology | 1 Comment »

[哈]telnet测试一把

Posted by bianbian on 2006-08-25 22:59


本文Tags: , ,

本来想自己写的,感谢有牛人已经:http://localhost.geek.nz/telnet/ 遗憾的是他的字体库是自己写的,不支持中文;还有并不是针对bbs的,所以上下左右和Ctrl-P之类的并不支持。准备在这个的基础上做一个PSPTerm,支持中文显示和提供方便的Term操作。
附图:telnet bbs.nju.edu.cn under psp
telnet bbs.nju.edu.cn under psp

另外,推荐一下上面用到的输入法:http://www.niwra.nl/psp/p-sprint-c/doc/index.htm 能想到这个的真是牛啊。可惜没有把上下左右、Home、End之类的也搞进去。不过还是很赞了。这个世界牛人真多啊。呵呵
附输入法的软键盘一张:
psp p-sprint-c

改天等我写完PSPTerm,我会顺便把上面两个译成中文。

标签: , ,

遵守创作共用协议,转载请链接形式注明来自http://bianbian.org 做人要厚道

相关日志

Posted in Entertainment, Not IT | 5 Comments »