??xml version="1.0" encoding="utf-8" standalone="yes"?>久久精品免视看,免费观看久久久4p,av大片在线观看http://www.aygfsteel.com/webber/zh-cnTue, 17 Jun 2025 22:58:01 GMTTue, 17 Jun 2025 22:58:01 GMT60java HashMap分析http://www.aygfsteel.com/webber/archive/2010/03/26/316657.htmlwebberwebberFri, 26 Mar 2010 09:08:00 GMThttp://www.aygfsteel.com/webber/archive/2010/03/26/316657.htmlhttp://www.aygfsteel.com/webber/comments/316657.htmlhttp://www.aygfsteel.com/webber/archive/2010/03/26/316657.html#Feedback0http://www.aygfsteel.com/webber/comments/commentRss/316657.htmlhttp://www.aygfsteel.com/webber/services/trackbacks/316657.html

在Java的世界里Q无论类q是各种数据Q其l构的处理是整个E序的逻辑以及(qing)性能的关键。由于本人接触了(jin)一个有x能与逻辑同时q存的问题,于是开始研I这斚w的问题。找遍了(jin)大大小的论坛,也把《Java 虚拟范》,《apress,.java.collections.(2001),.bm.ocr.6.0.shareconnector》,和《Thinking in Java》翻?jin)也找不到很好的{案Q于是一气之下把JDK?src 解压出来研究Q扩然开朗,遂写此文Q跟大家分n感受和顺侉K证我理解q有没有漏洞?q里拿HashMap来研I吧?



  HashMap可谓JDK的一大实用工P把各个Object映射hQ实C(jin)“键-Q?#8221;对应的快速存取。但实际里面做了(jin)些什么呢Q?

  在这之前Q先介绍一下负载因子和定w的属性。大安知道其实一?HashMap 的实际容量就 因子*定wQ其默认值是 16×0.75Q?2Q?q个很重要,Ҏ(gu)率很一定媄(jing)响!当存入HashMap的对象超q这个容量时QHashMap ׃(x)重新构造存取表。这是一个大问题Q我后面慢慢介绍Q反正,如果你已l知道你大概要存攑֤个对象Q最好设实际定w的能接受的数字?

  两个关键的方法,put和getQ?

  先有q样一个概念,HashMap是声明了(jin) MapQCloneable, Serializable 接口Q和l承?AbstractMap c,里面?Iterator 其实主要都是其内部类HashIterator 和其他几?iterator cd玎ͼ当然q有一个很重要的承了(jin)Map.Entry ?Entry 内部c,׃大家都有源代码,大家有兴可以看看这部分Q我主要惌明的?Entry 内部cR它包含?jin)hashQvalueQkey 和next q四个属性,很重要。put的源码如?

public Object put(Object key, Object value) {
Object k = maskNull(key);

  q个是判断键值是否ؓ(f)I,q不很深奥,其实如果为空Q它?x)返回一个static Object 作ؓ(f)键|q就是ؓ(f)什么HashMap允许I键值的原因?

int hash = hash(k);
int i = indexFor(hash, table.length);

  q连l的两步是 HashMap 最牛的地方Q研I完我都汗颜?jin),其?hash 是通过 key q个Object?hashcode q行 hashQ然后通过 indexFor 获得在Object table的烦(ch)引倹{?

  tableQ?Q不要惊Ӟ其实HashMap也神不到哪里去,它就是用 table 来放的。最牛的是?hash 能正的q回索引。其中的hash法Q我跟JDK的作?Doug 联系q,他徏议我看看《The art of programing vol3》可恨的是,我之前就一直在找,我都找不刎ͼ他这样一提,我就更加急了(jin)Q可惜口袋空I啊Q!Q?

  不知道大家有没有留意 put 其实是一个有q回的方法,它会(x)把相同键值的 put 覆盖掉ƈq回旧的|如下Ҏ(gu)d说明?HashMap 的结构,其实是一个表加上在相应位|的Entry的链表:(x)

for (Entry e = table[i]; e != null; e = e.next) {
 if (e.hash == hash && eq(k, e.key)) {
  Object oldvalue = e.value;
  e.value = value; //把新的D予给对应键倹{?
  e.recordAccess(this); //I方法,留待实现
  return oldvalue; //q回相同键值的对应的旧的倹{?
 }
}
modCount++; //l构性更改的ơ数
addEntry(hash, k, value, i); //d新元素,关键所在!
return null; //没有相同的键D?
}

  我们把关键的Ҏ(gu)拿出来分析:(x)

void addEntry(int hash, Object key, Object value, int bucketIndex) {
table[bucketIndex] = new Entry(hash, key, value, table[bucketIndex]);

  因ؓ(f) hash 的算法有可能令不同的键值有相同的hash码ƈ有相同的table索引Q如QkeyQ?#8220;33”和keyQObject g的hash都是Q?901334Q那它经qindexfor之后的烦(ch)引一定都为iQ这样在new的时候这个Entry的next׃(x)指向q个原本的table[i]Q再有下一个也如此QŞ成一个链表,和put的@环对定e.next获得旧的倹{到q里QHashMap的结构,大家也十分明白了(jin)吧?

if (size++ >= threshold) //q个threshold是能实际容U的?
resize(2 * table.length); //出q个定w׃(x)Object table重构

  所谓的重构也不,是Z个两倍大的tableQ我在别的论坛上看到有h说是两倍加1Q把我骗?jin)?j)Q然后再一个个indexforq去Q注意!Q这是效率Q!如果你能让你的HashMap不需要重构那么多ơ,效率?x)大大提高?

  说到q里也差不多?jin),get比put单得多,大家Q了(jin)解putQget也差不了(jin)多少?jin)。对于collections我是认ؓ(f)Q它是适合q泛的,当不完全适合Ҏ(gu)的,如果大家的程序需要特D的用途,自己写吧Q其实很单。(作者是q样跟我说的Q他q徏议我用LinkedHashMap,我看?jin)源码以后发玎ͼLinkHashMap其实是l承HashMap的,然后override相应的方法,有兴的同hQ自己looklookQ徏?Object tableQ写相应的算法,ok啦?

  举个例子吧,?VectorQlist 啊什么的其实都很单,最多就多了(jin)的同步的声明Q其实如果要实现像Vector那种Q插入,删除不多的,可以用一个Object table来实玎ͼ按烦(ch)引存取,d{?

  如果插入Q删除比较多的,可以Z个Object tableQ然后每个元素用含有nextl构的,一个tableQ如果要插入到iQ但是i已经有元素,用nextqv来,然后sizeQ+Qƈ在另一个table记录其位|?/p>

HashMap用法

 

 

package hashmap;

import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;

public class HashMap1 {
//初始?br /> private void init(Map map,String kind)
{
   if(map != null)
   {
    for(int i=1; i<6; i++)
    {
     map.put(String.valueOf(i),kind+i);
    }
   }
}

//l果输出
private void outPut(Map map)
{
   if(map != null)
   {
    Object key    = null;
    Object value = null;
    Iterator iterater = map.keySet().iterator();
    while(iterater.hasNext())
    {
     key = iterater.next();
     value = map.get(key);
     System.out.print(key+": "+value+"\t");
    }
    System.out.println("\n");
   }
}
public static void main(String args[])
{
    HashMap hashmap = new HashMap();
    hashmap.put("x", "1");
    hashmap.put("u", "2");
    hashmap.put("z", "3");
    hashmap.put("h", "4");
    hashmap.put("a", "5");
    hashmap.put("o", "6");
    hashmap.put("g", "7");
    hashmap.put("u", "8");
    hashmap.put("a", "9");
    hashmap.put("n", "10");
    hashmap.put("g", "11");

     Object key    = null;
     Object value = null;
     Iterator iterater = hashmap.keySet().iterator();
     while(iterater.hasNext())
     {
      key = iterater.next();
      value = hashmap.get(key);
      System.out.print(key+": "+value+"\t");
     }
     System.out.println("\n");

}
//声明HashMap对象
private void setHashMap()
{
   HashMap hashMap = new HashMap();
   init(hashMap,"HashMap");
   hashMap.put(null,"键gؓ(f)I?);
   hashMap.put("gؓ(f)I?,null);
   System.out.println("q是HashMap对象的键与?");
   outPut(hashMap);
}
     //声明Hashtable对象
private void setHashtable(){
   Hashtable hashtable = new Hashtable();
   init(hashtable,"Hashtable");
   //hashtable.put(null,"键gؓ(f)I?); Hashtable不允?dng)R或gؓ(f)null;
   //hashtable.put("gؓ(f)I?,null);
   System.out.println("q是Hashtable对象的键与?");
   outPut(hashtable);
}
     //声明LinkedHashMap对象
private void setLinkedHashMap(){
   LinkedHashMap linkedHashMap = new LinkedHashMap();
   init(linkedHashMap,"LinkedHashMap");
   linkedHashMap.put(null,"键gؓ(f)I?);
   linkedHashMap.put("gؓ(f)I?,null);
   System.out.println("q是LinkedHashMap对象的键与?");
   outPut(linkedHashMap);
}
     //声明TreeMap对象
private void setTreeMap(){
   TreeMap treeMap = new TreeMap();
   //TreeMap treeMap = new TreeMap(new MySort());//按自定义的方式排?br />    init(treeMap,"TreeMap");
   treeMap.put("0", "后插入的?);
   //treeMap.put(null,"键gؓ(f)I?); TreeMap不允?dng)R或gؓ(f)null
   //treeMap.put("gؓ(f)I?,null);
   System.out.println("q是TreeMap对象的键与?");
   outPut(treeMap);
}
// public static void main(String[] args){
//   HashMapDemo tm = new HashMapDemo();
//   tm.setHashMap();
//   tm.setHashtable();
//   tm.setLinkedHashMap();
//   tm.setTreeMap();
//
//   Map hashMap = new HashMap();
//   hashMap.put(null, "键gؓ(f)null");
//   hashMap.put("gؓ(f)null", null);
//   System.out.println("新徏HashMap对象元素的记录数?"+hashMap.size());
//   hashMap.remove(null);
//   System.out.println("删除键gؓ(f)null的HashMap对象元素的记录数?"+hashMap.size());
// }



webber 2010-03-26 17:08 发表评论
]]>
学习(fn)HashMap遍历的两U方?/title><link>http://www.aygfsteel.com/webber/archive/2010/03/26/316654.html</link><dc:creator>webber</dc:creator><author>webber</author><pubDate>Fri, 26 Mar 2010 08:57:00 GMT</pubDate><guid>http://www.aygfsteel.com/webber/archive/2010/03/26/316654.html</guid><wfw:comment>http://www.aygfsteel.com/webber/comments/316654.html</wfw:comment><comments>http://www.aygfsteel.com/webber/archive/2010/03/26/316654.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/webber/comments/commentRss/316654.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/webber/services/trackbacks/316654.html</trackback:ping><description><![CDATA[<p> </p> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td valign="top" width="344">W一U? <br /> Map map = new HashMap(); <br /> Iterator iter = map.entrySet().iterator(); <br /> while (iter.hasNext()) { <br />     Map.Entry entry = (Map.Entry) iter.next(); <br />     Object key = entry.getKey(); <br />     Object val = entry.getValue(); <br /> } <br /> 效率?以后一定要使用此种方式Q?<br />                                                                                     <br /> W二U? <br /> Map map = new HashMap(); <br /> Iterator iter = map.keySet().iterator(); <br /> while (iter.hasNext()) { <br />     Object key = iter.next(); <br />     Object val = map.get(key); <br /> } <br /> 效率?以后量用! <br /> HashMap的遍历有两种常用的方法,那就是用keyset?qing)entryset来进行遍历,但两者的遍历速度是有差别的,下面L(fng)实例Q?/td> </tr> <tr> <td colspan="2" height="20"> <pre>import java.util.*; public class HashMapTest { public static void main(String[] args) { HashMap< Integer,String> hashmap = new HashMap< Integer,String>(); for (int i = 0; i <1000; i++ ) { hashmap.put(i, "thanks"); } long bs = Calendar.getInstance().getTimeInMillis(); Iterator iterator = hashmap.keySet().iterator(); while (iterator.hasNext()) { System.out.print(hashmap.get(iterator.next())); } System.out.println(); System.out.println(Calendar.getInstance().getTimeInMillis() - bs); listHashMap(); } public static void listHashMap() { java.util.HashMap< Integer,String> hashmap = new java.util.HashMap< Integer,String>(); for (int i = 0; i < 1000; i++ ) { hashmap.put(i, "thanks"); } long bs = Calendar.getInstance().getTimeInMillis(); Iterator< Map.Entry< Integer,String>> it = hashmap.entrySet().iterator(); while (it.hasNext()) { Map.Entry< Integer,String> entry = it.next(); // entry.getKey() q回与此对应的? // entry.getValue() q回与此对应的? System.out.print(entry.getValue()); } System.out.println(); System.out.println(Calendar.getInstance().getTimeInMillis() - bs); } </pre> <p>对于keySet其实是遍历了(jin)2ơ,一ơ是转ؓ(f)iteratorQ一ơ就从hashmap中取出key所对于的value。而entryset只是遍历?jin)第一ơ,他把key和value都放C(jin)entry中,所以就快了(jin)?/p> <p>?Hashtable的遍历方法和以上的差不多Q?/p> </td> </tr> </tbody> </table> <img src ="http://www.aygfsteel.com/webber/aggbug/316654.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/webber/" target="_blank">webber</a> 2010-03-26 16:57 <a href="http://www.aygfsteel.com/webber/archive/2010/03/26/316654.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>webwork Spring hibernate整合配置http://www.aygfsteel.com/webber/archive/2010/03/15/315430.htmlwebberwebberMon, 15 Mar 2010 02:10:00 GMThttp://www.aygfsteel.com/webber/archive/2010/03/15/315430.htmlhttp://www.aygfsteel.com/webber/comments/315430.htmlhttp://www.aygfsteel.com/webber/archive/2010/03/15/315430.html#Feedback0http://www.aygfsteel.com/webber/comments/commentRss/315430.htmlhttp://www.aygfsteel.com/webber/services/trackbacks/315430.htmlweb.xml  
// q里不需要配|字W过滤,|上有的例子加了(jin)Q实际上
webwork.properties里设|如下就可以?jin)页面也是GBK
webwork.locale=zh_CN
webwork.i18n.encoding=GBK
Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q?br /> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>

     <context-param>
         <param-name>contextConfigLocation</param-name>
         <param-value>/WEB-INF/classes/applicationContext.xml</param-value>
     </context-param>

<listener>
   <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<listener>
   <listener-class>com.atlassian.xwork.ext.ResolverSetupServletContextListener</listener-class>
</listener>
     <!--
     <servlet>
     <servlet-name>context</servlet-name>
              <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
              <load-on-startup>1</load-on-startup>
      </servlet>
      -->
     <servlet>
         <servlet-name>webwork</servlet-name>
         <servlet-class>com.opensymphony.webwork.dispatcher.ServletDispatcher</servlet-class>
         <load-on-startup>3</load-on-startup>
     </servlet>

<servlet>
   <servlet-name>freemarker</servlet-name>
   <servlet-class>com.opensymphony.webwork.views.freemarker.FreemarkerServlet</servlet-class>
   <load-on-startup>10</load-on-startup>
</servlet>

     <servlet-mapping>
         <servlet-name>webwork</servlet-name>
         <url-pattern>*.action</url-pattern>
     </servlet-mapping>

<servlet-mapping>
   <servlet-name>freemarker</servlet-name>
   <url-pattern>*.ftl</url-pattern>
</servlet-mapping>

     <welcome-file-list>
         <welcome-file>index.html</welcome-file>
     </welcome-file-list>

     <taglib>
         <taglib-uri>webwork</taglib-uri>
         <taglib-location>/WEB-INF/webwork.tld</taglib-location>
     </taglib>

</web-app>

Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q?br />
xwork.xml

==================---------------------------------------------
<?xml version="1.0"?>
<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN" "http://www.opensymphony.com/xwork/xwork-1.0.dtd">

<xwork>

   <include file="webwork-default.xml"/>
     <package name="users" extends="webwork-default"
         externalReferenceResolver="com.atlassian.xwork.ext.SpringServletContextReferenceResolver">

         <interceptors>
             <interceptor name="reference-resolver" class="com.opensymphony.xwork.interceptor.ExternalReferencesInterceptor"/>
             <interceptor-stack name="myDefaultWebStack">
                 <interceptor-ref name="defaultStack"/>
                 <interceptor-ref name="reference-resolver"/>
                 <interceptor-ref name="model-driven"/>
        <interceptor-ref name="params"/>
             </interceptor-stack>
         </interceptors>

<default-interceptor-ref name="myDefaultWebStack"/>
         <action name="blogUser" class="com.jsblog.action.BlogUserAction">
    <external-ref name="baseDao">baseDaoTarget</external-ref>      //q里是把applicationContext里配|的DAO 注入action?action里要有baseDao属?br />     <result name="success">/add.htm</result>
   </action>
-------------------------------------------------------------------------

applicationContext.xml

---------------------------------------------------------------------------
<?xml version="1.0"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-autowire="no" default-dependency-check="none" default-lazy-init="false">
     <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
         <property name="driverClassName">
             <value>com.microsoft.jdbc.sqlserver.SQLServerDriver</value>
         </property>
         <property name="url">
             <value>jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=jsblog;SelectMethod=cursor</value>
         </property>
         <property name="username">
             <value>sa</value>
         </property>
         <property name="password">
             <value>jfy</value>
         </property>
     </bean>

     <bean id="sessionFactory"
           class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
         <property name="dataSource">
             <ref local="dataSource"/>
         </property>
         <property name="mappingResources">
             <list>
                 <value>com/jsblog/BlogUserForm.hbm.xml</value>
             </list>
         </property>
         <property name="hibernateProperties">
             <props>
                 <prop key="hibernate.dialect">
                     net.sf.hibernate.dialect.SQLServerDialect
                 </prop>
                 <prop key="hibernate.show_sql">true</prop>
             </props>
         </property>
     </bean>

     <bean id="transactionManager"
           class="org.springframework.orm.hibernate.HibernateTransactionManager">
         <property name="sessionFactory">
             <ref local="sessionFactory"/>
         </property>
     </bean>


     <bean id="baseDaoTarget" class="com.jsblog.dao.BlogUserDao">
         <property name="sessionFactory">
             <ref local="sessionFactory"/>
         </property>
     </bean>


</beans>
---------------------------------------------------------------------------

BlogUserDao.java
---------------------------------------------------------------------------
package com.jsblog.dao;

import org.springframework.orm.hibernate.support.HibernateDaoSupport;
import org.springframework.orm.hibernate.HibernateCallback;
import org.springframework.orm.hibernate.SessionFactoryUtils;
import com.jsblog.BlogUserForm;

import java.io.Serializable;
import java.util.List;

import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Session;

public class BlogUserDao extends HibernateDaoSupport implements BaseDao {

     public void insert(BlogUserForm bloguser) {
         getHibernateTemplate().save(bloguser);
     }

}



webber 2010-03-15 10:10 发表评论
]]>
webwork+spring+hibernate整合 http://www.aygfsteel.com/webber/archive/2010/03/15/315429.htmlwebberwebberMon, 15 Mar 2010 02:00:00 GMThttp://www.aygfsteel.com/webber/archive/2010/03/15/315429.htmlhttp://www.aygfsteel.com/webber/comments/315429.htmlhttp://www.aygfsteel.com/webber/archive/2010/03/15/315429.html#Feedback0http://www.aygfsteel.com/webber/comments/commentRss/315429.htmlhttp://www.aygfsteel.com/webber/services/trackbacks/315429.html 

Zwebwork spring hibernate 目的开?br /> q三者的l合Q应该是java web~程最好的模式?/p>

首先说明三者各自负责的职务Q?/p>

1 hibernate 负责数据库的操作

2 spring 负责真正的业务操?/p>

3 webwork 负责h转交Qƈ把spring的处理结果返回给用户


以往的开发中Q很多h注重MVC模式。的,q种模式把程序以面向对象的思想分成 ?jin)三个部分。但在web开发中Qƈ不能单纯的运用此U模式:(x)web开发的View是固定的Q页面)(j)Q而在引入hibernate后,modelq一块也非常单和清晰。就剩下control?jin),q是web开发的关键部分Q现在流行的做法便是controll分成两个部分:(x)dispacher(转交?和business object(处理业务逻辑的对?。ƈ后者抽出接口,甚至和model׃n接口Q一边真正做到对dispacher隐藏逻辑实现?/p>

而这UM-V-D-B(model-view-dispacher-business object)模式的实现有好多方式。比如一个bo(business object)对象的创建,你可以直?new,也可以动态加载,采用工厂Ҏ(gu)Q抽象工厂。但最好的是用spring容器。dispacher只管用接口就行了(jin)Q具体类已经有spring?AOPl注入了(jin)?/p>

当然spring也可以很好地和hibernatel合Q你可以采用DAOQ也可以用spring的hibernate 模板。但q都不重要,因ؓ(f)你的业务对象已经和调用层d分开?jin),当业务层需要和hibernate打交道的时候,直接做个HibernateUtil也未不可呀。怎么做都已经不是关键?/p>

下面具体介lspring webwork的结合方式?/p>

在webwork 中的wiki doc中有三种l合方式Qgoogle查)(j)Q我q里采用的最后一U-Q采用一个自动装配的拦截器com.opensymphony.xwork.spring.interceptor.ActionAutowiringInterceptor关键代码如下Q?/p>


   ApplicationContext applicationContext = (ApplicationContext)ActionContext.getContext().getApplication().get(
          WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
        factory = new SpringObjectFactory();
        factory.setApplicationContext(getApplicationContext());
    Action bean = invocation.getAction();
    factory.autoWireBean(bean);
   
    ActionContext.getContext().put(APPLICATION_CONTEXT, context);

1、webwork、spring的集?br />   (1)、开启spring的集成:(x)
         首先最新的spring的jar加到classpath中,然后在src目录下徏立webwork.properties文gQ文件只包含下面的内?br />         webwork.objectFactory=spring
         q种情况?所有的对象都至会(x)试图使用Spring来创?如果它们不能被Spring创徏,然后WebWork?x)自己创建对?接下??br />         web.xml打开Spring的Listener
           <listener>
             <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
           </listener>
        ׃使用标准的Listener来集成Spring,它可以被配置来支持除?jin)applicationContext.xml之外的配|文?把下面的几行d?br />        web.xml?x)让Spring的ApplicationContext从所有匹配给定的规则的文件中初始?

       <!-- Context Configuration locations for Spring XML files -->
        <context-param>
             <param-name>contextConfigLocation</param-name>
             <param-value>/WEB-INF/applicationContext-*.xml,classpath*:applicationContext   
       </context-param>
       Ҏ(gu)需要配|相应的spring上下文文?br />    (2)、在spring中初始化Action
         正常情况?在xwork.xml里可以ؓ(f)每个action指定c?当你使用SpringObjectFactory时WebWork?x)请求Spring?br />          创徏actionq按照缺省指定的自动装配行ؓ(f)来装配依赖的lg.SpringObjectFactory 也会(x)讄所有的bean的后|处理程?br />         (post processors)来完成类似对Actionq行事务,安全{等斚w的代理的事情.Spring可以不依赖外在的配置来自动确?
         对于大多数的使用,q就是全部需要的?用来配置a(chn)ction,讄它们获取服务和依赖组?
         强烈推荐使用一U声明式的方法来让Spring知道为action提供什?q包括让bean能够自动装配,无论是把Action里的
         依赖的属性命名ؓ(f)和Spring应该提供的Bean的名字一?q允许基于名字的自动装配),或者用by type方式的自动装?也就是在注册?br />         Spring的Bean中需要的cd仅拥有一?也可以包括用JDK5的标准来声明事务和安全需?而不是必d你的Spring配置里明设|代?
         如果能找到方法让Spring在没有Q何明的配置(在_applicationContext.xml_?的情况下知道需要ؓ(f)action做什?那么׃
         需要在两个地方l护q个配置?
         当然,有时候可能想要Spring完全来管理bean.q是有实际意义的,例如,如果惌为bean讄更复杂的AOP或者Spring相关的技?
         例如Acegi.Z(jin)辑ֈq个目的,所有必要做的事情是在Spring?applicationContext.xml 里配|bean,然后?xwork.xml
         里改变你的WebWork action的类属性来使用在Spring里面定义的bean的名?而不再用类? 
        xwork.xml文g也会(x)改变actioncȝ属?最后留下的像q样    
         
        <xwork>
       <!-- Include webwork defaults (from WebWork JAR). -->
         <include file="webwork-default.xml" />

       <!-- Configuration for the default package. -->
         <package name="default" extends="webwork-default">
           <action name="register" class="userAction" method="register">
              <result name="success">/pages/registerSuccess.jsp</result>
           </action>
         </package>
       </xwork>
        在applicationContext.xml 里定义了(jin)一个名字ؓ(f) "userAction"的Spring的bean.注意cn.com.nawang.Action.UserAction不需?br />         改变,因ؓ(f)它可能是自动装配的:(x)
        <bean id="userAction" class="cn.com.nawang.action.UserAction" > 
             <property name="userService" ref="userService"/>
        </bean>
       注:(x)bean中的id值必Mxwork.xml中对应的classg致?br />         
   2?ZHibernate3的原生API实现DAO
        Hibernate 3.0.1引入?jin)一个新的特性:(x)“带上下文环境的Session”?q一Ҏ(gu)得Hibernate自n具备?jin)每个事务绑定当?Session 对象的功能?br />          q与Spring中每个Hibernate?Session 与事务同步的功能大致相同?br />    (1)?为Dao创徏基类BaseDao
         public class BaseDao {
         private SessionFactory  sessionFactory;

         public void setSessionFactory(SessionFactory sessionFactory) {
          this.sessionFactory = sessionFactory;
         }
 
         public Session getSession(){
                 Session session = this.sessionFactory.getCurrentSession();
                 return session;
         }
         }
   (2)、在子类Dao中实现具体持久化操作
        public class UserDao extends BaseDao implements IUserDao {
        public void saveUser(User user) throws HibernateException {
              getSession().save(user);
        }     
        }
   (3)、在上下文中配置
        <bean id="baseDao" class="cn.com.nawang.dao.BaseDao">
           <property name="sessionFactory" ref="sessionFactory"/>
        </bean>
    
        <bean id="userDao" class="cn.com.nawang.dao.impl.UserDao" parent="baseDao"/>
       
        <bean id="userService" class="cn.com.nawang.service.impl.UserService">
           <property name="userDao" ref="userDao"/>
        </bean>
   
        <bean id="userAction" class="cn.com.nawang.action.UserAction" > 
          <property name="userService" ref="userService"/>
        </bean>    
     重启服务Q在web面上触发register的actionQ执行后Q抛Z面的异常Q?br />       Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
    google?jin)下Q大概明白了(jin)是因为没有配|了(jin)事务D的错误。在配置事务之前Q查看了(jin)以前的一个采用HibernateDaoSupport实现的项目,记得
     当时q不需要配|事务就可以正常q行。于是,让UserDaol承于HibernateDaoSupportQ修改后的代码如下:(x)
         public class UserDao extends BaseDao implements IUserDao {
        public void saveUser(User user) throws HibernateException {
              getHibernateTemplate().save(user);
        }     
        }
     接下去,修改spring上下文中的相关配|,
       <!--
        <bean id="baseDao" class="cn.com.nawang.dao.BaseDao">
           <property name="sessionFactory" ref="sessionFactory"/>
        </bean>-->
    
        <bean id="userDao" class="cn.com.nawang.dao.impl.UserDao">
           <property name="sessionFactory" ref="sessionFactory"/>
        </bean>
       
        <bean id="userService" class="cn.com.nawang.service.impl.UserService">
           <property name="userDao" ref="userDao"/>
        </bean>
   
        <bean id="userAction" class="cn.com.nawang.action.UserAction" > 
          <property name="userService" ref="userService"/>
        </bean> 
     保存修改后的Q重启服务,再次触发register的actionQ用户信息成功保存?br />     
     LHibernateDaoSupport的dao实现后,又换回基于hibernate3.0原生API的实现方式,Ҏ(gu)之前google后的l果Q给userService配置
     事务Q拷贝了(jin)下之前项目中的配|,q做相应修改Q修改后的内容如下:(x)
       <bean id="baseTransaction"
       class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
        <property name="transactionManager" ref="transactionManager"/>
        <property name="proxyTargetClass" value="true"/>
        <property name="transactionAttributes">
           <props>                
               <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
               <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
               <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>                
               <prop key="save*">PROPAGATION_REQUIRED</prop>                
               <prop key="add*">PROPAGATION_REQUIRED</prop>                
               <prop key="update*">PROPAGATION_REQUIRED</prop>                
               <prop key="delete*">PROPAGATION_REQUIRED</prop>            
           </props>       
        </property>  
    </bean>
   
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>      
   
    <bean id="baseDao" class="cn.com.nawang.dao.BaseDao">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    
    <bean id="userDao" class="cn.com.nawang.dao.impl.UserDao" parent="baseDao"/>
   
    <bean id="userServiceTarget" class="cn.com.nawang.service.impl.UserService">
       <property name="userDao" ref="userDao"/>
    </bean>
   
    <bean id="userService" parent="baseTransaction">
       <property name="target" ref="userServiceTarget"/>
    </bean>
   
    <bean id="userAction" class="cn.com.nawang.action.UserAction" > 
       <property name="userService" ref="userService"/>
    </bean>
   
    保存修改内容Q重启服务,重启中出现错误,查看?jin)spring in action中的相关配置Q发现baseTransactionq个bean的配|稍有不同,
    上面那个配置是参考springside的,当时那个目Ӟq接拿q来用,也没出现问题Q就不认真去考虑Q现在拷贝到现有目中,却出错了(jin)Q?br />     于是先根据书上的介绍做相应修改,改后的内容如下:(x)
       <bean id="baseTransaction"
      class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" lazy-init="true">
        <property name="transactionManager" ref="transactionManager"/>
        <property name="transactionAttributes">
           <props>                
               <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
               <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
               <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>                
               <prop key="save*">PROPAGATION_REQUIRED</prop>                              
               <prop key="update*">PROPAGATION_REQUIRED</prop>                
               <prop key="delete*">PROPAGATION_REQUIRED</prop>            
           </props>       
        </property>  
    </bean>
    L?lt;property name="proxyTargetClass" value="true"/>的配|,abstract="true"改ؓ(f)lazy-init="true"Q保存修?br />     重启服务Qƈ再次触发register的actionQ一切如所ѝ?nbsp;



webber 2010-03-15 10:00 发表评论
]]>
关于面~码的doctypeQ用正的doctype声明http://www.aygfsteel.com/webber/archive/2010/02/11/312566.htmlwebberwebberThu, 11 Feb 2010 02:49:00 GMThttp://www.aygfsteel.com/webber/archive/2010/02/11/312566.htmlhttp://www.aygfsteel.com/webber/comments/312566.htmlhttp://www.aygfsteel.com/webber/archive/2010/02/11/312566.html#Feedback0http://www.aygfsteel.com/webber/comments/commentRss/312566.htmlhttp://www.aygfsteel.com/webber/services/trackbacks/312566.html
虽然doctype被许多h忽视Q但在遵循标准的Mweb文档中,它都是一必需的元素。doctype?x)?jing)响代码验证,q决定了(jin)览器最l如何显CZ的web文档?br />

doctype的作?br /> doctype声明指出阅读E序应该用什么规则集来解释文档中的标记。在web文档的情况下Q?#8220;阅读E序”通常是浏览器或者校验器q样的一个程序,“规则”则是w3c所发布的一个文档类型定义(dtdQ中包含的规则?br />
每个dtd都包括一pd标记、attributes和propertiesQ它们用于标记web文档的内容;此外q包括一些规则,它们规定?jin)哪些标记能出现在其他哪些标C。每个web标准Q比如html 4 frameset和xhtml 1.0 transitionalQ都有自qdtd?br />
假如文档中的标记不遵循doctype声明所指定的dtdQ这个文档除?jin)不能通过代码校验之外Q还有可能无法在览器中正确昄。对于标C一致的问题Q浏览器相较于校验器来说更宽宏V但是,不正的doctype声明l常D|页不正显C,或者导致它们根本不能显C?br />

选择正确的doctype
Z(jin)获得正确的doctype声明Q关键就是让dtd与文档所遵@的标准对应。例如,假定文档遵@的是xhtml 1.0 strict标准Q文档的doctype声明应该引用相应的dtd。另一斚wQ如果doctype声明指定的是xhtml dtdQ但文档包含的是旧式风格的html标记Q就是不恰当的;cM圎ͼ如果doctype声明指定的是html dtdQ但文档包含的是xhtml 1.0 strict标记Q同h不恰当的?br />
有的时候,也可以根本不使用一个doctype声明。如果没有指定有效的doctype声明Q大多数览器都?x)用一个内建的默认dtd。在q种情况下,览器会(x)用内建的dtd来试着昄你所指定的标记。对于一些(f)时性的、匆忙拼凑的文档Q这U文档有许多Q,你确实可以考虑省略doctype声明Qƈ接受览器的默认昄?br />
完全可以从头~写一个doctype声明Qƈ让它指向自己选择的一个dtd。然而,׃大多数web文档都需要遵循由w3c发布的某个国际公认的web标准Q所以那些文档通常都要包含以下标准doctype声明之一Q?br />
html 2Q?br />
<!doctype html public "-/ietf/dtd html 2.0/en">

html 3.2Q?br />
<!doctype html public "-/w3c/dtd html 3.2 final/en">

html 4.01 strictQ?br />
<!doctype html public "-/w3c/dtd html 4.01/en"
"http://www.w3.org/tr/html4/strict.dtd">

html 4.01 transitionalQ?br />
<!doctype html public "-/w3c/dtd html 4.01 transitional/en"
"http://www.w3.org/tr/html4/loose.dtd">

html 4.01 framesetQ?br />
<!doctype html public "-/w3c/dtd html 4.01 frameset/en"
"http://www.w3.org/tr/html4/frameset.dtd">

xhtml 1.0 strictQ?br />
<!doctype html public "-/w3c/dtd xhtml 1.0 strict/en"
"http://www.w3.org/tr/xhtml1/dtd/xhtml1-strict.dtd">

xhtml 1.0 transitionalQ?br />
<!doctype html public "-/w3c/dtd xhtml 1.0 transitional/en"
"http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd">

xhtml 1.0 framesetQ?br />
<!doctype html public "-/w3c/dtd xhtml 1.0 frameset/en"
"http://www.w3.org/tr/xhtml1/dtd/xhtml1-frameset.dtd">

xhtml 1.1Q?br />
<!doctype html public "-/w3c/dtd xhtml 1.1/en"
"http://www.w3.org/tr/xhtml11/dtd/xhtml11.dtd">

xhtml 1.1 plus mathml plus svgQ?br />
<!doctype html public
"-/w3c/dtd xhtml 1.1 plus mathml 2.0 plus svg 1.1/en"
"http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">

除了(jin)上面列出的doctype声明Q具有特D要求的一些文档还使用?jin)其他几U声明?br />
doctype声明通常是文档的W一行,要在<html>标记以及(qing)其他文档内容之前。注意,在xhtml文档中,doctype的前面偶?dng)?x)出现一条xml处理指o(h)Q也UCؓ(f)xml prologQ:(x)

<@xml version="1.0" encoding="utf-8"@>

Z(jin)保|页正确昄和顺利通过验证Q用正的doctype是关键。与内容相反的、不正确的或者Ş式错误的doctype是大量问题的|魁R。在未来的专栏文章中Q我q会(x)具体解释如何诊断?qing)纠正这些问题?br />
用dw设计|页Ӟ新徏一个文Ӟ看代码最前面总要出现一个下面的东东Q?br /> <!doctype html public "-/w3c/dtd html 4.01 transitional/en"
"http://www.w3.org/tr/html4/loose.dtd">
q个是dw自动在网|仉增加?jin)dtd信息.可以?
删除后,览器会(x)使用的默认dtd.


webber 2010-02-11 10:49 发表评论
]]>
webwork2.0配置详解http://www.aygfsteel.com/webber/archive/2010/02/10/312532.htmlwebberwebberWed, 10 Feb 2010 08:44:00 GMThttp://www.aygfsteel.com/webber/archive/2010/02/10/312532.htmlhttp://www.aygfsteel.com/webber/comments/312532.htmlhttp://www.aygfsteel.com/webber/archive/2010/02/10/312532.html#Feedback0http://www.aygfsteel.com/webber/comments/commentRss/312532.htmlhttp://www.aygfsteel.com/webber/services/trackbacks/312532.htmlwebwork2.0配置详解

首先下蝲WebWork2 的最新版?http://www.opensymphony.com/webwork/)?/p>

q里我们所谈及(qing)的WebWorkQ实际上是Webwork+XWork的总集QW(xu)ebwork1.x 版本中,
整个框架采用?jin)紧耦合的设计(cMStrutsQ,?.0 之后QW(xu)ebwork被拆分ؓ(f)两个部分Q?br /> 即Webwork 2.x +XWork 1.xQ设计上的改良带来了(jin)pȝ灉|性上的极大提升?/p>

本例的部|如下图所C?

webwork能ؓ(f)我们做什么:(x)
1Q将Web面中的输入元素装Z个(hQ数据对象?/div>
2Q根据请求的不同Q调度相应的逻辑处理单元Qƈ(hQ数据对象作为参C入?/div>
3Q逻辑处理单元完成q算后,q回一个结果数据对象?/div>
4Q将l果数据对象中的数据与预先设计的表现层相融合q展现给用户?/div>
首先来看d界面Q?br /> index.jsp
<html>
<body>
<form action="/login.action">
<p align="center">
d<br> </p>
用户?<input type="text" name="model.username" /><br>
??:<input type="password" name="model.password" /><br>
<p align="center"><input type="submit" value="提交" name="B1"/><input type="reset" value="重置" name="B2"/></p>
</form>
</body>
</html>
 q里的index.jsp实际上是qhtml l成Q非常简单,其中包含一个表单:(x)
<form action="/login.action">
q表明其提交对象?login.action . 表单中同时包含两个文本输入框Q?br /> <input type="text" name="model.username" />
<input type="password" name="model.password" />
可以看到Q两个输入框的名U均?#8220;model”开_(d)q是因ؓ(f)在这里我们采用了(jin)WebWork
中Model-Driven的Action驱动模式
当表单被提交之时Q浏览器?x)以两个文本框的g为参敎ͼ向Web h?login.action命名的服务?br /> 标准HTTP协议中ƈ没有.actionl尾的服务资源。我们需要在web.xml中加以设定:(x)
……
<servlet>
<servlet-name>webwork</servlet-name>
<servlet-class>
com.opensymphony.webwork.dispatcher.ServletDispatcher
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>webwork</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>

 此后Q所有以.actionl尾的服务请求将由ServletDispatcher 接管?br /> ServletDispatcher 接受到Servlet Container 传递过来的hQ将q行一下几个动作:(x)
1. 从请求的服务名(/login.actionQ中解析出对应的Action名称QloginQ?br /> 2. 遍历 HttpServletRequest、HttpSession、ServletContext 中的数据Qƈ其复制?br /> Webwork的Map实现中,x之后Q所有数据操作均在此Mapl构中进行,从而将内部l构与Servlet API相分R?br /> xQW(xu)ebwork 的工作阶D늻束,数据传递给XWork q行下一步处理。从q里也可以看
到Webwork和xwork之间的切分点QW(xu)ebwork为xwork提供?jin)一个面向Servlet 的协议{?br /> 器,Servlet 相关的数据{构{换成xwork所需要的通用数据格式Q而xwork完成实际的
服务调度和功能实现?br /> q样一来,以xwork为核?j),只需替换外围的协议{换组Ӟ卛_实现不同技术^C间的
切换Q如面向Servlet的Webwork替换为面向JMS的协议{换器实现Q即可在保留应用?br /> 辑实现的情况下,实现不同外部技术^C间的ULQ?br /> 3. 以上qC息作为参敎ͼ调用ActionProxyFactory创徏对应的ActionProxy实例?br /> ActionProxyFactory 根据Xwork 配置文gQxwork.xmlQ中的设定,创徏
ActionProxy实例QActionProxy中包含了(jin)Action的配|信息(包括Action名称Q?br /> 对应实现cȝ{)(j)?br /> 4. ActionProxy创徏对应的Action实例QƈҎ(gu)配置q行一pd的处理程序。包?br /> 执行相应的预处理E序Q如通过Interceptor Map 中的h数据转换为Action
所需要的Java 输入数据对象{)(j)Q以?qing)对Action q行l果q行后处理?br /> ActionInvocation 是这一q程的调度者。而com.opensymphony.xwork.
DefaultActionInvocation 则是XWork 中对ActionInvocation 接口的标准实玎ͼ?br /> 果有_֊可以Ҏ(gu)c进行仔l研读,掌握?jin)这里面的玄机,怿XWork的引?br /> ׃再神U?/p>

下面我们来看配置文gQ?br /> xwork.xmlQ?br /> <!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN"
"http://www.opensymphony.com/xwork/xwork-1.0.dtd">
<xwork>
<include file="webwork-default.xml" />

<package name="default" extends="webwork-default">

<action name="login" class="net.xiaxin.webwork.action.LoginAction">
<result name="success" type="dispatcher">

<param name="location">/main.jsp</param>
</result>
<result name="loginfail" type="dispatcher">

<param name="location">/index.jsp</param>
</result>
<interceptor-ref name="params" />
<interceptor-ref name="model-driven"/>
</action>
</package>
</xwork>
?include
通过include 节点Q我们可以将其他配置文g导入到默认配|文件xwork.xml 中?br /> 从而实现良好的配置划分?br /> q里我们导入?jin)Webwork 提供的默认配|webwork-default.xmlQ位?br /> webwork.jar 的根路径Q?br /> ?package
XWork中,可以通过package对actionq行分组。类似Java 中package和class?br /> 关系。ؓ(f)可能出现的同名Action提供?jin)命名空间上的隔R?br /> 同时Qpackageq支持承关pR在q里的定义中Q我们可以看刎ͼ(x)
extends="webwork-default"
"webwork-default"是webwork-default.xml文g中定义的packageQ这里?br /> q承,"default" package 自动拥有"webwork-default" package 中的所?br /> 定义关系?br /> q个Ҏ(gu)ؓ(f)我们的配|带来了(jin)极大便利。在实际开发过E中Q我们可以根据自w?br /> 的应用特点,定义相应的package模板Qƈ在各个项目中加以重用Q无需再在重复
J琐的配|过E中消耗精力和旉?br /> 此外Q我们还可以在Package节点中指定namespaceQ将我们的action分ؓ(f)若干?br /> 逻辑区间。如Q?br /> <package name="default" namespace="/user"
extends="webwork-default">
将此package中的action定义划归?user 区间Q之后在面调用action的时候,
我们需要用/user/login.action 作ؓ(f)form action 的属性倹{其中的/user/指定了(jin)?br /> action的namespaceQ通过q样的机Ӟ我们可以系l内的actionq行逻辑分类Q?br /> 从而得各模块之间的划分更加清晰?br /> ?action
Action配置节点Q这里可以设定Action的名U和对应实现cR?br /> ?result
通过result 节点Q可以定义Action q回语义Q即Ҏ(gu)q回|军_处理模式以及(qing)
响应界面?br /> q里Q返回?success"QAction 调用q回gؓ(f)String cdQ对应的处理模式?br /> "dispatcher"?br /> 可选的处理模式q有Q?br /> 1. dispatcher
本系l页面间转向。类似forward?br /> 2. redirect
览器蟩转。可转向其他pȝ面?br /> 3. chain
处理结果{交给另外一个Action处理Q以实现Action的链式处理?br /> 4. velocity
指定的velocity模板作ؓ(f)l果呈现界面?br /> 5. xslt
指定的XSLT 作ؓ(f)l果呈现界面?br /> 随后的param节点则设定了(jin)相匹配的资源名称?br /> ?interceptor-ref
讑֮?jin)施加于此Action的拦截器QinterceptorQ。关于拦截器Q请参见E后?#8220;XWork
拦截器体p?#8221;部分?br /> interceptor-ref定义的是一个拦截器的应用,具体的拦截器讑֮Q实际上是
承于webwork-default packageQ我们可以在webwork-default.xml 中找?br /> 对应?params"?model-driven"拦截器设|:(x)
<interceptors>
……
<interceptor name="params"
class="com.opensymphony.xwork.interceptor.ParametersInt
erceptor" />
<interceptor name="model-driven"
class="com.opensymphony.xwork.interceptor.ModelDrivenIn
terceptor" />
……
</interceptors>
"params"大概是Webwork 中最重要、也最常用的一个Interceptor。上面曾l将
MVC工作程划分为几个步骤,其中的第一?
“?Web 面中的输入元素装Z个(hQ数据对?#8221;
是通过"params"拦截器完成。Interceptor 在Action 之前被调用,因而,
Interceptor 也成为将Webwork传来的MAP 格式的数据{换ؓ(f)强类型Java 对象?br />
最?jng)_现场所?br /> "model-driven"则是针对Action 的Model驱动模式的interceptor 实现。具体描
q请参见E后?#8220;Action驱动模式”部分
很可能我们的Action 都需要对q两个interceptor q行引用。我们可以定义一?br /> interceptor-stackQ将其作Z个interceptor l合在所有Action 中引用。如Q上?br /> 的配|文件可修改为:(x)
<xwork>
<include file="webwork-default.xml" />
<package name="default" extends="webwork-default">
<interceptors>
<interceptor-stack name="modelParamsStack">
<interceptor-ref name="params" />
<interceptor-ref name="model-driven" />
</interceptor-stack>
</interceptors>
<action name="login"
class="net.xiaxin.webwork.action.LoginAction">
<result name="success" type="dispatcher">
<param name="location">/main.jsp</param>
</result>
<result name="loginfail" type="dispatcher">
<param name="location">/index.jsp</param>
</result>
<interceptor-ref name="modelParamsStack" />
</action>
</package>
</xwork>
通过引入interceptor-stackQ我们可以减interceptor 的重复申明?br /> 下面是我们的Model对象Q?br /> LoginInfo.javaQ?br /> public class LoginInfo {
private String password;
private String username;
private List messages = new ArrayList();
private String errorMessage;

public List getMessages() {
return messages;
}
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
很简单,q只是一个纯_的值对象(Value-ObjectQ。这里,它扮演着模型QModelQ的
角色Qƈ与Action的输入输出密切相兟?br /> ?SpringMVC中的Command对象不同QW(xu)ebwork 中的Model对象Q扮演着承上启下
的角Ԍ它既是Action的输入参敎ͼ又包含了(jin)Action处理的结果数据?br /> 换句话说Q输入的Httph参数Q将被存储在Model对象传递给Actionq行处理QAction
处理完毕之后Q也结果数据放|到Model 对象中,之后QModel 对象与返回界面融合生
成最后的反馈面?br /> 也正׃此,W者徏议在实际开发中采用Model-Driven 模式Q而非Property-Driven ?br /> 式(见稍?#8220;Action驱动模式”部分Q,q将使得业务逻辑更加清晰可读?br /> 对应的Action代码
public class LoginAction implements Action, ModelDriven {
private final static String LOGIN_FAIL="loginfail";
LoginInfo loginInfo = new LoginInfo();
public String execute() throws Exception {
if ("erica".equalsIgnoreCase(loginInfo.getUsername())
&& "mypass".equals(loginInfo.getPassword())) {
//当前登录的用户名保存到Session
ActionContext ctx = ActionContext.getContext();
Map session = ctx.getSession();
session.put("username",loginInfo.getUsername());
//Z演示目的Q通过编码增加通知消息以供昄
loginInfo.getMessages().add("message1");
loginInfo.getMessages().add("message2");
loginInfo.getMessages().add("message3");
return SUCCESS;
}else{
loginInfo.setErrorMessage("Username/Password Error!");
return LOGIN_FAIL;
}
}
public Object getModel() {
return loginInfo;
}
}

 

 LoginAction实现?jin)两个接口?x)
1. Action
Action接口非常单,它指定了(jin)Action的入口方法(executeQ,q定义了(jin)
几个默认的返回值常量:(x)
public interface Action extends Serializable {
public static final String SUCCESS = "success";
public static final String NONE = "none";
public static final String ERROR = "error";
public static final String INPUT = "input";
public static final String LOGIN = "login";
public String execute() throws Exception;
}

SUCCESS、NONE、ERROR、INPUT、LOGIN 几个字符串常量定义了(jin)常用?br /> 几类q回倹{我们可以在Action 实现中定义自qq回cdQ如本例中的
LOGIN_FAIL定义?br /> 而executeҎ(gu)Q则是Action的入口方法,XWork调用每个Action的execute
Ҏ(gu)以完成业务逻辑处理?br /> 2. ModelDriven
ModelDriven接口更ؓ(f)z:(x)
public interface ModelDriven {
Object getModel();
}
ModelDriven仅仅定义?jin)一个getModelҎ(gu)。XWork在调度ActionӞ?br /> q此Ҏ(gu)获取Model 对象实例QƈҎ(gu)h参数为其讑֮属性倹{而此后的
面q回q程中,XWork 也将调用此方法获取Model 对象实例q将其与讑֮
的返回界面相融合?br /> 注意q里与Spring MVC 不同QSpring MVC ?x)自动?f)逻辑处理单元创徏
Command Class实例Q但Webwork不会(x)自动为Action创徏Model对象实例Q?br /> Model 对象实例的创建需要我们在Action 代码中完成(如LoginAction ?br /> LoginInfo对象实例的创建)(j)?br /> 另外Q如代码注释中所描述Q登录成功之后,我们随即username保存在Session之中Q?br /> q也是大多数d操作必不可少的一个操作过E?br /> q里面牵涉到?jin)Webwork中的一个重要组成部分:(x)ActionContext?br /> ActionContext为Action提供?jin)与容器交互的途径。对于Web 应用而言Q与容器的交?br /> 大多集中在Session、ParameterQ通过ActionContext我们在代码中实现与Servlet API无关?br /> 容器交互?br /> 如上面代码中的:(x)
ActionContext ctx = ActionContext.getContext();
Map session = ctx.getSession();
session.put("username",loginInfo.getUsername());
同样Q我们也可以操作Parameter:
ActionContext ctx = ActionContext.getContext();
Map params = ctx.getParameters();
String username = ctx.getParameters("username");
上述的操作,由XWorkҎ(gu)当前环境Q调用容器相关的讉KlgQWeb 应用对应?br /> 是WebworkQ完成。上面的ActionContext.getSession()QXWork 实际上将通过Webwork
提供的容器访问代?#8220;HttpServletRequest.getSession()”完成?br /> 注意刎ͼActionContext.getSessionq回的是一个Mapcd的数据对象,而非HttpSession?br /> q是׃WebWork对HttpSessionq行?jin){换,使其转变ZServlet API无关的Map对象?br /> 通过q样的方式,保证?jin)Xwork 所面向的是一个通用的开攄构。从而得逻辑层与表现
层无兟뀂增加了(jin)代码重用的可能?br /> ?外, Z(jin)提供与Web 容器直接交互的可能。WebWork q提供了(jin)一?br /> ServletActionContext实现。它扩展?jin)ActionContextQ提供了(jin)直接面向Servlet API的容器访
问机制?br /> 我们可以直接通过ServletActionContext.getRequest 得到当前HttpServletRequest 对象?
引用Q从而直接与Web 容器交互?br /> 获得如此灉|性的代h(hun)是Q我们的代码从此与ServletAPI 紧密耦合Q之后系l在?br /> 同^C间移植就面临更多的挑战Q同时单元测试也难于q行Q?br /> q_UL的需求ƈ不是每个应用都具备。大部分pȝ在设计阶D就已经定其运行^
収ͼ且无太多变更的可能。不q,如果条g允许Q尽量通过ActionContext 与容器交互,?br /> 不是q_相关的ServletActionContextQ这样在利实现功能的同Ӟ也获得了(jin)q_q移?br /> 的潜在优势,何乐而不为?br /> d成功界面Q?br /> main.jsp:
<%@ taglib prefix="ww" uri="webwork"%>
<html>
<body>
<p align="center">Login Success!</p>
<p align="center">Welcome!
<ww:property value="#session['username']"/>
</p>
<p align="center">
<b>Messages:</b><br>
<ww:iterator value="messages" status="index">
<ww:if test="#index.odd == true">
!<ww:property/><br>
</ww:if>
<ww:else>
*<ww:property/><br>
</ww:else>
</ww:iterator>
</p>
</body>
</html>
q里我们引入?jin)Webwork的taglibQ如面代码W一行的x语句?br /> 下面主要使用?jin)三个tag:
 <ww:property value="#session['username']"/>
dModel对象的属性填充到当前位置?br /> value指定?jin)需要读取的Model对象的属性名?br /> q里我们引用?jin)LoginAction在session中保存的’username’对象?br /> ׃对应的ModelQLoginInfoQ中也保存了(jin)username 属性。下面的语句与之
效果相同Q?br /> <ww:property value="username"/>
?JSP2中的ELcMQ对于联对象,q里我们也可以通过“.”操作W获?br /> 其属性|如value="user.username"得到Model 对象中所引用的user
对象的username 属性(假设LoginInfo中包含一个User 对象Qƈ拥有一个名
?#8220;username”的属性)(j)?br /> 关于EL的内Ҏ(gu)较简单,本文׃再单独开辟章节进行探讨?br /> Webwork中包括以下几U特D的EL表达式:(x)
parameter[‘username’] 相当于request.getParameter(“username”);
request[‘username’] 相当于request.getAttribute(“username”);
session[‘username’] 从session中取Z“username”为key的?br /> application[‘username’] 从ServletContext中取Z“username”为key
的?br /> 注意需要用“#”操作W引用这些特D表辑ּ?br /> 另外对于帔RQ需要用单引号包_(d)?session['username'] 中的
'username'?br />  <ww:iterator value="messages" status="index">
q代器。用于对java.util.Collection、java.util.Iterator、java.util.Enumeration,?br /> java.util.Map、Arraycd的数据集q行循环处理?br /> 其中Qvalue属性的语义?lt;ww:property>中一致?br /> ?status属性则指定?jin)@环中的烦(ch)引变量,在@环中Q它?yu)自动递增?br /> 而在下面?lt;ww:if>中,我们通过“#”操作W引用这个烦(ch)引变量的倹{?br /> 索引变量提供?jin)以下几个常用判定方法?x)
first 当前是否为首ơP?br /> last 当前是否为最后一ơP?br /> odd 当前q代ơ数是否奇数
even 当前q代ơ数是否偶数
<ww:if test="#index.odd == true">?lt;ww:else>
用于条g判定?br /> test属性指定了(jin)判定表达式。表辑ּ中可通过“#”操作W对变量q行引用?br /> 表达式的~写语法与java 表达式类伹{?br /> cM的,q有<ww:elseif test="……">?br /> dp|界面
实际上,q个界面即登录界面index.jsp。只是由于之前出于避免干扰的考虑Q隐藏了(jin)
index.jsp中显C错误信息的部分?br /> 完整的index.jsp如下Q?br /> <%@ page pageEncoding="gb2312"
contentType="text/html;charset=gb2312"%>
<%@ taglib prefix="ww" uri="webwork"%>
<html>
<body>
<form action="/login.action">
<p align="center">
d<br>
<ww:if test="errorMessage != null">
<font color="red">
<ww:property value="errorMessage"/>
</font>
</ww:if>
</p>
用户?
<input type="text" name="model.username" />
<br>
??:
<input type="password" name="model.password" />
<br>
<p align="center">
<input type="submit" value="提交" name="B1"/>
<input type="reset" value="重置" name="B2"/>
</p>
</form>
</body>
</html>
q里首先我们q行判断Q如果Model中的errorMessage不ؓ(f)nullQ则昄错误信息。这
P在用L(fng)一ơ登录时Q由于Model对象未创徏QerrorMessage自然为nullQ错误信?br /> 不会(x)昄Q即得到?jin)与之前的index.jsp同样的效果?br />


webber 2010-02-10 16:44 发表评论
]]>Struts2QXWorkQ提供的拦截器的功能说明http://www.aygfsteel.com/webber/archive/2010/02/10/312531.htmlwebberwebberWed, 10 Feb 2010 08:36:00 GMThttp://www.aygfsteel.com/webber/archive/2010/02/10/312531.htmlhttp://www.aygfsteel.com/webber/comments/312531.htmlhttp://www.aygfsteel.com/webber/archive/2010/02/10/312531.html#Feedback0http://www.aygfsteel.com/webber/comments/commentRss/312531.htmlhttp://www.aygfsteel.com/webber/services/trackbacks/312531.html阅读全文

webber 2010-02-10 16:36 发表评论
]]>
document.form.actionhttp://www.aygfsteel.com/webber/archive/2010/02/10/312530.htmlwebberwebberWed, 10 Feb 2010 08:35:00 GMThttp://www.aygfsteel.com/webber/archive/2010/02/10/312530.htmlhttp://www.aygfsteel.com/webber/comments/312530.htmlhttp://www.aygfsteel.com/webber/archive/2010/02/10/312530.html#Feedback1http://www.aygfsteel.com/webber/comments/commentRss/312530.htmlhttp://www.aygfsteel.com/webber/services/trackbacks/312530.html 同一个表单可以根据用L(fng)选择Q提交给不同的后台处理程序。即Q表单的分向提交。如Q在~写论坛E序Ӟ如果我们希望实现用户在发送脓(chung)子的时候,既发送提交功能又有预览功能时Q就?x)遇Cq问题。即Q当用户点击提交按钮Ӟ我们希望表单提交l?提交"处理E序Q而当用户点击预览按钮Ӟ我们希望表单提交l?预览"处理E序。那么,如何实现上述功能呢?下面代码可以很好的解册个问题?nbsp;
<form name="form" method="post">
试表单:<input name="test"><br>
<input type="button" value="提交" onClick=send()>
<input type="button" value="预览" onClick=preview()>
</form>
<script language=javascript>
function send()
  {
    document.form.action="send.asp"
    document.form.submit()
   }
function preview()
   {
     document.form.action="preview.asp"
     document.form.submit()
   }
</script>

         关于上面实例的两点说明:(x)
        1、在整个表单中,不应有名字ؓ(f)action或submit的标{,否则会(x)产生"对象不支持此属性和Ҏ(gu)"的错误。如代码 "<input type='xxxx' name='action' >"在表单中是不允许出现的;
        2、在form标签中应该存在name属性。即Q应该给表单取一个名字。语句document.form.action和document.form.submit中的"form"也就是表单的名字?br />         表单的分向提交不仅仅使用在论坛的E序中,它还可以q用在许多场合下。恰当的q用表单的分向提交功能可以大大的增强|站的h性化E度?

        昨天Q我调试E序出C(jin)q样的问题,是出现?对象不支持此属性和Ҏ(gu)"的错误,一直无法定位出来,都快疯掉?jin),后来在发C个button命名为submit?jin)?br />
1.--------  
   
  <form   name="formname"   action="">  
  <input   name="inputname">  
  <input   type="submit"   onclick="document.formname.action='a.asp'"   value="button   a">  
  <input   type="submit"   onclick="document.formname.action='b.asp'"   value="button   b">  
  <input   type="submit"   onclick="document.formname.action='c.asp'"   value="button   c">  
  </form>      
  2.----------  
  <input   type=button   name="a"   value="a"   onclick="this.form.action='a.asp';this.form.submit();">  
  <input   type=button   name="b"   value="b"   onclick="this.form.action='b.asp';this.form.submit();">  
  <input   type=button   name="c"   value="c"   onclick="this.form.action='c.asp';this.form.submit();">  
  <input   type=button   name="d"   value="d"   onclick="this.form.action='d.asp';this.form.submit();">

webber 2010-02-10 16:35 发表评论
]]>
word 2007 手工制作选择性粘贴快捷键http://www.aygfsteel.com/webber/archive/2010/02/10/312482.htmlwebberwebberWed, 10 Feb 2010 02:56:00 GMThttp://www.aygfsteel.com/webber/archive/2010/02/10/312482.htmlhttp://www.aygfsteel.com/webber/comments/312482.htmlhttp://www.aygfsteel.com/webber/archive/2010/02/10/312482.html#Feedback2http://www.aygfsteel.com/webber/comments/commentRss/312482.htmlhttp://www.aygfsteel.com/webber/services/trackbacks/312482.html用过办公软gword的h都知道,快捷键对我们的工作有多么重要。据_(d)真正的电(sh)脑高手们很少使用鼠标操作Q绝大多数操作都直接通过键盘实现。但有些操作在Y件本wƈ没有自带Q这U情况下需要我们开动脑{,自已动手创徏快捷键?/p>

下面我们?#8220;_脓(chung)”中的“选择性粘?#8221;ZQ介l下自己创徏pȝ中所没有的快捷键的步骤。其它的快捷键以此类推?/p>

用wordӞ复制_脓(chung)是必不可的操作步骤。以前在word 97 时代Q能_脓(chung)到Word中的只是U文本的文字Q现在更多的Z用的?003、xp版本Q粘贴结果就是有格式的文字,q包括图片、甚臌根{这个新功能当然有它的好处,可是如果我只需要源文g中的U文字,不想要格式、图片,那就需要用到它所附带的选择性粘贴功能。目前word2007提供的方法有两个Q?/p>

1. 在粘贴结束后Q会(x)自动出现一个Q动的“_脓(chung)选项”按钮Q用鼠标按这个按钮,选择“仅保留文?#8221;卛_。这个方法的~点是,_脓(chung)动作比较慢(因ؓ(f)无用的内Ҏ(gu)较多Q?/p>

2. 不是用一般的“_脓(chung)”功能Q而在菜单中?#8220;~辑”--“选择性粘?#8221;--“无格式文?#8221;卛_。这个方法执行速度快,但操作步骤多Q太ȝ(ch)?/p>

下面通过自己创徏宏来解决q个问题Q实现快捷键操作Q就象按一下ctrl+V可以实现粘贴一栗这个过E分两步Q一是徏立一个实?#8220;选择性粘?#8221;的宏Q二是给q个宏指定键盘快捷键?/p>

一、创?#8220;选择性粘?#8221;功能的宏

1、打开word 2007Q选择开发工具下?#8220;Visual Basic~辑?#8221;Q或者直接按Alt+F11也可以。这时会(x)出现一个Visual Basic~辑H口Q现在看看你的窗口中左侧位置是否有某个模块存在?如果已经有了(jin)Q你可以跌建立新模块这一步。如果你的系l在Normal下面不存在Q何模块,那么在Normal上,打开右键菜单Q选插入模块?/p>

2、现在模块已l有?jin),用鼠标点M之高亮,然后按F7键(直接双击模块也可以)(j)。这样右侧就?x)出C码窗口?/p>

3、将下面的代码粘贴到“代码H口”中。关闭Visual Basic~辑H口。这P一个宏徏立好?jin)?/p>

Sub 无格式粘?)

'无格式粘?Macro

'宏在 2005-9-22 ?SQ 录制

Selection.PasteSpecial Link:=False, DataType:=wdPasteText, Placement:=wdInLine, DisplayAsIcon:=False
End Sub

到这一步,可以自动q行选择性粘贴的宏就创徏成功?jin),但这时候用它q需要到“工具—宏—宏”Q选择相应的宏名称来运行它Q比较麻?ch)。想快捷使用Ql向下看?/p>


二、将宏拖到工hQƈ指定键盘快捷?/p>

在Wordȝ口中Q找到word选项,选择工具按钮中的“自定?#8221;?/p>

?#8220;从下列位|选择命o(h)”选项卡,?#8220;?#8221;Q会(x)出现我们刚徏立的宏。用鼠标这个宏拖到双快速访问工h位置Q松开鼠标键。请单击修改按钮Q在弹出菜单中作相应的图标、名U。这样工h中就有了(jin)刚才制作的选择性粘贴的宏的快捷按钮?jin)?/p>

再指定快捷键Q此?#8220;自定?#8221;对话框依然打开着Q请?#8220;键盘快捷方式”按钮旁的“自定?#8221;?#8220;cd”?#8220;?#8221;Q在“?#8221;中选定EditPasteNoFormat。这?#8220;h新快捷键”应该是空白的Q用鼠标点一下这里,然后按一下你惌的快捷键。这里,假设我们参考粘贴的快捷键ctrl+V,而用alt+V,出现“未指?#8221;Q说明这是一个可用的快捷键,和其它功能不发生冲突。按“指定”按钮。现在alt+V被指定ؓ(f)q个宏的快捷键了(jin)。按“关闭”按钮Q再 关闭“自定?#8221;H口。(上面的步骤中既设|了(jin)工具栏按钮,也设|了(jin)键盘快捷键,也可以只指定其中的一个,看各Z用习(fn)惯而定。)(j)

以后再用WORDӞ我们可以按这个工h钮,或者用alt+v快捷键方便地实现“_脓(chung)为纯文本”的功能了(jin)。其它功能的快捷键也可以照葫芦画瓢?/p>

webber 2010-02-10 10:56 发表评论
]]>
J2EE常见问题?qing)经验汇总(转蝲Q?/title><link>http://www.aygfsteel.com/webber/archive/2010/01/13/309317.html</link><dc:creator>webber</dc:creator><author>webber</author><pubDate>Wed, 13 Jan 2010 07:26:00 GMT</pubDate><guid>http://www.aygfsteel.com/webber/archive/2010/01/13/309317.html</guid><wfw:comment>http://www.aygfsteel.com/webber/comments/309317.html</wfw:comment><comments>http://www.aygfsteel.com/webber/archive/2010/01/13/309317.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/webber/comments/commentRss/309317.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/webber/services/trackbacks/309317.html</trackback:ping><description><![CDATA[<p>*****************web开发的问题汇?*******************</p> <p><br /> 2.      Hibernate优化问题。如何优化数据库讉KQɽE序讉K数据库更优化?</p> <p> 初用HIBERNATE的h也许都遇到过性能问题Q实现同一功能Q用HIBERNATE与用JDBC性能相差十几倍很正常Q如果不?qing)早调整Q很可能影响整个目的进度?</p> <p>  大体上,对于HIBERNATE性能调优的主要考虑点如? </p> <p>  * 数据库设计调?</p> <p>  * HQL优化 </p> <p>  *  API的正?如根据不同的业务cd选用不同的集合及(qing)查询API) </p> <p>  * 主配|参?日志Q查询缓存,fetch_size, batch_size{? </p> <p>* 映射文g优化(ID生成{略Q二U缓存,延迟加蝲Q关联优? </p> <p>  * 一U缓存的理 </p> <p>  * 针对二~存Q还有许多特有的{略 </p> <p>  * 事务控制{略?</p> <p>  1?数据库设?</p> <p>  a) 降低兌的复杂?</p> <p>  b) 量不用联合主?</p> <p>  c) ID的生成机Ӟ不同的数据库所提供的机制ƈ不完全一?</p> <p>  d) 适当的冗余数据,不过分追求高范式 </p> <p>  2?HQL优化 </p> <p>  HQL如果抛开它同HIBERNATE本n一些缓存机制的兌QHQL的优化技巧同普通的SQL优化技巧一P可以很容易在|上扑ֈ一些经验之谈?</p> <p>  3?主配|?</p> <p>  a) 查询~存Q同下面讲的~存不太一P它是针对HQL语句的缓存,卛_全一L(fng)语句再次执行时可以利用缓存数据。但是,查询~存在一个交易系l?数据变更频繁Q查询条件相同的机率q不?中可能会(x)起反作用:它会(x)白白耗费大量的系l资源但却难以派上用场?</p> <p>  b) fetch_sizeQ同JDBC的相兛_C用类|参数q不是越大越好,而应Ҏ(gu)业务特征去设|?</p> <p>  c) batch_size同上?</p> <p>  d) 生pȝ中,切记要关掉SQL语句打印?</p> <p>  4?~存 </p> <p>  a) 数据库~存:q~存是最高效和安全的Q但不同的数据库可管理的层次q不一P比如Q在ORACLE中,可以在徏表时指定整个表|于~存当中?</p> <p>  b) SESSION~存:在一个HIBERNATE SESSION有效Q这U缓存的可干预性不强,大多于HIBERNATE自动理Q但它提供清除缓存的Ҏ(gu)Q这在大扚w增加/更新操作是有效的。比如,同时增加十万条记录,按常规方式进行,很可能会(x)发现OutofMemeroy的异常,q时可能需要手动清除这一U缓?Session.evict以及(qing)Session.clear </p> <p>  c) 应用~存:在一个SESSIONFACTORY中有效,因此也是优化的重中之重,因此Q各cȝ略也考虑的较多,在将数据攑օq一U缓存之前,需要考虑一些前提条? </p> <p>  i. 数据不会(x)被第三方修改(比如Q是否有另一个应用也在修改这些数?) </p> <p>  ii. 数据不会(x)太大 </p> <p>  iii. 数据不会(x)频繁更新(否则使用CACHE可能适得其反) </p> <p>  iv. 数据?x)被频繁查?</p> <p>  v. 数据不是关键数据(如涉?qing)钱Q安全等斚w的问??</p> <p>  ~存有几UŞ式,可以在映文件中配置:read-only(只读Q适用于很变更的?rn)态数?历史数据)Qnonstrict-read-writeQread-write(比较普遍的Ş式,效率一?Qtransactional(JTA中,且支持的~存产品较少) </p> <p>  d) 分布式缓?同c)的配|一P只是~存产品的选用不同Q在目前的HIBERNATE中可供选择的不多,oscache, jboss cacheQ目前的大多数项目,对它们的用于集群的?特别是关键交易系l?都持保守态度。在集群环境中,只利用数据库U的~存是最安全的?</p> <p>  5?延迟加蝲 </p> <p>  a) 实体延迟加蝲:通过使用动态代理实?</p> <p>  b) 集合延迟加蝲:通过实现自有的SET/LISTQHIBERNATE提供?jin)这斚w的支?</p> <p>  c) 属性gq加? </p> <p>  6?Ҏ(gu)选用 </p> <p>  a) 完成同样一件事QHIBERNATE提供?jin)可供选择的一些方式,但具体用什么方式,可能用性能/代码都会(x)有媄(jing)响。显C,一ơ返回十万条记录(List/Set/Bag/Map{?q行处理Q很可能D内存不够的问题,而如果用Z游标(ScrollableResults)或Iterator的结果集Q则不存在这L(fng)问题?</p> <p>  b) Session的load/getҎ(gu)Q前者会(x)使用二~存Q而后者则不用?</p> <p>  c) Query和list/iteratorQ如果去仔细研究一下它们,你可能会(x)发现很多有意思的情况Q二者主要区?如果使用?jin)SpringQ在HibernateTemplate中对应find,iteratorҎ(gu)): </p> <p>  i. list只能利用查询~存(但在交易pȝ中查询缓存作用不?Q无法利用二U缓存中的单个实体,但list查出的对象会(x)写入二~存Q但它一般只生成较少的执行SQL语句Q很多情况就是一?无关??</p> <p>  ii. iterator则可以利用二U缓存,对于一条查询语句,它会(x)先从数据库中扑և所有符合条件的记录的IDQ再通过IDȝ存找Q对于缓存中没有的记录,再构造语句从数据库中查出Q因此很Ҏ(gu)知道Q如果缓存中没有MW合条g的记录,使用iterator?x)生N+1条SQL语句(N为符合条件的记录? </p> <p>  iii. 通过iteratorQ配合缓存管理APIQ在量数据查询中可以很好的解决内存问题Q如: </p> <p>  while(it.hasNext()){ </p> <p>  YouObject object = (YouObject)it.next(); </p> <p>  session.evict(youObject); </p> <p> sessionFactory.evice(YouObject.class, youObject.getId()); </p> <p>  } </p> <p>  如果用listҎ(gu)Q很可能出OutofMemory错误?jin)?</p> <p>  iv. 通过上面的说明,我想你应该知道如何去使用q两个方法了(jin)?</p> <p>  7?集合的选用 </p> <p>  在HIBERNATE 3.1文档?#8220;19.5. Understanding Collection performance”中有详细的说明?</p> <p>  8?事务控制 </p> <p>  事务斚wҎ(gu)能有媄(jing)响的主要包括:事务方式的选用Q事务隔ȝ别以?qing)锁的选用 </p> <p>  a) 事务方式选用:如果不涉?qing)多个事务管理器事务的话Q不需要用JTAQ只有JDBC的事务控制就可以?</p> <p>  b) 事务隔离U别:参见标准的SQL事务隔离U别 </p> <p>  c) 锁的选用:(zhn)观?一般由具体的事务管理器实现)Q对于长事务效率低,但安全。乐观锁(一般在应用U别实现)Q如在HIBERNATE中可以定义VERSION字段Q显?dng)如果有多个应用操作数据,且这些应用不是用同一U乐观锁机制Q则乐观锁会(x)失效。因此,针对不同的数据应有不同的{略Q同前面许多情况一P很多时候我们是在效率与安全/准确性上找一个^衡点Q无论如何,优化都不是一个纯技术的问题Q你应该对你的应用和业务特征有够的?jin)解?</p> <p>  9?扚w操作 </p> <p>  即是用JDBCQ在q行大批数据更新ӞBATCH与不使用BATCH有效率上也有很大的差别。我们可以通过讄batch_size来让其支持批量操作?</p> <p>  举个例子Q要扚w删除某表中的对象Q如“delete Account”Q打出来的语句,?x)发现HIBERNATE扑և?jin)所有ACCOUNT的IDQ再q行删除Q这主要是ؓ(f)?jin)维护二U缓存,q样效率肯定高不?jin),在后l的版本中增加了(jin)bulk delete/updateQ但q也无法解决~存的维护问题。也是_(d)׃有了(jin)二~存的维护问题,HIBERNATE的批量操作效率ƈ不尽如h? </p> <p>3.      |站是动态的Q需要频J访问数据库Q如何提高访问速度Q减服务器压力Q?</p> <p>提供JDBC数据库链接池׃n,大大降低数据库压力; </p> <p>动态HTMLQ大大减网l数据流量; </p> <p>量数据优化Q大大提高登录和讉K速度Q?</p> <p>用户界面和数据缓存,大大提高d速度Q?</p> <p>多层ơ体pȝ构,支持多个应用E序服务器ƈ行,大大提高pȝ伸羃性,q发讉K用户数目和数据安全?</p> <p>4.      搜烦(ch)引擎优化Q如何提高网站排名。优化有哪些具体技术措施? </p> <p>   |站l构设计中面向搜索引擎的优化注意事项包括Q?</p> <p>1)链接引用的重要?</p> <p>a.以量取胜Q不一定加入传l门L(fng)站的分类目录才是|站推广Q来自其他网站的M反相链接都是有用?</p> <p>b. 以质取胜Q被PageRank高的|站引用能更快地提高PageRank </p> <p>c. ?jin)解搜?ch)引擎?价D"Q不要通过Link Farm提高自n的站Ҏ(gu)名:(x)Google?x)惩|那些主动链接到Link Farm站点以提高自w排名站点,相应站点的页面将不会(x)被收入到索引中。但如果你的面被别的Link Farm链接?jin)也不必担?j)Q因U被动的链接是不?x)被惩罚的?</p> <p>d. 不要吝啬l其他网站的链接Q如果一个网只有大量的q入链接Q而缺乏导出链接,也会(x)被搜索引擎认为是没有价值的站点?</p> <p>2)如何H出关键词:(x)|页标题、主题的设计 </p> <p>a.Theme Engine正在逐步过PRQ成为结果排序中更主要的因素 </p> <p>b.不要I着标题Q空着<title></title>无异于浪费了(jin)最有h(hun)值的一块阵?</p> <p>c. 标题长度和内容:(x)不要q长Q一般在40个字(80个字?以内Qƈ充分H出关键词的比重 </p> <p>d. 如果|页很多的话Q尽量用不同的|页标题Q争取让自己|站的内Ҏ(gu)多的q入搜烦(ch)引擎索引范围 </p> <p>e. 除了(jin)<title></title>外,q可以用<h1></h1>标题行突出内容主题, 加强标题的效?</p> <p>3)面?qing)站点结构设计注意事?</p> <p>a. ?rn)态链? 大部分搜索引擎都认ؓ(f)?rn)态链接的|页是优质网,Google在优先抓取烦(ch)引的|页?0%以上是不带参数链接的?rn)态网c(din)而且即同样的内容,?rn)态网也 ?x)比动态网|重高 </p> <p>b. 能够q入Google索引的页面数量越多越?</p> <p>c. |站目录l构要扁qI因ؓ(f)每深一U目录,PAGERANK降低1Q?个档ơ。假N|3Q其子可能目录就??jin),更深可能无法列入评U范围了(jin)?</p> <p>d. 表现和内容的分离Q?#8220;l色”|页 </p> <p>|页中的javascript和css可能和|页分离Q一斚w提高代码重用度(也方侉K面缓存)(j)Q另外一斚wQ由于有效内容占|页长度的百分比高,也能提高相关关键词在面中的比重也增加了(jin)。MQ应该鼓励遵循w3c的规范,使用更规范的XHTML和XML作ؓ(f)昄格式便于内容更长旉的保存?</p> <p>e. 让所有的面都有能够快速入口:(x)站点地图Q?方便|页爬虫QspiderQ快速遍历网站所有需要发布的内容。如果首就是用Flash或图片进入的话,无异于将搜烦(ch)引擎拒之门外Q除?jin)UI设计的用?友好外,spider friendly也是非常重要?</p> <p>f. 保持|站自n的健P(x)l常利用?链检查工h查网站中是否有死?</p> <p>g. 保持|页内容/链接的稳定性和持久性:(x)在搜索引擎烦(ch)引中|页存在的历史也是一个比较重要的因素Q而且历史比较久的|页被链接的几率高。ؓ(f)?保证自己|页能够被比较持久的被其他网站的面引用Q如果自q中有链接更新时Q最好能保留旧的面q做好链接{向,以保持内容的q箋性?</p> <p>h. 文gcd因素QGoogle有对PDF, Word(Power Point, Excel), PS文档的烦(ch)引能力,׃q种文档的内Ҏ(gu)一般的HTMLl过?jin)更多的整理Q学术h(hun)g般比较高Q所以这些类型的文档天生比一般的HTMLcd的文?PageRank要高。因此,对于比较重要的文档:(x)技术白皮书QFAQQ安装文档等使用PDF PS{高U格式存取,q样在搜索结果中也能获得比较靠前的位zhi点访问统计的重要性等Q,的设?nbsp; </p> <p>4)以及(qing)站点讉Kl计的重要性等 </p> <p>5)Google的站点设计指?</p> <p>1.Make a site with a clear hierarchy and text links. Every page should be reachable from at least one static text link.  让网站有着清晰的结构和文本链接Q所有的面臛_要有一个静(rn)态文本链接入?</p> <p>Ҏ(gu)Q尽量不要用囄和JAVASCRIPT </p> <p>2.Offer a site map to your users with links that point to the important parts of your site. If the site map is larger than 100 or so links, you may want to break the site map into separate pages. </p> <p>为用h供一个站点地图:(x)转向|站的重要部分。如果站点地N面超q?00个链接,则需要将面分成多个面?</p> <p>Ҏ(gu)Q烦(ch)引页不要过100个链接:(x)SPIDER只考虑面中头100个链?</p> <p>3.Create a useful, information-rich site and write pages that clearly and accurately describe your content. </p> <p>用一些有用的Q信息量丰富的站点,清晰q正的描述你的信息?</p> <p>4.Think about the words users would type to find your pages, and make sure that your site actually includes those words within it. </p> <p>惛_用户可能用来扑ֈ你的关键词,q保证这些关键词在网站中出现?</p> <p>Ҏ(gu)Q少?#8220;最?#8221;Q?#8220;最?#8221;之类的Ş容词Q用用户最兛_(j)的词Q比如:(x)下蝲Q歌星名字,而不是一些抽象名词?</p> <p>5.Try to use text instead of images to display important names, content, or links. The Google crawler doesn't recognize text contained in images. </p> <p>可能用文本,而不是图片显C重要的名称Q内容和链接。GOOGLE的机器h不认识图片中的文字?</p> <p>6.Make sure that your TITLE and ALT tags are descriptive and accurate. </p> <p>保证Q页面的TITLE和ALT标记正确的精描q?</p> <p>7.Check for broken links and correct HTML. </p> <p>(g)查坏铑ƈ修正q些HTML错误?</p> <p>8.If you decide to use dynamic pages (i.e., the URL contains a '?' character), be aware that not every search engine spider crawls dynamic pages as well as static pages. It helps to keep the parameters short and the number of them small. </p> <p>如果你打用动态页面:(x)链接中包??"Q必M(jin)解:(x)q所有的搜烦(ch)引擎的机器h能想对待?rn)态页面一样对待动态页面,保持动态页面的参数可能的也?很有帮助?</p> <p>9.Keep the links on a given page to a reasonable number (fewer than 100). </p> <p>让一个页面中的链接少?00个?</p> <p>Ҏ(gu)Q用lynx -dump <a >http://www.chedong.com/</a> 可以模拟从robot角度看到的页面。其最后有链接l计 </p> <p>5.      hibernate对动态查询的理解Q如何应用,q作应用CZ?</p> <p>定义Q?</p> <p>??rn)态查询:(x)在编E时已经定要查询的字段Q这时编写的HQL或QBCUCؓ(f)?rn)态查询?</p> <p>?动态查询:(x)在编E时无法定要查询的字段Q这时编写的HQL或QBCUCؓ(f)动态查询。比如组合查询时Q往往需要查询的很多,但不是每个项都必需?</p> <p>QHQL适用于静(rn)态查询,QBC适用于动态查询)(j) </p> <p>以下分别用HQL和QBC实现动态查询:(x) </p> <p>1Q下面的E序通过对字W串的拼装用HQL语句实现动态查询:(x) </p> <p>Public List findStu(String name, int age){ </p> <p>StringBuffer queryString= new StringBuffer(); </p> <p>Boolean conditionFound= false; </p> <p>if(name!=null){ </p> <p>queryString.append(“lower(s.name) like :name”); </p> <p>conditionFound= true; </p> <p>}if(age!= 0){ </p> <p>if(conditionFound) queryString.append(“and”); </p> <p>queryString.append(“s.age= :age”); </p> <p>conditionFound=true; </p> <p>} </p> <p>String fromClause= conditionFound?”fromStudent s where” : ”fromStudent s”; </p> <p>queryString.insert(0,fromClause).append(“order by s.name”); </p> <p>Query query=getSession().createQuery(“queryString.toString()”); </p> <p>if(name!=null)query.setString(“name”,’%’+name.toLowerCase()+’%’); </p> <p>if(age!=0)query.setInteger(“age”,newInteger(age)); </p> <p>return query.list(); </p> <p>} </p> <p>上面的代码虽然可以正常工作,但是把简单的功能实现的相当复杂,l护h不方ѝ我们来看一下用QBC查询?</p> <p>Public List findStu(String name, int age){ </p> <p>Criteria crit= getSession().createCriteria(Student.class); </p> <p>if(name!=null){ </p> <p>crit.add(Restrictions.like(“name”,name,MatchMode.ANYWHERE)); </p> <p>}if(age!=0){ </p> <p>crit.add(Restrictions.eq(“age”,newInteger(age))); </p> <p>} </p> <p>crit.addOrder(Order.asc(“name”)); </p> <p>return crit.list(); </p> <p>} </p> <p>6.      Hibernate问题 </p> <p>?nbsp;    a different object with the same identifier value was already associated with the session是什么原因导致的Q?</p> <p>在hibernate中同一个session里面有了(jin)两个相同标识但是是不同实体,当这时运行saveOrUpdate(object)操作的时候就?x)报q个错误。种错误l常出现在一对多映射和多对多映射 </p> <p>在hibernate的开发中QHBM文g中会(x)涉及(qing)到n2m的种U关p,但是Q只有在Z必要性考虑的时候,才加上cascade="all" Q同Ӟ需心(j)规避由此引v的程序ExceptionQ?</p> <p>考虑不周Q会(x)D可能出现的最常见Exception是:(x) </p> <p>net.sf.hibernate.NonUniqueObjectException </p> <p>a different object with the same identifier value was already associated with the session:...... </p> <p>解决办法是:(x) </p> <p>1. L引vException的associated ClassҎ(gu)HBM中的不必要cascadeQ?</p> <p>2. (g)查Exception发生位置的session的用情况; </p> <p>?nbsp;    Object references an unsaved transient instance-save the transient instance before flushing是什么原因导致的Q?</p> <p>某个对象的某个属性是一个实体,在这个实体没有保存之前就保存q个对象而造成?jin)这个错误?</p> <p>以下举个例子说明以下 </p> <p>Session session = dao.getSession(); </p> <p>Transaction tx = session.beginTransaction(); </p> <p>Bo.setBman( form ,man,session); </p> <p>Bo.saveChangeTable( man,session); // 把man当作属性赋lC(j)hangeTable,q保存ChangeTable. 是q出的错Q?</p> <p>dao.save(man,session);  // 保存man </p> <p>tx.commit(); </p> <p>==================== 应该q样写:(x)=============== </p> <p>Session session = dao.getSession(); </p> <p>Transaction tx = session.beginTransaction(); </p> <p>Bo.setBman( form ,man,session); </p> <p>dao.save(man,session);  // 保存man </p> <p>Bo.saveChangeTable( man,session); // 把man当作属性赋lC(j)hangeTable,q保存ChangeTable </p> <p>tx.commit(); </p> <p>q样Q问题就解决?jin)?</p> <p> </p> <p>?nbsp;    如果修改一个列表中的一个数据,?x)发现这个数据不E_Q一?x)是修改后的Q一?x)是修改前的Q说出其原因 </p> <p>因ؓ(f)hibernate利用?jin)缓存技术,sql适时提交Q当数据修改以后Q数据ƈ不一定及(qing)时提交到数据库,而是攑֜hibernate的缓存中Q当我们察看数据Ӟ可能是提交完的,也可能是没有提交的,所以就?x)出现数据的脏读?</p> <p>如何避免使用~存技术所带来的脏数据问题呢? </p> <p>在设计、实现和试Ӟ应该清晰定义~存数据的更斎ͼ(x) </p> <p>i. 不考虑~存数据的更斎ͼ重启软gpȝ是一U必要的方式Q?</p> <p>ii. 不考虑~存数据的更斎ͼ~存数据不可能成数据(但在软gpȝ中,往往“不可?#8221;?x)在一ơ又一ơ的重构之后变ؓ(f)“可能”)Q?</p> <p>iii. 考虑~存数据的更斎ͼ当源数据变化Ӟ实时更新~存数据?</p> <p>?nbsp;    对于数据库自增长来说Q在映射文g中主键配|,用哪U配|方案最好,最不容易出现问题? </p> <p>Hibernate标识生成{略Q?</p> <p>标识W生成器 描述 </p> <p>increment 适用于代理主键。由Hibernate自动以递增方式生成?</p> <p>identity     适用于代理主键。由底层数据库生成标识符?</p> <p>sequence  适用于代理主键。HibernateҎ(gu)底层数据库的序列生成标识W,q要求底层数据库支持序列?</p> <p>hilo       适用于代理主键。Hibernate分局high/low法生成标识W?</p> <p>seqhilo     适用于代理主键。用一个高/低位法来高效的生成longQshort或者intcd的标识符?</p> <p>native适用于代理主键。根据底层数据库对自动生成标识符的方式,自动选择identity、sequence或hilo?</p> <p>uuid.hex   适用于代理主键。Hibernate采用128位的UUID法生成标识W?</p> <p>uuid.string       适用于代理主键。UUID被编码成一?6字符长的字符丌Ӏ?</p> <p>assigned   适用于自然主键。由Java应用E序负责生成标识W?</p> <p>foreign     适用于代理主键。用另外一个相兌的对象的标识W?</p> <p>p个问题我认ؓ(f)应该用increment、native都可?</p> <p>7.       概括你常用的框架的优~点?</p> <p>1. Struts的优~点Q?</p> <p>具体来讲QStruts的优Ҏ(gu)Q?</p> <p>1. 实现MVC模式Q结构清?使开发者只x业务逻辑的实? </p> <p>2. 有丰富的tag可以?,Struts的标记库(Taglib)Q如能灵zd用,则能大大提高开发效率。另外,q前国内的JSP开发者而言Q除?jin)用JSP自带的常用标记外Q很开发自q标记Q或许Struts是一个很好的L(fng)?</p> <p>3. 面D.面D是今后的一个发展方向,事实上,q样做,使系l的脉络更加清晰。通过一个配|文Ӟ卛_把握整个pȝ各部分之间的联系Q这对于后期的维护有着莫大的好处。尤其是当另一批开发者接手这个项目时Q这U优势体现得更加明显?</p> <p>4. 提供Exception处理机制 . </p> <p>5. 数据库链接池理 </p> <p>6. 支持I18N </p> <p>~点Q?</p> <p>一?转到展示层时Q需要配|forwardQ每一ơ{到展C层Q相信大多数都是直接转到jspQ而涉?qing)到转向Q需要配|forwardQ如果有十个展示层的jspQ需要配|十ơstrutsQ而且q不包括有时候目录、文件变_(d)需要重C改forwardQ注意,每次修改配置之后Q要求重新部|整个项目,而tomcateq样的服务器Q还必须重新启动服务器,如果业务变更复杂频繁的系l,q样的操作简单不可想象。现在就是这P几十上百个h同时在线使用我们的系l,大家可以惌一下,我的?ch)恼有多大?</p> <p>二?Struts 的Action必需是threadQsafe方式Q它仅仅允许一个实例去处理所有的h。所以action用到的所有的资源都必需l一同步Q这个就引v?jin)线E安全的问题?</p> <p>三?试不方? Struts的每个Action都同W(xu)eb层耦合在一Pq样它的试依赖于Web容器Q单元测试也很难实现。不q有一个Junit的扩展工具Struts TestCase可以实现它的单元试?</p> <p>四?cd的{? Struts的FormBean把所有的数据都作为StringcdQ它可以使用工具Commons-Beanutilsq行cd转化。但它的转化都是在ClassU别Q而且转化的类型是不可配置的。类型{化时的错误信息返回给用户也是非常困难的?</p> <p>五?对Servlet的依赖性过? Struts处理Action时必需要依赖ServletRequest 和ServletResponseQ所有它摆脱不了(jin)Servlet容器?</p> <p>六?前端表达式语a斚w.Struts集成?jin)JSTLQ所以它主要使用JSTL的表辑ּ语言来获取数据。可是JSTL的表辑ּ语言在Collection和烦(ch)引属性方面处理显得很弱?</p> <p>七?对Action执行的控制困? Struts创徏一个ActionQ如果想控制它的执行序会(x)非常困难。甚至你要重新去写Servlet来实C的这个功能需求?</p> <p>八?对Action 执行前和后的处理. Struts处理Action的时候是Zclass的hierarchiesQ很隑֜action处理前和后进行操作?</p> <p>?ji)?对事件支持不? 在struts中,实际是一个表单Form对应一个Actionc?或DispatchAction)Q换一句话_(d)(x)在Struts中实际是一个表单只能对应一个事Ӟstrutsq种事g方式UCؓ(f)application eventQapplication event和component event相比是一U粗_度的事件?</p> <p>Struts重要的表单对象ActionForm是一U对象,它代表了(jin)一U应用,q个对象中至包含几个字D,q些字段是Jsp面表单中的input字段Q因Z个表单对应一个事Ӟ所以,当我们需要将事g_度l化到表单中q些字段Ӟ也就是说Q一个字D对应一个事件时Q单U用Struts׃太可能,当然通过l合JavaScript也是可以转弯实现的?</p> <p> </p> <p>       2QHibernate的优~点Q?</p> <p>Hibernate是一个开放源代码的对象关pL框Ӟ它对JDBCq行?jin)非常轻量的对象封装,使得JavaE序员可以随?j)所Ʋ的使用对象~程思维来操U|据库?</p> <p>Hibernate可以应用在Q何用JDBC的场合,既可以在Java的客L(fng)E序实用Q也可以在Servlet/JSP的Web应用中用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMPQ完成数据持久化的重仅R?</p> <p>大多数开发机构经帔R取创建各自独立的数据持久层。一旦底层的数据l构发生改变Q那么修改应用的其余部分使之适应q种改变的代价将是十分巨大的。Hibernate适时的填补了(jin)q一I白Q它为Java应用提供?jin)一个易用的、高效率的对象关pL框架。hibernate是个轻量U的持久性框Ӟ功能却非怸富?</p> <p>优点Q?</p> <p>a. Hibernate 使用 Java 反射机制而不是字节码增强E序来实现透明性?</p> <p>b. Hibernate 的性能非常好,因ؓ(f)它是个轻量框架。映的灉|性很?gu)?</p> <p>c. 它支持各U关pL据库Q从一对一到多对多的各U复杂关pR?</p> <p>~点Q它限制(zhn)所使用的对象模型?例如Q一个持久性类不能映射到多个表)其独有的界面和可怜的?jng)场份额也让Z安,管如此QHibernate q是以其强大的发展动力减M(jin)q些风险。其他的开源持久性框架也有一些,不过都没?Hibernate q样有市(jng)场冲d?</p> <p>3Q?Spring框架的优~点 </p> <p>它是一个开源的目Q而且目前非常z跃Q它ZIoCQInversion of ControlQ反向控Ӟ(j)和AOP的构架多层j2eepȝ的框Ӟ但它不强q你必须在每一层中必须使用SpringQ因为它模块化的很好Q允怽Ҏ(gu)自己的需要选择使用它的某一个模块;它实C(jin)很优雅的MVCQ对不同的数据访问技术提供了(jin)l一的接口,采用IoC使得可以很容易的实现bean的装配,提供?jin)简z的AOPq据此实现Transcation ManagmentQ等{?</p> <p>优点 </p> <p>   a. Spring能有效地l织你的中间层对象,不管你是否选择使用?jin)EJB。如果你仅仅使用?jin)Struts或其他ؓ(f)J2EE?API特制的frameworkQSpring致力于解军_下的问题?</p> <p>   b. Spring能消除在许多工程中常见的对Singleton的过多用。根据我的经验,q是一个很大的问题Q它降低?jin)系l的可测试性和面向对象的程度?</p> <p>   c. 通过一U在不同应用E序和项目间一致的Ҏ(gu)来处理配|文ӞSpring能消除各U各栯定义格式的属性文件的需要。曾l对某个c要L的是哪个法般的属性项或系l属性感C解,为此不得不去读Javadoc甚至源编码?有了(jin)SpringQ你仅仅需要看看类的JavaBean属性。Inversion of Control的用(在下面讨论)(j)帮助完成?jin)这U简化?</p> <p>  d.  通过把对接口~程而不是对cȝE的代h(hun)几乎减少到没有,Spring能够?j)进L好的~程?fn)惯?</p> <p>  e. Spring被设计ؓ(f)让用它创徏的应用尽可能的依赖于他的APIs。在Spring应用中的大多C务对象没有依赖于Spring?</p> <p>  f. 使用Spring构徏的应用程序易于单元测试?</p> <p>  g.  Spring能EJB的用成Z个实现选择,而不是应用架构的必然选择。你能选择用POJOs或local EJBs来实C务接口,却不?x)?jing)响调用代码?</p> <p>  h. Spring帮助你解册多问题而无需使用EJB。Spring能提供一UEJB的替换物Q它们适用于许多web应用。例如,Spring能用AOP提供声明性事务管理而不通过EJB容器Q如果你仅仅需要与单个数据库打交道Q甚至不需要一个JTA实现?</p> <p>  i.  Spring为数据存取提供了(jin)一个一致的框架,不论是用的是JDBCq是O/R mapping产品 </p> <p>Spring实使你能通过最单可行的解决办法来解决你的问题。而这是有有很大h(hun)值的?</p> <p>~点Q用hC多、jsp中要写很多代码、控制器q于灉|Q缺一个公用控制器 </p> <p>8.       是否?jin)解设计模式Q将几种常用的设计模式的思想、ƈ举例?</p> <p>创徏模式Q?</p> <p>Factory、PrototypeQ原型)(j)、Builder、Singleton </p> <p>l构模式Q?</p> <p>Facade(外观)、Proxy(代理)、Adapter(适配?、Composite(l合)、Decorator(Ҏ(gu)?、Bridge、Flyweight(享元) </p> <p>行ؓ(f)模式Q?</p> <p>Template、Memento(备忘机制)、Observer、Chain of Responsibility(职责?、Command、State、Strategy({略)、Mediator(中介?、Interdivter(解释?、Visitor </p> <p>9.       面重复hQ如何解冻I客户的行为是无法控制的,那如何控制客L(fng)重复hD的重复提交?</p> <p>Jsp防止面h表单自提交重复提交思\Q?</p> <p>1. 提交后禁用提交按钮(大部分h都是q样做的Q?</p> <p>2. 用javascript实现 </p> <p>10.   如何_记录同时在线人数 </p> <p>   我们可以利用Servlet规范中定义的事g监听器(ListenerQ来解决q个问题Q实现更准确的在Uh数统计功能。对每一个正在访问的用户QJ2EE应用服务器会(x)为其建立一个对应的HttpSession对象。当一个浏览器W一ơ访问网站的时候,J2EE应用服务器会(x)新徏一个HttpSession对象Qƈ触发HttpSession创徏事gQ如果注册了(jin)HttpSessionListener事g监听器,则会(x)调用HttpSessionListener事g监听器的sessionCreatedҎ(gu)。相反,当这个浏览器讉Kl束时的时候,J2EE应用服务器会(x)销毁相应的HttpSession对象Q触发HttpSession销毁事Ӟ同时调用所注册HttpSessionListener事g监听器的sessionDestroyedҎ(gu)?</p> <p>  可见Q对应于一个用戯问的开始和l束Q相应的有sessionCreatedҎ(gu)和sessionDestroyedҎ(gu)执行。这P我们只需要在HttpSessionListener实现cȝsessionCreatedҎ(gu)中让计数器加1Q在sessionDestroyedҎ(gu)中让计数器减1Q就L实现?jin)网站在Uh数的l计功能?</p> <p>  下面是利用HttpSessionListener实现在线人数l计的一个例子,q个例子已经在中创Y件的J2EE应用服务器InforWeb中测试通过?</p> <p>  首先Q编写一个简单的计数器,代码如下Q?</p> <p>package gongfei.cmc.articles.onlinecounter; </p> <p>public class OnlineCounter { </p> <p>    private static long online = 0;     </p> <p>    public static long getOnline() { </p> <p>        return online; </p> <p>    }     </p> <p>    public static void raise(){ </p> <p>        online++; </p> <p>    }  </p> <p>    public static void reduce(){ </p> <p>        online--; </p> <p>   } </p> <p>} </p> <p>  然后Q编写HttpSessionListener实现c,在这个实现类的sessionCreatedҎ(gu)中调用OnlineCounter的raiseҎ(gu)Q在sessionDestroyedҎ(gu)中调用OnlineCounter的reduceҎ(gu)Q代码如下:(x) </p> <p>package gongfei.cmc.articles.onlinecounter; </p> <p>import javax.servlet.http.HttpSessionEvent; </p> <p>import javax.servlet.http.HttpSessionListener; </p> <p>public class OnlineCounterListener implements HttpSessionListener { </p> <p>    public void sessionCreated(HttpSessionEvent hse) { </p> <p>        OnlineCounter.raise(); </p> <p>    } </p> <p>    public void sessionDestroyed(HttpSessionEvent hse) { </p> <p>        OnlineCounter.reduce(); </p> <p>    } </p> <p>} </p> <p>  再然后,把这个HttpSessionListener实现cL册到|站应用中,也就是在|站应用的web.xml中加入如下内容:(x) </p> <p><web-app> </p> <p>    …… </p> <p>    <listener> </p> <p>        <listener-class> </p> <p>            gongfei.cmc.articles.example.OnlineCounterListener </p> <p>        </listener-class> </p> <p>    </listener> </p> <p>    …… </p> <p></web-app> </p> <p>OKQ在Uh数统计功能已l实玎ͼ只要在JSP面中加入下面这L(fng)脚本p昄但前在线人数?jin)?x) </p> <p><%@ page language="java" pageEncoding="GB2312" %> </p> <p><%@ page language="java" pageEncoding="GB2312" %> </p> <p><%@ page import="gongfei.cmc.articles.onlinecounter.OnlineCounter" %> </p> <p><html> </p> <p>    <head><title>On Line Counert</title></head> </p> <p>    <body bgcolor="#FFFFFF"> </p> <p>        On line:<%=OnlineCounter.getOnline()%> </p> <p>    </body> </p> <p></html> </p> <p>11.   q解决Ҏ(gu)。是否遇到过Q有哪些Q讲解具体遇到的情ŞQƈ说出你在具体的应用中的解x案?</p> <p>1.JSP输出中文的ؕ码问?</p> <p>所谓在jsp输出中文Q即直接在jsp中输Z文,或者给变量赋中文值再输出{,q种情况下的q问题往往是因为没有给jsp面制定昄中文字符的编码方式,解决办法如下Q?</p> <p>1)在jsp面头部加上语句<%@ page contentType="text/html;charset=utf-8"%>(在Servlet中用httpServletResponse.setContentTypeQ?text/html;charset=utf-8"Q,最好同时在jsp面的head部分加上<meta http-equiv="Content-Type" content="text/html;charset="utf-8"> </p> <p>2)在每ơ要输出中文的地方主动{换编码方式,比如要在面中输?#8220;中文”二字Q就可以用以下的Ҏ(gu)Q?</p> <p><% </p> <p>   String str="中文"; </p> <p>   byte[] tmpbyte=str.getBytes("ISO8859_1"); </p> <p>   str=new String(tmpbyte); </p> <p>   out.println(str); </p> <p>%> </p> <p>对于以上q两U方法,昄W一U方法更通用一点,只需要在一个页面中d一ơ代码即可;而对于第二种Ҏ(gu)Q在每个需要输Z文的地方都需要{码,如果q样的地方很多,q将是一个繁重的工作?</p> <p>2.获取表单提交的数据时的中文ؕ码问?</p> <p>在没有加M其他处理之前Q用request.getParameter("paramName")获取表单提交中的数据Q且表单数据中含有中文时Q返回的字符串会(x)呈现q。出现这U问题的原因是Tomcat的j2ee实现对表单提交,即以POST方式提交的参数采用默认的ISO-8859-1来处理?</p> <p>解决此问题的办法有两个:(x) </p> <p>1)不修改其他配|,只是在将表单中的中文数据区出来后再{换编码,Ҏ(gu)如语?String str=request.getParameter("chStr");String str = new String(str.getBytes("ISO-8859-1"),"UTF-8");但这U方法只是从一个局部来考虑问题Q如果这L(fng)情况很多Q就要写很多ơ,势必加大工作量?</p> <p>2)让对所有页面的h都通过一个FilterQ将处理字符集设|ؓ(f)utf-8Q根据自己需要也可以讄成其他的Q如gb2312QgbkQ。具体做法参考Tomcat的webapps/servlet-exemples目录有一个完整的例子,也可以参考其中web.xml和SetCharacterEncodingFilter的配|? </p> <p>3.URL中的中文问题 </p> <p>对于直接通过在url中传递中文参??a href="http://localhost:8080/a.jsp?str">http://localhost:8080/a.jsp?str</a>="中文"q样的gethQ在服务器端用request.getParameter("name")时返回的往往是ؕ码。按照以上的做法讄Filter没有用,用request.setCharacterEncoding("utf-8")的方式,仍然不管用。造成q种l果的原因是Tomcat中以get方式提交的请求对query-string处理旉用了(jin)和postҎ(gu)不一L(fng)处理方式?</p> <p>解决q个问题的方法是是打开Tomcat安装目录下的/conf/server.xml文g,扑ֈConnector?往其中dURLEncoding="utf-8"/> </p> <p>4.数据库访问时的ؕ码问?</p> <p>数据库中所有表的编码方式和jsp中的使用的编码要保持一?q样做的目的可以减少不必要的~码转换问题.另外,在用jdbcq接MySQL数据库时,q接字符串写成如下Ş式可以避免一些中文问? </p> <p>jdbc://mysql://hostname:port/DBname?user=username&password=pwd&useUnicode=true&character Encoding=utf-8 </p> <p>如果是以数据源的方式q接数据库,配置文g中用:(x) </p> <p><parameter> </p> <p>   <name>url</name> </p> <p>   <value>jdbc:mysql://hostname:port/DBname?&useUnicode=true&characterEncoding=utf-8 </p> <p>   </value> </p> <p></parameter> </p> <p>但是如果使用一个已l存在的数据库,数据库的~码方式为ISO-8859-1Q而W(xu)eb应用中用的utf-8Q且数据库已l有很多重要的信息,因此不能通过更改数据库的~码方式来解冟뀂这个时候,在往数据库中写数据时Q一定要在jdbcq接字符串中加入“useUnicode=true&characterEncoding=ISO-8859-1”Q这样可以顺利的王数据库写入正常的数据。但是,在将数据d数据库时Qؕ码又?x)出玎ͼq个时候就应该在数据取出时对其转码Q可以将转码功能写ؓ(f)一个函敎ͼ具体实现如下Q?</p> <p>public String charConvert(String src){ </p> <p>String result=null; </p> <p>if(src!=null){ </p> <p>  try{ </p> <p>   result=new String(src.getBytes("ISO-8859-1"),"UTF-8"); </p> <p>  }catch(Exception e){ </p> <p>   result=null; </p> <p>  } </p> <p>} </p> <p>return result; </p> <p>} </p> <p>于是Q在数据库读出数据过后调用charConvert(rs.getString("colName"));q样可以正常的昄数据库中的中文数据了(jin)?/p> <img src ="http://www.aygfsteel.com/webber/aggbug/309317.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/webber/" target="_blank">webber</a> 2010-01-13 15:26 <a href="http://www.aygfsteel.com/webber/archive/2010/01/13/309317.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <a href="http://www.aygfsteel.com/" title="狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频">狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频</a> </div> </footer> վ֩ģ壺 <a href="http://" target="_blank">׺</a>| <a href="http://" target="_blank">괨</a>| <a href="http://" target="_blank">ʦ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ﶫ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ƽ</a>| <a href="http://" target="_blank">Ž</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Դ</a>| <a href="http://" target="_blank">齭</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ٷ</a>| <a href="http://" target="_blank">ƺ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ƽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Т</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ƽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ͨ</a>| <a href="http://" target="_blank">̨</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ֶ</a>| <a href="http://" target="_blank">ٳ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>