[Miles' Blog]

Welcome 2 My Planet

Available categories: [/] [development. ~] [working on downwap.] [trouble shooting] [working on Yup Mailman] [general infomation.] [life style]

ContentType不可以反复设置? [Permalink]

Wed Sep 15 10:11:55 CST 2004
Category [working on Yup Mailman]

发现一个新问题,就是JTextPane的ContentType在被设置成text/html后,重新设置成text/plain就会报IllegalArgumentException: Must be StyledEditorKit
我估计可能是因为text/plain无法保证text/html所拥有的格式导致的。。总之api doc上面没有说明。

BTW,新的YupStudio logo和Mailman的icon:

   

Posted by: miles
Comments [0] |

Yup Mailman - 我们的自用群发软件 [Permalink]

Wed Sep 15 10:04:09 CST 2004
Category [working on Yup Mailman]

因为目前的网站推广需要,这两天抽空作了一个群发邮件的桌面程序。以前没真正做过swing UI,这也算是新的尝试了 /images/emoticons/wink.gif

程序的核心是利用socket与目标smtp server通信来发信。因为考虑到带宽的利用率,所以设计了多线程的方式。这里的任务分配其实很有学问,目前只是简单的根据mail address的数量和用户设置的thread count进行了数学上分配,其实考虑到建立socket的开销,更好的方式是根据主机MX纪录来分配,这样可以最大限度的利用现有socket资源,避免频繁的握手。。。有空一定要好好优化这部分! (y)

大多的工作还是在周边。一方面是UI,还有一方面是设置文件、成功失败列表文件、临时预览文件的管理,以及他们和UI的交互。大量的dirty works。。。还好有jb这样的优秀RAD工具,否则现在也没有写笔记的功夫了 /images/emoticons/silly.gif

总结一下其间遇到的几个难缠的问题:

  1. 要让滚动条总在最下端,有3个方法:
    • 调用JScrollPane.getViewport().scrollRectToVisible(),使得最下面的某一点可见;
    • 设置vertical scroll bar的value到max;
    • 在scroll pane里面setCaretPosition()(也就是编辑光标的位置)到length()。
    看上去第一和第二个方案比较cool一点,可实际上用于多线程环境都会造成死锁。而我这里恰好有一个需要多线程更新scroll pane的地方:失败和成功邮件状态察看(参看下面的截图)。这里为了保证逐行的显示mail address,不至于串行,所以在scroll pane内的那个text pane上用到了synchronized() {}
    没有细看类库的source,我推测可能是因为这些操作都不是原子的,而其中某些步骤和我这里的synchronized相互竞争了锁导致的问题。这里还有待进一步的研究(如果有时间/images/emoticons/silly.gif)。

  2. 发信时候,有些smtp server会反向查询from地址的主机部分,检查和你的本机ip是否相同。我现在用的是blah@本机ip地址,不过似乎有时候还是会失败。这个需要深入测试
  3. 我的几个dialog,比如preference,还有preview,都是在show的时候让默认的cancel/close button去requestFocus(),不过完全没有作用 /images/emoticons/sad.gif
其他的问题大多没什么难解决的,细心就没问题了。目前的版本还很粗糙,我的目标是把它最终做成一个功能完善的共享软件。有时间就有可能,呵呵。。 下面是一些界面截图以供参考 /images/emoticons/happy.gif



主界面




参数设置界面




邮件预览菜单:可以用内部的浏览器,或者IE进行预览。




预览界面




开始发送




失败和成功邮件状态察看




发送完成报告

Posted by: miles
Comments [0] |

借助xml数据岛的站点信息统计 续 [Permalink]

Thu Sep 02 14:00:37 CST 2004
Category [working on downwap.]

这次更新了这部分程序。效果又上一个台阶。 这次一个重要改进,是对于数据的缓存。因为这些查询时效性要求不高(几分钟更新一次完全没有问题),而且查询本身开销很大,所以做的时候就有考虑cache。cache的更新方案有两个:

  1. 每次数据表更新数据的同时更新cache
  2. 不关心实时数据情况,每隔固定时间段重新load cache
第一种方法因为cache时刻保证内容的同步性,而且cache实际上是脱机的,所以对于显示时效性要求高的应用,比如论坛的帖子列表比较合适。他的缺点是对于更新操作比较分散的应用代码的改动量较大,而且容易使得cache和数据库完全丧失数据一致性。

第二种方法的优点是数据一致性容易保证,而且对现有代码完全没有影响。缺点则是效率相对比较低,而且时效性和效率完全成反比关系,要保证时效性,就得频繁的查询数据库。

结合信息统计应用本身特点,以及开发的具体情况,权衡利弊以后我决定采用第二种方法。cache在context load时候建立,有一个timer保证以固定时间间隔reload cache。

效果如下,请注意中间的“查询”那个部分:

当前查询日期:



总用户数
wap用户数
wap总流量
wap下载量
html下载量
本月新用户数
本月用户增长率
一周以来新用户数
一周以来用户增长率
一周以来活动用户数
当月免费wap下载量
当日免费wap下载量
当月收费wap下载量
当日收费wap下载量
当月免费html下载量
当日免费html下载量
当月收费html下载量
当日收费html下载量


日流量查询 ==>

日流量统计
--



?2004, downjoy.com

Posted by: miles
Comments [0] |

借助xml数据岛的站点信息统计 [Permalink]

Tue Jul 27 09:33:27 CST 2004
Category [working on downwap.]

新加入了站点信息统计。这次xslt生成的是xml,简单多了。。调用时候,是通过数据岛方式,无刷新,效果很cool,可惜只有IE高版本(IE5+)支持。

这里的xml数据源也是通过xslt转换原始xml数据(raw data)得到的。由此可见xslt在数据和表现的分离方面的优势。

效果如下:


当前查询日期:



总用户数
总访问量
总论题数
总回复数
技术论题数
非技术论题数
当月新用户数
一周以来新用户数
一周以来活动用户数
当月用户增长率
当年度访问量
当月访问量
当天访问量
本月访问量增长率
当月论题数
当日论题数
当月回复数
当日回复数



?2000-2004, 2yup.com

Posted by: miles
Comments [0] |

没有package的bean在jsp中的应用 [Permalink]

Fri Jun 25 14:07:50 CST 2004
Category [development. ~]

今天有人问我一个问题,说是他的bean怎么也无法在jsp中使用。我看了代码,没什么问题。拿来一试,果然不行。。经过调试发现,只要没有package,就有问题!仔细想想,以前好像也遇到过,不过当时因为赶进度,加了package就过了,没有回头多看。

这次时间充裕,上网找了一下资料。终于找了一个看上去比较合理的解释:

When you put the bean class files in the WEB-INF/classes dir, they are automatically in the CLASSPATH. You don't have to do anything special.

Having said that, when you put bean classes in the WEB-INF/classes, the whole Java world knows that these are beans without any package stmts, right!

Now there is a sticky thing with no-package bean classes.... /images/emoticons/sad.gif . When you use bean without a package stmt, the App Server will look for the bean class in the same package as that of the generated Servlet code. And we don't know what package the generated servlet code is, so generally the JSP fails.

Bottomline, put your beans in a package and then access them. Ofcourse in this case you will put the bean class files in the WEB-INF/classes/mycom/mypackage/ directory which reflects the package stmt in your bean class.

Posted by: miles
Comments [0] |

issues, 040601 [Permalink]

Tue Jun 01 14:01:04 CST 2004
Category [working on downwap.]

客户端兼容性问题。模拟器上测试没有任何问题,M320还是不行。问题有两个:

  1. 汉字编码。对于模拟器,对汉字的处理方法等同于html浏览器作普通html客户端时候的做法。就是说,显示和入库,都需要做一个编码转换。但是,M320却用不着。只能再测试看看了。。如果真的有这种差异,还是不容易处理阿。。
    A: 通过检查客户端类型解决了。扩展性不好。期待更好的方法。
  2. request保存值问题。现在做法,是在用户请求某些需要登录的操作(比如回复帖子)的时候,进行权限检查(此时的request URI可能是:/wml/fcs.jw?act=goreply&pid=12345)。如果未登录,就在servlet里面直接forward到用户管理的servlet(/wml/mcs.jw?act=gologin&from=/wml/fcs.jw?act=goreply&pid=12345),并且在里面进一步forward到login.jwml(这是login form,pagefield包括username,password,from,和act。其中act=loginmember),并且带上from参数。用户填好表单之后,仍然提交回用户管理servlet(mcs.jw)。在这个servlet中,根据act(loginmember)进行登录。当登录完成,再forward回来。整个流程本身没什么问题。同上,模拟器正常。但是,M320中,最后一次act却成了goreply(期待值是loginmember),导致叶面出错。怎么会这样呢?request里面的参数居然跨request存在?而且没有被覆盖?晕啊。。[流程参看下图]
    A: 没法子。加了一个冗余的request.setAttribute()。似乎可以解决。
    问题在于from参数本身可能带有查询字符串。比如:/nexus/wml/fcs.jw?act=reply&pid=123。一般的客户端,比如IE,处理时候没有问题,因为这个字串会encode。也就是说,允许form field内容有&。但是,对于m320就不同了。这里的&会把post数据截断。目前还没有好办法,晚上回去研究一下。
    找到问题了。。。原来M320对于url的编码仅仅限于%(会变成%25),其他字符,比如&/都不会处理。。现在只能是手动的进行编码和解码了。没有办法。还好只是在UI层 /images/emoticons/happy.gif


Posted by: miles
Comments [0] |

开发环境 [补] [Permalink]

Fri May 28 11:02:02 CST 2004
Category [working on downwap.]

整个开发/测试/运行的环境。
tomcat4.0.x和4.1.x有显著不同!参考issues, 040520。

开发环境

项目 内容
Platform Windows 2000 Server Edition
JDK(JRE) 1.4_02
Web Server IIS 5.0
Jsp/Servlet Container jakarta-tomcat-4.1.27-LE-jdk14
IDE Borland JBuilder X Enterprise Trial

运行环境
项目 内容
Platform Windows 2000 Server Edition
JDK(JRE) 1.4_02
Web Server IIS 5.0
Jsp/Servlet Container Tomcat 5.0.x

测试环境
项目 内容
Platform Windows 2000 Serv/Prof Edition
Client
  • WinWap 3.1 PRO
  • Mitsubishi M320
  • Nokia Wap Toolkit
  • Phone.Com Simulator
  • IE 6
  • Posted by: miles
    Comments [0] |

    issues, 040526 [Permalink]

    Thu May 27 14:44:44 CST 2004
    Category [working on downwap.]

    1. encoding。昨天发现手机支持的编码似乎很有限。有些模拟器(Nokia Wap Toolkit 6110/6150;phone.com)上,我现在采用的encoding,gbk,根本通过不了。我的M320,还有winwap倒是没有问题。
      A: 改成gb2312,就好了 /images/emoticons/plain.gif
    2. encoding。以前为了转换gb汉字到xml entity,用的是简单的字符串处理的方法。主要是觉得分析tag,然后替换里面的内容好麻烦。
      A: 笨啊。。DOM是做什么的!当年还经常用来着。。 /images/emoticons/sad.gif 晕!
    3. truncate。看到资料说,一个只能有1.4k内容。谁定的这么奇怪的规定 /images/emoticons/sad.gif 本来手机都有超时的嘛。。首页latest post list(20条标题而已阿)刚好超过。。。和上面一样,我的M320/winwap仍然没有问题。看来M320的wml支持好像比较新。这下麻烦了。。我怎么知道有没有超过?如果简单内容还好,比如帖子详细信息,我直接“[请登录论坛查看]”或者“show me more”就行了。但是,像这种标题列表动态的东西,就很难说几条会超过。。是不是需要做一个方法,去remove呢??
      A: 帖子信息已经分页显示了。做法是在xsl里面处理。不过标题仍然是问题。我现在做法是留够余量。回复列表仍然没有处理。有时候游懒惰的想法,觉得wap毕竟是html版的补充,又不是为了取代他。也不用太过追求完美。
    4. @#@#$!@#。M320提交帖子汉字出乱码;登录时候,如果密码大写就通不过(我已经ignore case了阿。winwap就可以通过的。)。
      A: 是编码问题。从PC上模拟器里和手机上提交过来的文字编码不同。现在是判断了终端类型。扩展性不好,不过管用。
    5. 为什么wbmp这么差效果?不过看上去倒是挺有历史感,呵呵。。现在我是在网上直接gif=>wbmp。还是找个工具把。。据说ps7.0直接支持wbmp。可我的刚好是6.0。
      A: 7.0的确支持。效果很好
    6. 模拟器里的7110,只能通过gateway方式上网。麻烦,还得打电话给移动。
      A: 懒得搞了。多发动群众把。

    Posted by: miles
    Comments [0] |

    class view [Permalink]

    Thu May 27 14:33:28 CST 2004
    Category [working on downwap.]

    目前为止的class view:













    Posted by: miles
    Comments [0] |

    issues, 040520 [Permalink]

    Thu May 27 14:32:44 CST 2004
    Category [working on downwap.]

    1. ContentType。我需要让所有的/wml下面的servlet和jsp的contentType是text/vnd.wap.wml,可是,如果一个一个设置,多麻烦阿。所以呢,考虑到用一个filter,过滤所有/wml开头的请求,设置response的contentType。建立一个Filter,在他的doFilter里面response.setContentType("text/vnd.wap.wml"),可是呢,却对jsp不管用!
      A: 检查work目录,观察jsp生成的java源码,发现在刚刚进入_jspService的时候,会自动加上:
      response.setContentType("text/html;charset=ISO-8859-1");。所以filter在他之前设置的contentType就白瞎了。。既然不能更改设置contentType的顺序,那就让它失效!
      所以在这里引入了一个WmlMimeServletResponseWrapper。他的作用主要在这几段:
          private static final String CONTENT_TYPE = "text/vnd.wap.wml";
      
          public WmlMimeServletResponseWrapper(HttpServletResponse response) {
              super(response);
              response.setContentType(CONTENT_TYPE);
          }
      
          public void setContentType(String type) {
              super.setContentType(CONTENT_TYPE);
          }
      
      很简单,就不说了。不管传入什么type,我统统不理会,一律vnd.wap.wml。不过,这里有一个小问题。最初,我是把setContentType方法留空了。看上去也很合理,而且在tomcat4.0.6下面运行很正常。可是,到了tomcat4.1.27/5就不正常了。百思不得其解,把它改成了现在的样子,问题得以解决。究竟为什么呢?有空看看tomcat的源码吧。跟踪看看究竟发生了什么。
    2. 构造一个XSLT的transformer,是需要时间的。他的输入参数,是一个xsl文件资源。
      A: 因为一般情况下,xsl文件不会频繁更新,所以这里可以考虑做成factory,维护一个static的transformer集合。

    Posted by: miles
    Comments [0] |

    ?
    四月 2024
    Sun? Mon? Tue? Wed? Thu? Fri? Sat?
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
    <  Mar???Today??? May  >
    << <   2 3 4 5 6   > >>

    Available categories: [/] [development. ~] [working on downwap.] [trouble shooting] [working on Yup Mailman] [general infomation.] [life style]

    Powered By blojsom?? RSS Feed? RSS2 Feed? RDF Feed

    html hits:?51082