Posted by bianbian on 2006-08-29 19:17
本文Tags: HttpServletResponseWrapper
有时候我们需要得到某个jsp的输出内容。比如说在servlet里处理了Module Controller后,需要不同的jsp页面来展示view;又或者得到不同的模板内容(jsp本身可以作为模板语言)并将其缓冲到内存里。
利用 javax.servlet.http.HttpServletResponseWrapper 可以很好地实现我们所需要的功能。下面是使用方法:
- ....
- public static String getJspOutput(String jsppath, HttpServletRequest request, HttpServletResponse response)
- throws Exception
- {
- WrapperResponse wrapperResponse = new WrapperResponse(response);
- request.getRequestDispatcher(jsppath).include(request, wrapperResponse);
- return wrapperResponse.getContent();
- }
可以看到,使用起来还是挺方便的。getJspOutput(”/view/header.jsp”, request, response) 就完成了对”/view/header.jsp”的输出内容获取,之后可以进行其他操作。
附WrapperResponse类代码:
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.io.UnsupportedEncodingException;
-
- import javax.servlet.ServletOutputStream;
- import javax.servlet.http.HttpServletResponse;
- import javax.servlet.http.HttpServletResponseWrapper
- /**
- * @see http://bianbian.sunshow.net/
- * @author dannyzhu, bianbian
- * @version 1.0
- */
- public class WrapperResponse extends HttpServletResponseWrapper
- {
- private PrintWriter tmpWriter;
- private ByteArrayOutputStream output;
- private ByteArrayServletOutputStream servletOutput;
-
- public WrapperResponse(HttpServletResponse httpServletResponse)
- {
- super(httpServletResponse);
- output = new ByteArrayOutputStream();
- tmpWriter = new PrintWriter(output);
- servletOutput = new ByteArrayServletOutputStream(output);
- }
-
- public void finalize() throws Throwable
- {
- super.finalize();
- servletOutput.close();
- output.close();
- tmpWriter.close();
- }
-
- public String getContent()
- {
- try{
- String s = output.toString("UTF-8");
- reset();
- return s;
- } catch(UnsupportedEncodingException e) {
- return "UnsupportedEncoding";
- }
- }
-
- public PrintWriter getWriter() throws IOException
- {
- // return servletResponse.getWriter();
- return tmpWriter;
- }
-
- public ServletOutputStream getOutputStream() throws IOException
- {
- return servletOutput;
- }
-
- public byte[] toByteArray()
- {
- return output.toByteArray();
- }
-
- public void flushBuffer() throws IOException
- {
- tmpWriter.flush();
- servletOutput.flush();
- }
-
- public void reset()
- {
- output.reset();
- }
-
- public void close() throws IOException
- {
- tmpWriter.close();
- }
-
- private static class ByteArrayServletOutputStream extends ServletOutputStream
- {
-
- ByteArrayOutputStream baos;
-
- public ByteArrayServletOutputStream(ByteArrayOutputStream baos)
- {
- this.baos = baos;
- }
-
- public void write(int i) throws IOException
- {
- baos.write(i);
- }
-
- }
- }
标签:
HttpServletResponseWrapper遵守创作共用协议,转载请链接形式注明来自
http://bianbian.org 做人要厚道
相关日志
Posted in Java, Technology | No Comments »
Posted by bianbian on 2006-08-27 18:11
本文Tags: HTML, JavaScript, UBB
UBB标签作为HTML标签的安全替代,在网络上应用已经十分广泛。常规的做法是服务器端解析,这类代码几乎泛滥,我就不贴了。唯一的问题是比较耗服务器的CPU(字符串匹配、正则匹配),其实这种活我都喜欢让客户端做。
作为演示,我下面的代码将解析[b]、[i]、[url]、[img]、[color]、[wma]、[flash]这几个常见的UBB标签。主要利用了JavaScript的正则表达式。正则表达式语法可以察看:正则表达式语法,下面代码的测试可以察看:测试UBB标签解析。
- function text2html(s)
- {
- if(s.indexOf("://") > 0)
- {
- //url
- s = s.replace(/(^|[^\"\'\]])(http|ftp|mms|rstp|news|https)\:\/\/([^\s\033\[\]\"\']+)/gi, "$1[url]$2://$3[/url]");
- //img
- s = s.replace(/\[url\](http\:\/\/\S+\.)(gif|jpg|jpeg|png)\[\/url\]/gi, "[img]$1$2[/img]");
- }
- //ubb: 匹配[UBB]...[/UBB]形式
- if(s.match(/\[(\w+)([^\[\]\s]*)\].*\[\/\1\]/))
- {
- s = s.replace(/\[url\](.+?)\[\/url\]/gi,"<a href=$1 target=_blank>$1</a>");
- s = s.replace(/\[img\](.+?\.(?:gif|jpg|jpeg|png))\[\/img\]/gi, "<img src='$1' alt='$1'>");
- 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>");
- 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>");
- s = s.replace(/\[color=([#0-9a-zA-Z]{1,10})\](.+?)\[\/color\]/gi, "<font color='$1'>$2</font>");
- s = s.replace(/\[b\](.+?)\[\/b\]/gi, "<b>$1</b>");
- s = s.replace(/\[i\](.+?)\[\/i\]/gi, "<i>$1</i>");
- }
- return s;
- }
接下来的问题是怎样把文本传递到函数里,一个自己的经验是把待解析的文本放到textarea里,这样可以避免<和>等特殊符号的转义(即<、>),放到textarea里转义的工作就自动被浏览器做了。
唯一的也是比较严重的问题是待解析的文本里不能有“</textarea>”,否则浏览器会认为本文已经结束,其后的文本将被浏览器当成HTML代码——这是很危险的,想想看,用户输入“</textarea>”之后就可以插入任何HTML代码!解决的办法是服务器端输出文本内容的时候,将“</textarea”拆开,比如输出“< /textarea”或“</text area”都是可以的。要注意,不能整个搜寻替换“</textarea>”,因为有可能别有用心的用户会输入“</textarea >”,这会带来同样的问题(最近部分小百合用户的说明档被改就是因为这个漏洞)。也许你会问,这样不是服务器端每次生成页面的时候又进行字符串匹配了吗?对性能有什么提高呢?OK,我们可以在用户提交数据的时候进行这样的替换,“绝对不要相信客户端”,这是一个web程序员应该具有的基本观念。
标签:
HTML,
JavaScript,
UBB遵守创作共用协议,转载请链接形式注明来自
http://bianbian.org 做人要厚道
相关日志
Posted in JavaScript, Technology | 1 Comment »
Posted by bianbian on 2006-08-26 22:44
本文Tags: JavaScript, 全局变量
一直以为自己对JavaScript已经很精通了,这次却犯了一个低级错误。这个错误带来的后果就是:如果你最近用浏览器上小百合的话,发现点击左边导航菜单的链接都会打开新窗口。。。其次的后果是害我调试了一下午加晚上。。。
先是这样的,为了DOM设置属性的方便,我自己写了个方法,省得每次都setAttribute:
- Net = {};
- Net.Dom = {};
- Net.Dom.setProperties = function(obj)
- {
- for(var i=1; i<arguments.length; i++)
- {
- if(typeof arguments[i]=="object")
- {
- for(name in arguments[i])
- obj[name] = arguments[i][name];
- }
- }
- }
-
- //这样原来:
- div.setAttribute("width", "100px");
- div.setAttribute("height", "100%");
- ......
- //就可以写成:
- 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 »
标签:
JavaScript,
全局变量遵守创作共用协议,转载请链接形式注明来自
http://bianbian.org 做人要厚道
相关日志
Posted in JavaScript, Technology | 1 Comment »
Posted by bianbian on 2006-08-25 22:59
本文Tags: PSP, telnet, 测试
本来想自己写的,感谢有牛人已经:http://localhost.geek.nz/telnet/ 遗憾的是他的字体库是自己写的,不支持中文;还有并不是针对bbs的,所以上下左右和Ctrl-P之类的并不支持。准备在这个的基础上做一个PSPTerm,支持中文显示和提供方便的Term操作。
附图:telnet bbs.nju.edu.cn under psp

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

改天等我写完PSPTerm,我会顺便把上面两个译成中文。
标签:
PSP,
telnet,
测试遵守创作共用协议,转载请链接形式注明来自
http://bianbian.org 做人要厚道
相关日志
Posted in Entertainment, Not IT | 5 Comments »