“善意的谎言、美丽的错误”,这些事情在我们的生活及工作经常都在发生。最近花了三天多的时间学习了EasyJF开源官网的Blog程序源码,振奋人心之处就不说了,看过的都知道。同时也存在很多的错误,这些错误有的是由我不知何时亲自导演,这里就捡一些“美丽”的错误及Bub来说说,为了自己以后不再犯这样错误。

  技术构架:EasyJWeb+Spring2+JPA 视图模板使用:Velocity

 1、很Cool的循环 来自:Blog的圈子显示 错误等级★★★★★


美丽的错误_html页面#foreach($!subList in $!CommUtil.toRowChildList($myOnweCircle,2))

美丽的错误_html页面  <tr>

美丽的错误_html页面 #foreach($!info in $subList)

美丽的错误_html页面 <td>

美丽的错误_html页面$!info.title

美丽的错误_html页面</td>

美丽的错误_html页面 #end

美丽的错误_html页面<tr>

美丽的错误_html页面 #end

美丽的错误_html页面


  其中$myOnwerCircle是从后台传过来的一个List。这个程序是遍历一个列集合,把集合的元素循环显示到<tr>中,第行最多显示两列<td>。

  但无论如何,都无法得到想要的结果,由于准备换成类似$BlogQuery.circleQuery.user($blog.owner).number(-1).list这样的标签来查询数据,所以一直认为是标签设计的问题。经过后来的一阵折腾证明是脚本写法的问题,你知道是哪些地方出的问题了吗?先说明:$!CommUtil.toRowChildList这个标签没任何问题。

2、easy的echo 来自:Blog的圈子显示 错误等级★★★★★☆

  页面内容:


美丽的错误_html页面<span class="strong0">$!info.title($!info.blogs.size())</span><br>


  这里打算显示圈子的主题以及圈子下面的blog数量。但如果不亲身体会,鬼都不知道他会给你显示什么出来。你知道吗?

 3、非菜鸟的equals 来自:文章及照片评论

  


美丽的错误_html页面String user =!"".equals(obj.getInputUser()) ? obj.getInputUser().getName() : "匿名用户"; 

美丽的错误_html页面


  数据结构永远就比算法重要,这个是不容质疑的,可以搞出很漂亮的算法,但没有一个好的模型,你就瞎忙吧。你觉得上面的代码哪儿错了?

 4、一不小心就OO及ORM 来自:评论系统设计 ★★☆


美丽的错误_html页面@Entity

美丽的错误_html页面@javax.persistence.Inheritance(strategy = javax.persistence.InheritanceType.JOINED)

美丽的错误_html页面@Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)

美丽的错误_html页面@FormPO(inject = "sequence,content,owner")

美丽的错误_数据_18美丽的错误_前台页面_19public abstract class Review implements java.io.Serializable ...{

美丽的错误_前台页面_20

美丽的错误_前台页面_20 @Id

美丽的错误_前台页面_20 @GeneratedValue(strategy = GenerationType.TABLE)

美丽的错误_前台页面_20 private Long id;// 主键

美丽的错误_html页面_24..}

美丽的错误_html页面

美丽的错误_html页面

美丽的错误_html页面@FormPO(inject="blogOwner,inputUser")

美丽的错误_html页面@Entity

美丽的错误_html页面@javax.persistence.MappedSuperclass

美丽的错误_数据_18美丽的错误_前台页面_19public class BlogReview extends Review implements IBlogComponment ...{

美丽的错误_前台页面_20 @POLoad(name="userId")

美丽的错误_前台页面_20 @ManyToOne

美丽的错误_前台页面_20 private User blogOwner;

美丽的错误_前台页面_20

美丽的错误_前台页面_20 private String inputUser;

美丽的错误_html页面_24}

美丽的错误_html页面

美丽的错误_html页面

美丽的错误_html页面@FormPO(inject="newsDoc")

美丽的错误_html页面@Entity

美丽的错误_数据_18美丽的错误_前台页面_19public class BlogNewsReview extends BlogReview ...{

美丽的错误_前台页面_20 @POLoad(name = "docId")

美丽的错误_前台页面_20 @ManyToOne

美丽的错误_前台页面_20 @JoinColumn

美丽的错误_前台页面_20 private BlogNewsDoc newsDoc;// 评论的对象

美丽的错误_前台页面_20

美丽的错误_html页面_24}

美丽的错误_html页面

美丽的错误_数据_18美丽的错误_前台页面_19public interface IBlogReviewDAO  extends GenericDAO<BlogReview> ...{

美丽的错误_前台页面_20

美丽的错误_html页面_24}

美丽的错误_html页面

美丽的错误_html页面 private IBlogReviewDAO dao;

美丽的错误_数据_18美丽的错误_前台页面_19    public BlogReview getBlogReview(Long id) ...{

美丽的错误_前台页面_20  return this.dao.get(id);

美丽的错误_html页面_24 }

美丽的错误_html页面

美丽的错误_html页面


  评论系统,管理员能管理所有评论,能对Blog文章、像册等进行评论。

这个示例要是搞好了可以当成是一个比较经典的OO及ORM示例,但是现在这样的写法你知道JPA会创建几张表吗,各个表之间关联字段是是什么? Service中的getBlogReview返回什么?答对了有奖。

 4、有事无事的事务 来自blog信息发表 

  


美丽的错误_html页面<!--事务配置-->

美丽的错误_html页面 <aop:config>

美丽的错误_html页面  <aop:pointcut id="saveMethods"

美丽的错误_html页面   expression="execution(* com.easyjf.blog.service.BlogNewsDocService.*(..))" />

美丽的错误_html页面   <aop:advisor advice-ref="txBlogServiceAdvice"

美丽的错误_html页面   pointcut-ref="saveMethods" /> 

美丽的错误_html页面 </aop:config>

美丽的错误_html页面 <tx:advice id="txBlogServiceAdvice"

美丽的错误_html页面  transaction-manager="transactionManager">

美丽的错误_html页面  <tx:attributes>

美丽的错误_html页面   <tx:method name="wirteBlog*" propagation="REQUIRES_NEW" />

美丽的错误_html页面   <tx:method name="update*" propagation="REQUIRES_NEW" />

美丽的错误_html页面   <tx:method name="get*" propagation="SUPPORTS"

美丽的错误_html页面    read-only="true" />

美丽的错误_html页面   <tx:method name="query*" propagation="SUPPORTS"

美丽的错误_html页面    read-only="true" />

美丽的错误_html页面   <tx:method name="*" propagation="REQUIRED" />

美丽的错误_html页面  </tx:attributes>

美丽的错误_html页面 </tx:advice>

美丽的错误_html页面

美丽的错误_html页面代码:

美丽的错误_html页面this.service.addBlogReview(review);

美丽的错误_数据_18美丽的错误_前台页面_19 if (review instanceof BlogNewsReview) ...{

美丽的错误_前台页面_20   BlogNewsReview r = (BlogNewsReview) review;

美丽的错误_前台页面_20   //this.docService.updateBlogNewsDoc(r.getNewsDoc());

美丽的错误_前台页面_20   this.htmlGenerator.process(r.getNewsDoc());

美丽的错误_前台页面_20   r.getNewsDoc().getReviews().remove(r);// 很怪也滑稽的设计

美丽的错误_前台页面_20   return new Page("html", r.getNewsDoc().getStaticUrl(), "html");

美丽的错误_html页面_24 }

美丽的错误_html页面

美丽的错误_html页面


   为什么Blog更新后出来的html页面还是上一次更新的内容?为什么在添加新闻的评论里面要加一句r.getNewsDoc().getReviews().remove(r),是无奈还是真的滑稽。

 5、究竟是要IP、IQ还是IC卡 来自:blog首页 ☆

 


美丽的错误_html页面 后台Action代码

美丽的错误_数据_18美丽的错误_前台页面_19public Page doInit(WebForm form, Module module) ...{

美丽的错误_前台页面_20  form.addResult("blogInfoService", this.blogInfoService);

美丽的错误_前台页面_20  form.addResult("bqu", bqu);

美丽的错误_前台页面_20  form.addResult("bdqu", bdqu);

美丽的错误_前台页面_20  form.addResult("bcqu", bcqu);

美丽的错误_前台页面_20form.addResult("bb” bb);

美丽的错误_html_103美丽的错误_java_104  if (UserContext.getUser() != null) ...{

美丽的错误_前台页面_20   form.addResult("user", "true");

美丽的错误_数据_106  }

美丽的错误_前台页面_20  return new Page("index", "/blog/index.html");

美丽的错误_html页面_24 }

美丽的错误_html页面前台页面

美丽的错误_html页面#foreach($info in $bcu.thisYear.doc.list)

美丽的错误_html页面$info.title

美丽的错误_html页面#end

美丽的错误_html页面


  这段代码是想把一些实用工具比如bb,bq,bcqu,bdqu等暴露给页面,由页面人员根据自己的喜爱想要展示什么数据就展示什么数据。严格来说,这没什么错,只是害苦了美工MM而已,难怪她们不喜欢呆办公室。

 7、真空还是没空(is NULL or EMPTY) 来自Blog发布程序


美丽的错误_html页面业务层代码:

美丽的错误_html页面QueryObject query = new QueryObject();

美丽的错误_html页面java.util.Calendar ca = java.util.Calendar.getInstance();

美丽的错误_html页面ca.setTimeInMillis(ca.getTimeInMillis() - blogIntervals * 1000);  

美丽的错误_数据_18美丽的错误_前台页面_19query.addQuery("(obj.updateTime<? or obj.updateTime is EMPTY)",new Object[]...{ca.getTime()});

美丽的错误_html页面query.setPageSize(-1);  

美丽的错误_html页面List list = this.blogService.getBlogInfo(query).getResult();

美丽的错误_html页面


知道执行这段代码生成的SQL吗?一定会让你大吃一惊,把EMPTY改成NULL难道是我们想要的?

 8、F想要干什么 来自:blog新闻管理 

 


美丽的错误_html页面Javascript脚本代码:

美丽的错误_数据_18美丽的错误_前台页面_19function init()...{

美丽的错误_前台页面_20   F=new FORM("blogNewsDoc.ejf","ListForm");

美丽的错误_前台页面_20   windowInit();

美丽的错误_html页面_24  }

美丽的错误_html页面  window.onload=init;  

美丽的错误_html页面  F.doList = F.doOneCommand("listDoc");

美丽的错误_html页面


 

  古老的new FORM曾经让我们非常欣喜,但为什么现在换来的却是大家抱怨呢?代码有时候也是有生命的,你如何都不用心好好对待他,他怎么会一直按部就班的运转呢?

 9.想擦掉js给你留下的伤疤吗 来自blog管理后台

 


美丽的错误_html页面  Html代码

美丽的错误_html页面<form name=”ListForm” id=”ListForm”/>

美丽的错误_html页面<input type="button" name="submit" value="彻底删除" onClick="F.doRemove();" class="pushbutton" style="cursor:pointer ">

美丽的错误_html页面</form>

美丽的错误_html页面     F.doRemove()里面会执行类似$(“ListForm”).submit()这样的代码来提交表单。


你觉得这段代码能让你真正的彻底删除掉js曾经留给你的诸多痛苦回忆吗?你继续痛哭吧,呵呵。其实我们只要仔细看一看就知道问题了。w3c可不是war3,不能随便乱来的。

10.你拥有什么? 来自Blog域对象 

 

  


美丽的错误_html页面@FormPO(disInject="id,owner,inputTime,readTimes,status,elite,updated,docNum,photoNum")

美丽的错误_html页面@MappedSuperclass

美丽的错误_数据_18美丽的错误_前台页面_19public class AbstractBlog implements Serializable ...{ 

美丽的错误_前台页面_20 @Id

美丽的错误_前台页面_20 @GeneratedValue(strategy = GenerationType.TABLE)

美丽的错误_前台页面_20 protected Long id;

美丽的错误_前台页面_20 

美丽的错误_前台页面_20 @OneToOne

美丽的错误_前台页面_20 protected User onwer;

美丽的错误_前台页面_20 

美丽的错误_前台页面_20 @Column(length = 200)

美丽的错误_前台页面_20 protected String title;// 标题

美丽的错误_前台页面_20

美丽的错误_前台页面_20 @Column(length = 200)

美丽的错误_前台页面_20 protected String subtitle;// 副标题

美丽的错误_前台页面_20

美丽的错误_html页面_24}

美丽的错误_html页面页面标签:

美丽的错误_html页面#foreach($info $BlogQuery.photoQuery.blogOwner($blog.owner).number(6).orderBy("inputTime").desc().list)

美丽的错误_html页面

美丽的错误_html页面#end

美丽的错误_html页面

美丽的错误_html页面


  呵呵,今天就这么多了,先听听大家的高见!下次发几个能让人眼前一亮的。