??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲精品中文字幕无码A片老,中文亚洲AV片在线观看不卡,亚洲成年看片在线观看http://www.tkk7.com/hummer008/category/28088.html不走d?要走p无间?/description>zh-cnSat, 30 Jul 2016 20:45:23 GMTSat, 30 Jul 2016 20:45:23 GMT60Ҏ(gu)不同参数加蝲不同的配|文?Spring ContextLoaderListenerhttp://www.tkk7.com/hummer008/articles/348683.htmlhummerhummerThu, 21 Apr 2011 02:25:00 GMThttp://www.tkk7.com/hummer008/articles/348683.html 2. l承ContextLoader Q重?protected WebApplicationContext createWebApplicationContext(
            ServletContext servletContext, ApplicationContext parent)
            throws BeansException {}Q方法;

codeQ?br />
public class ContextLoaderListener implements ServletContextListener {

    private ContextLoader contextLoader;


    /**
     * Initialize the root web application context.
     */
    public void contextInitialized(ServletContextEvent event) {
        this.contextLoader = createContextLoader();
        this.contextLoader.initWebApplicationContext(event.getServletContext());
    }

    /**
     * Create the ContextLoader to use. Can be overridden in subclasses.
     * @return the new ContextLoader
     */
    protected ContextLoader createContextLoader() {
        return new CasContextLoader();
    }

    /**
     * Return the ContextLoader used by this listener.
     * @return the current ContextLoader
     */
    public ContextLoader getContextLoader() {
        return this.contextLoader;
    }


    /**
     * Close the root web application context.
     */
    public void contextDestroyed(ServletContextEvent event) {
        if (this.contextLoader != null) {
            this.contextLoader.closeWebApplicationContext(event.getServletContext());
        }
    }

}


public class CasContextLoader extends ContextLoader {

    protected WebApplicationContext createWebApplicationContext(
            ServletContext servletContext, ApplicationContext parent)
            throws BeansException {
       
//        return super.createWebApplicationContext(servletContext, parent);
        Class contextClass = determineContextClass(servletContext);
        if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
            throw new ApplicationContextException("Custom context class [" + contextClass.getName() +
                    "] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]");
        }

        ConfigurableWebApplicationContext wac =
                (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
        wac.setParent(parent);
        wac.setServletContext(servletContext);
        String configLocation = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
        String flag=CasConstants.IS_USE_MEMCACHED;
       
        if (configLocation != null) {
            String[] xml=StringUtils.tokenizeToStringArray(configLocation,ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS);
            if(flag!=null && flag.equalsIgnoreCase("true")){
                String[] new_xml=StringUtils.addStringToArray(xml, "/WEB-INF/cas_memcached.xml");
                wac.setConfigLocations(new_xml);
            }else{
                wac.setConfigLocations(xml);
            }
           
        }

        wac.refresh();
        return wac;
    }

}




hummer 2011-04-21 10:25 发表评论
]]>
eclipse 快捷键用ȝhttp://www.tkk7.com/hummer008/articles/271707.htmlhummerhummerWed, 20 May 2009 06:06:00 GMThttp://www.tkk7.com/hummer008/articles/271707.htmlhttp://www.tkk7.com/hummer008/comments/271707.htmlhttp://www.tkk7.com/hummer008/articles/271707.html#Feedback0http://www.tkk7.com/hummer008/comments/commentRss/271707.htmlhttp://www.tkk7.com/hummer008/services/trackbacks/271707.html
2、查N中的下一?Ctr+kQ反?Ctr+Shift+k

3、大写转化QCtr+Shift+X Ctr+Shift+Y

4、ctrl+tQctrl+t+tQ?查看cLҎ(gu)的承结?

5、ctrl+shift+u 查看变量在哪里被引用?

6、ctrl+shift+gQalt+shift+hQ?查看Ҏ(gu)在哪里被调用?

7、ctrl+l 定位行号

8、选中cd 点击Edit 选择 Copy qualified Name 可以把类的完整\径copy下来 同样Ҏ(gu)法名也适用

9、Go to Next/Last Member          Ctrl+Shift+Down/Up

10、Copy Lines                 Ctrl+Alt+Down/Up

11、ctrl+r,查找资源文g

12、ctrl+t 查看cd?br />
13、ctrl+shift+f 代码格式?

hummer 2009-05-20 14:06 发表评论
]]>
采用p6spy完整昄hibernate的SQL语句 (OK)http://www.tkk7.com/hummer008/articles/236432.htmlhummerhummerFri, 24 Oct 2008 08:22:00 GMThttp://www.tkk7.com/hummer008/articles/236432.htmlhttp://www.tkk7.com/hummer008/comments/236432.htmlhttp://www.tkk7.com/hummer008/articles/236432.html#Feedback0http://www.tkk7.com/hummer008/comments/commentRss/236432.htmlhttp://www.tkk7.com/hummer008/services/trackbacks/236432.html     select * from xxx where value=?
    但是有时候我们需要得到完整的SQL语句Q怎么办呢Q用P6SPY可以完成这个Q?

    p6spy是一个开源YӞ它可以跟tQ何用jdbc的应用生的数据库操作。特别适合于监控ejb服务器生的 sql statements?br />     官方|址Q?a >http://www.p6spy.com/
    目前p6spy 适用的应用服务器包括jboss, atg, orion, jonas, iplanet, weblogic, websphere, resin and tomcat.

下面我介l一下p6spy在tomcat应用E序上安装的步骤Q?br /> Q?Q?a >http://www.p6spy.com/download.htmlQ下载zip?br /> Q?Q解压出p6spy.jar spy.properties两个文g
Q?Q将p6spy.jar 攑օ应用E序的WEB-INF/lib目录Q将spy.properties攑օWEB-INF/classes目录
Q?Q修改spy.properties

    realdriver  =com.mysql.jdbc.Driver  这行前面的#L
    logfile     = c:/spy.log  修改一个你需要的日志文g?br />    
Q?Q修改hibernate.xmlQ修改connection.driver_class的gؓcom.p6spy.engine.spy.P6SpyDriver
Q?Q重启tomcat
Q?Q这样在c:/下的spy.log记录了数据库的访问情c?/p>

hummer 2008-10-24 16:22 发表评论
]]>
查询性能问题 http://www.tkk7.com/hummer008/articles/235651.htmlhummerhummerTue, 21 Oct 2008 05:54:00 GMThttp://www.tkk7.com/hummer008/articles/235651.htmlhttp://www.tkk7.com/hummer008/comments/235651.htmlhttp://www.tkk7.com/hummer008/articles/235651.html#Feedback0http://www.tkk7.com/hummer008/comments/commentRss/235651.htmlhttp://www.tkk7.com/hummer008/services/trackbacks/235651.html1.传递一lagent_id 提高SQL性能Q不要一ơ传递一个agent_id

select agent_id agentId ,count(service_type) counts, sum(time_to_sec(end_time)-time_to_sec

(start_time)) seconds from et_service_log where service_type=? and site_id=? and agent_id in (?, ?,

?, ?, ?, ?, ?, ?, ?, ?)  group by agent_id

SQLQuery sqlQuery = this.getSession().createSQLQuery(conditionSql);
sqlQuery.setParameterList("agentId", agentIdList);

2.M明细表关pL询优?br />  
普遍Ҏ(gu)?先查询主表IDLIST,再通过每个ID,获取一l明l表中的数据
优化Ҏ(gu)?M?LEFT JOIN 一ơ执行就可以把相x据RESRARCH

CODE Q?br />  Criteria criteria = createCriteria(MessageCategory.class)
        .add(Restrictions.eq("entityPk.siteId", siteId))
        .add(Restrictions.eq("deleted", false));
   criteria.createAlias("messageContentSet",

"messageContentSet",JoinFragment.LEFT_OUTER_JOIN).setFetchMode("messageContentSet",

FetchMode.JOIN).add(
     Restrictions.eq("messageContentSet.deleted", false)).addOrder

(Order.desc("entityPk.id"));
   List listData=criteria.list();  
   Set set =new HashSet(listData); (* qo重复数据)



hummer 2008-10-21 13:54 发表评论
]]>
hashMap 便捷遍历http://www.tkk7.com/hummer008/articles/234387.htmlhummerhummerWed, 15 Oct 2008 02:43:00 GMThttp://www.tkk7.com/hummer008/articles/234387.htmlhttp://www.tkk7.com/hummer008/comments/234387.htmlhttp://www.tkk7.com/hummer008/articles/234387.html#Feedback0http://www.tkk7.com/hummer008/comments/commentRss/234387.htmlhttp://www.tkk7.com/hummer008/services/trackbacks/234387.html
@SuppressWarnings("unchecked")
          public static void listHashMap() {
          Map hashmap = new java.util.HashMap();
          for (int i = 0; i < 10; i++ ) {
           hashmap.put(""+i, "thanks"+i);
          }
          java.util.Iterator it = hashmap.entrySet().iterator();
          while (it.hasNext()) {
           java.util.Map.Entry entry = (java.util.Map.Entry) it.next();
           System.out.println(entry.getValue());
          }
          
        }
         
         @SuppressWarnings("unchecked")
          public static void newlistHashMap() {
          Map hashmap = new java.util.HashMap();
          for (int i = 0; i < 10; i++ ) {
           hashmap.put(""+i, "thanks"+i);
          }
          Set set = hashmap.entrySet();          
          for (Object obj : set) {
              Map.Entry e =(Map.Entry)obj;
              System.out.println(e.getKey()+":"+e.getValue());
        }
        }



hummer 2008-10-15 10:43 发表评论
]]>
dwr session error问题解决http://www.tkk7.com/hummer008/articles/226013.htmlhummerhummerMon, 01 Sep 2008 02:01:00 GMThttp://www.tkk7.com/hummer008/articles/226013.htmlhttp://www.tkk7.com/hummer008/comments/226013.htmlhttp://www.tkk7.com/hummer008/articles/226013.html#Feedback0http://www.tkk7.com/hummer008/comments/commentRss/226013.htmlhttp://www.tkk7.com/hummer008/services/trackbacks/226013.html 而控制台则输?
2007-5-29 11:58:53 org.directwebremoting.util.CommonsLoggingOutput error
严重: A request has been denied as a potential CSRF attack.
的错误信?
h被拒l因为可能存在csrf(cross-site request forgeries,跨站h伪?d.
也就是说面URL可能被跨站了的服务所调用.

------解决Ҏ(gu):

在web.xml配置文g?.
dwr的配|?br />

<servlet>
  
<servlet-name>dwr-invoker</servlet-name>
  
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
  
<init-param>
   
<param-name>debug</param-name>
   
<param-value>true</param-value>
  
</init-param>
  
<init-param>   
            
<param-name>crossDomainSessionSecurity</param-name>   
            
<param-value>false</param-value>   
        
</init-param>
 
</servlet>


加入corssDomainSessionSecurityq个配置选项..q个参数是在dwr版本2.0才有?默认gؓtrue,也就?/p> 止其他域发送请?
corssDomainSessionSecurity:讄成false能够从其他域q行h.注意q样做会在安全性上有一些冒?

hummer 2008-09-01 10:01 发表评论
]]>
业务层中使用拦截?/title><link>http://www.tkk7.com/hummer008/articles/222271.html</link><dc:creator>hummer</dc:creator><author>hummer</author><pubDate>Fri, 15 Aug 2008 07:38:00 GMT</pubDate><guid>http://www.tkk7.com/hummer008/articles/222271.html</guid><wfw:comment>http://www.tkk7.com/hummer008/comments/222271.html</wfw:comment><comments>http://www.tkk7.com/hummer008/articles/222271.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/hummer008/comments/commentRss/222271.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/hummer008/services/trackbacks/222271.html</trackback:ping><description><![CDATA[W一部分 拦截器实?<br />   <br /> <p>package com.infowarelab.cem.easytouch.web.interceptor;</p> <p>import java.lang.reflect.Method;</p> <p>import org.aopalliance.intercept.MethodInterceptor;<br /> import org.aopalliance.intercept.MethodInvocation;<br /> import org.springframework.beans.factory.InitializingBean;</p> <p>import com.infowarelab.cem.easytouch.service.cache.JbossCache;<br /> import com.infowarelab.common.log.Log;<br /> import com.infowarelab.common.log.LogFactory;</p> <p>public class FlushGroupCacheInterceptor implements MethodInterceptor,</p> <p>InitializingBean {</p> <p> protected Log log = LogFactory.getLog(FlushGroupCacheInterceptor.class);</p> <p> private static final long serialVersionUID = 2366041803410037545L;</p> <p> private JbossCache cache;</p> <p> private Integer siteId;</p> <p> public void setCache(JbossCache cache) {</p> <p>  this.cache = cache;<br />  }</p> <p> public Object invoke(MethodInvocation invocation) throws Throwable {</p> <p>  Object result = invocation.proceed();</p> <p>  flushGroupCache(invocation);</p> <p>  return result;</p> <p> }</p> <p> private void flushGroupCache(MethodInvocation invocation)<br />    throws NoSuchMethodException {</p> <p>  // extends ActionSupport<br />   // HttpSession session = ServletActionContext.getRequest().getSession();<br />   // String<br />   // siteId=(String)session.getAttribute(CEMConstants.SESSION_KEY_SITE_ID);</p> <p>  siteId = Context.getCurrentSiteId();</p> <p>  if (siteId == null) {<br />    return;<br />   }</p> <p>  String methodName = invocation.getMethod().getName();</p> <p>  log.info("--------------------");<br />   log.info("methodName:" + methodName);<br />   log.info("--------------------");</p> <p>  Class[] paramsType = invocation.getMethod().getParameterTypes();</p> <p>  Class methodNameClass = invocation.getThis().getClass();</p> <p>  Method m = methodNameClass.getMethod(methodName, paramsType);</p> <p>  boolean flag = m.isAnnotationPresent(OsCacheFlushGroupName.class);<br />   if (flag) {<br />    OsCacheFlushGroupName groupName = m<br />      .getAnnotation(OsCacheFlushGroupName.class);<br />    log.info("--------------------");<br />    log.info("groupName:" + "" + siteId + groupName.value());<br />    log.info("--------------------");<br />    cache.flushGroup("" + siteId + groupName.value());<br />   }<br />  }</p> <p> public void afterPropertiesSet() throws Exception {</p> <p>  // TODO Auto-generated method stub</p> <p> }<br /> }<br /> <br /> W?部分:web层数据传?br /> </p> <p>package com.infowarelab.cem.easytouch.web.interceptor;</p> <p>public class Context {</p> <p>  private static ThreadLocal<Integer> currentSiteId = new ThreadLocal<Integer>();  <br />     <br />       private Context(){}  <br />     <br />       //q个Ҏ(gu)由Filter在请求达到时Ҏ(gu)会话(e.g HttpSessionQ但不限于HttpSession)情况调用讄  <br />       public static void setCurrentSiteId(Integer siteId) {  <br />        currentSiteId.set(siteId);  <br />       }  <br />     <br />       //q个Ҏ(gu)Q可被同一JVM中的M其他Ҏ(gu)调用?nbsp; <br />       //q回当前h者的IdQ没有登录,则返回null  <br />       public static Integer getCurrentSiteId() {  <br />           return currentSiteId.get();  <br />       }  <br />     <br /> }<br /> </p> <p><br /> W?部分:web层数据传递通过filter,或web层Interceptor实现<br /> </p> <p>package com.infowarelab.cem.easytouch.filter;</p> <p>import java.io.IOException;</p> <p>import javax.servlet.Filter;<br /> import javax.servlet.FilterChain;<br /> import javax.servlet.FilterConfig;<br /> import javax.servlet.ServletException;<br /> import javax.servlet.ServletRequest;<br /> import javax.servlet.ServletResponse;<br /> import javax.servlet.http.HttpServletRequest;<br /> import javax.servlet.http.HttpSession;</p> <p>import com.infowarelab.cem.common.util.CEMConstants;<br /> import com.infowarelab.cem.easytouch.web.interceptor.Context;</p> <p>public class SiteIdFilter implements Filter {</p> <p> public void destroy() {<br />   // TODO Auto-generated method stub</p> <p> }</p> <p> public void doFilter(ServletRequest request, ServletResponse response,<br />    FilterChain filterChain) throws IOException, ServletException {<br />   // TODO Auto-generated method stub</p> <p>  setSiteIdToContext(request);<br />   <br />   filterChain.doFilter(request, response);<br />  }</p> <p> private void setSiteIdToContext(ServletRequest request) {<br />   String siteId = "";<br />   HttpServletRequest req = (HttpServletRequest) request;</p> <p> <br />   HttpSession session = req.getSession();<br />   if (session.getAttribute(CEMConstants.SESSION_KEY_SITE_ID) != null) {<br />    siteId = (String) session<br />      .getAttribute(CEMConstants.SESSION_KEY_SITE_ID);<br />    Context.setCurrentSiteId(new Integer(siteId));<br />    return;<br />   }<br />   <br />   siteId = req.getParameter("siteId");<br />   if (siteId != null && siteId.trim().length() > 0) {<br />    Context.setCurrentSiteId(new Integer(siteId));<br />    return;<br />   }</p> <p> }</p> <p> public void init(FilterConfig config) throws ServletException {<br />   // TODO Auto-generated method stub</p> <p> }</p> <p>}<br /> </p> <img src ="http://www.tkk7.com/hummer008/aggbug/222271.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/hummer008/" target="_blank">hummer</a> 2008-08-15 15:38 <a href="http://www.tkk7.com/hummer008/articles/222271.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java IP 解析http://www.tkk7.com/hummer008/articles/219354.htmlhummerhummerFri, 01 Aug 2008 07:28:00 GMThttp://www.tkk7.com/hummer008/articles/219354.htmlhttp://www.tkk7.com/hummer008/comments/219354.htmlhttp://www.tkk7.com/hummer008/articles/219354.html#Feedback0http://www.tkk7.com/hummer008/comments/commentRss/219354.htmlhttp://www.tkk7.com/hummer008/services/trackbacks/219354.html public class IPUtil {
   
   
    public static long IPToLong(String ipAddress)
    {
        String[]   ipqi_ary=ipAddress.split("\\.");       
        long ip0= new Long(ipqi_ary[0]).longValue();
        long ip1= new Long(ipqi_ary[1]).longValue();
        long ip2= new Long(ipqi_ary[2]).longValue();
        long ip3= new Long(ipqi_ary[3]).longValue();
        return (ip0 << 24) + (ip1 << 16) + (ip2 << 8) + ip3;
    }

    public static String LongToIP(long ipAddress)
    {
        long ui1 = ipAddress & 0xFF000000;
        ui1 = ui1 >> 24;
        long ui2 = ipAddress & 0x00FF0000;
        ui2 = ui2 >> 16;
        long ui3 = ipAddress & 0x0000FF00;
        ui3 = ui3 >> 8;
        long ui4 = ipAddress & 0x000000FF;
        String IPstr = "";
        IPstr = String.valueOf(ui1) + "." + String.valueOf(ui2) + "."
                + String.valueOf(ui3) + "." + String.valueOf(ui4);
        return IPstr;
    }

    public static void  main(String args[]){
       
        //
        String ipAddress="255.255.255.255";
       
        long ipInt=IPUtil.IPToLong(ipAddress);
       
        System.out.println("String to int :"+ipInt);
       
        System.out.println("int to String :"+IPUtil.LongToIP(ipInt));
    }
   
}



hummer 2008-08-01 15:28 发表评论
]]>
相对路径 l对路径(?http://www.tkk7.com/hummer008/articles/218735.htmlhummerhummerWed, 30 Jul 2008 07:17:00 GMThttp://www.tkk7.com/hummer008/articles/218735.htmlhttp://www.tkk7.com/hummer008/comments/218735.htmlhttp://www.tkk7.com/hummer008/articles/218735.html#Feedback0http://www.tkk7.com/hummer008/comments/commentRss/218735.htmlhttp://www.tkk7.com/hummer008/services/trackbacks/218735.html1.基本概念的理?/strong>

l对路径Q绝对\径就是你的主上的文件或目录在硬盘上真正的\径,(URL和物理\?例如Q?br /> C:xyz est.txt 代表了test.txt文g的绝对\径。http://www.sun.com/index.htm也代表了一个URLl对路径?br />
相对路径Q相对与某个基准目录的\径。包含Web的相对\径(HTML中的相对目录Q,例如Q在
Servlet中,"/"代表Web应用的跟目录。和物理路径的相对表C。例如:"./" 代表当前目录,"../"代表上目录。这U类似的表示Q也是属于相对\径?br /> 另外关于URIQURL,URN{内容,请参考RFC相关文档标准?br />
RFC 2396: Uniform Resource Identifiers (URI): Generic Syntax,
(http://www.ietf.org/rfc/rfc2396.txt)


2.关于JSP/Servlet中的相对路径和绝对\径?/strong>

2.1服务器端的地址

服务器端的相对地址指的是相对于你的web应用的地址Q这个地址是在服务器端解析的(不同于html和javascript中的相对地址Q他们是由客L览器解析的Q也是说这时候在jsp和servlet中的相对地址应该是相对于你的web应用Q即相对于http: //192.168.0.1/webapp/的?br />
其用到的地方有:
forwardQservlet中的request.getRequestDispatcher(address);q个address是在服务器端解析的,所以,你要forward到a.jsp应该q么写:request.getRequestDispatcher(“/user/a.jsp”)q个/ 相对于当前的web应用webappQ其l对地址是Qhttp://192.168.0.1/webapp/user/a.jsp?sendRedirectQ在jsp?lt;%response.sendRedirect("/rtccp/user/a.jsp");%>

2.22、客L的地址

所有的html面中的相对地址都是相对于服务器根目?http://192.168.0.1/)的,而不?跟目录下的该Web应用的目? http://192.168.0.1/webapp/的?Html中的form表单的action属性的地址应该是相对于服务器根目录(http://192.168.0.1/)的,所以,如果提交到a.jsp 为:actionQ?/webapp/user/a.jsp"或action="<%=request.getContextPath()% >"/user/a.jspQ?br /> 提交到servlet为actiomQ?/webapp/handleservlet" Javascript也是在客L解析的,所以其相对路径和form表单一栗?br />

因此Q一般情况下Q在JSP/HTML面{引用的CSS,Javascript.Action{属性前面最好都加上
<%=request.getContextPath()%>,以确保所引用的文仉属于Web应用中的目录。另外,应该量避免使用cM".","./","../../"{类似的相对该文件位|的相对路径Q这样当文gUdӞ很容易出问题?br />

3. JSP/Servlet中获得当前应用的相对路径和绝对\?br />
3.1 JSP中获得当前应用的相对路径和绝对\?br /> 根目录所对应的绝对\?request.getRequestURI()
文g的绝对\? :application.getRealPath(request.getRequestURI());
当前web应用的绝对\?:application.getRealPath("/");
取得h文g的上层目?new File(application.getRealPath(request.getRequestURI())).getParent()

3.2 Servlet中获得当前应用的相对路径和绝对\?br /> 根目录所对应的绝对\?request.getServletPath();
文g的绝对\?:request.getSession().getServletContext().getRealPath
(request.getRequestURI())
当前web应用的绝对\?:servletConfig.getServletContext().getRealPath("/");
(ServletContext对象获得几种方式Q?br /> javax.servlet.http.HttpSession.getServletContext()
javax.servlet.jsp.PageContext.getServletContext()
javax.servlet.ServletConfig.getServletContext()
)

4.java 的Class中获得相对\径,l对路径的方?br />
4.1单独的JavacM获得l对路径
Ҏ(gu)java.io.File的Doc文挡Q可?
默认情况下new File("/")代表的目录ؓQSystem.getProperty("user.dir")?br /> 一下程序获得执行类的当前\?/span>
 
  1. package org.cheng.file;  
  2.   
  3. import java.io.File;  
  4.   
  5. public class FileTest {  
  6.     public static void main(String[] args) throws Exception {  
  7.         System.out.println(Thread.currentThread().getContextClassLoader().getResource(""));  
  8.   
  9.         System.out.println(FileTest.class.getClassLoader().getResource(""));  
  10.   
  11.         System.out.println(ClassLoader.getSystemResource(""));  
  12.         System.out.println(FileTest.class.getResource(""));  
  13.         System.out.println(FileTest.class.getResource("/"));
  14.         //Class文g所在\?/span>
  15.         System.out.println(new File("/").getAbsolutePath());  
  16.         System.out.println(System.getProperty("user.dir"));  
  17.     }  


4.2服务器中的Javac获得当前\径(来自|络Q?strong>

(1).Weblogic

WebApplication的系l文件根目录是你的weblogic安装所在根目录?br /> 例如Q如果你的weblogic安装在c:eaweblogic700.....
那么Q你的文件根路径是c:.
所以,有两U方式能够让你访问你的服务器端的文gQ?br /> a.使用l对路径Q?br /> 比如你的参数文件放在c:yourconfigyourconf.propertiesQ?br /> 直接使用 new FileInputStream("yourconfig/yourconf.properties");
b.使用相对路径Q?br /> 相对路径的根目录是你的webapplication的根路径Q即WEB-INF的上一U目录,你的参数文件放

在yourwebappyourconfigyourconf.propertiesQ?br /> q样使用Q?br /> new FileInputStream("./yourconfig/yourconf.properties");
q两U方式均可,自己选择?br />
(2).Tomcat

在类中输出System.getProperty("user.dir");昄的是%Tomcat_Home%/bin

(3).Resin

不是你的JSP攄相对路径,是JSP引擎执行q个JSP~译成SERVLET
的\径ؓ?比如用新建文件法试File f = new File("a.htm");
q个a.htm在resin的安装目录下

(4).如何ȝ对\径哪Q?br />
在Java文g中getResource或getResourceAsStream均可

例:getClass().getResourceAsStream(filePath);//filePath可以?/filename",q里?代表web

发布根\径下WEB-INF/classes

默认使用该方法的路径是:WEB-INF/classes。已l在Tomcat中测试?br />
5.d文g时的相对路径Q避免硬~码和绝对\径的使用。(来自|络Q?br /> 5.1 采用Spring的DI机制获得文gQ避免硬~码?br /> 参考下面的q接内容Q?br /> http://www.javajia.net/viewtopic.php?p=90213&
5.2 配置文g的读?br /> 参考下面的q接内容Q?br /> http://dev.csdn.net/develop/article/39/39681.shtm

5.3 通过虚拟路径或相对\径读取一个xml文gQ避免硬~码

参考下面的q接内容Q?br /> http://club.gamvan.com/club/clubPage.jsp?iPage=1&tID=10708&ccID=8

6.Java中文件的常用操作Q复ӞUdQ删除,创徏{)Q来自网l)
常用 java File 操作c?br /> http://www.easydone.cn/014/200604022353065155.htm

Java文g操作大全QJSP中)
http://www.pconline.com.cn/pcedu/empolder/gj/java/0502/559401.html

java文g操作详解QJava中文|)
http://www.51cto.com/html/2005/1108/10947.htm

JAVA 如何创徏删除修改复制目录及文?br /> http://www.gamvan.com/developer/java/2005/2/264.html

ȝQ?br /> 通过上面内容的用,可以解决在Web应用服务器端Q移动文Ӟ查找文gQ复?br /> 删除文g{操作,同时Ҏ(gu)务器的相对地址Q绝对地址概念更加清晰?br /> 参考URI,的RFC标准文挡。同时对Java.io.File. Java.net.URI.{内容了解透彻
对其他方面的理解可以更加深入和透彻?/span>

hummer 2008-07-30 15:17 发表评论
]]>
Java路径的最l解x??http://www.tkk7.com/hummer008/articles/218725.htmlhummerhummerWed, 30 Jul 2008 06:41:00 GMThttp://www.tkk7.com/hummer008/articles/218725.htmlhttp://www.tkk7.com/hummer008/comments/218725.htmlhttp://www.tkk7.com/hummer008/articles/218725.html#Feedback0http://www.tkk7.com/hummer008/comments/commentRss/218725.htmlhttp://www.tkk7.com/hummer008/services/trackbacks/218725.html
ava路径的最l解x案:相对路径d(1)

  Java中用的路径Q分ZU:l对路径和相对\径。具体而言Q又分ؓ四种Q?/p>

  一、URI形式的绝对资源\?/p>

  如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/aaa.b

  URL是URI的特例。URL的前~/协议Q必LJava认识的。URL可以打开资源Q而URI则不行?/p>

  URL和URI对象可以互相转换Q用各自的toURI(),toURL()Ҏ(gu)卛_Q?/p>

  二、本地系l的l对路径

  D:/java/eclipse32/workspace/jbpmtest3/bin/aaa.b

  Java.io包中的类Q需要用这UŞ式的参数?/p>

  但是Q它们一般也提供了URIcd的参敎ͼ而URIcd的参敎ͼ接受的是URI样式的String。因此,通过URI转换Q还是可以把URI样式的绝对\径用在java.io包中的类中?/p>

  三、相对于classpath的相对\?/p>

  如:相对?/p>

  file:/D:/java/eclipse32/workspace/jbpmtest3/bin/q个路径的相对\径。其中,bin是本目的classpath。所有的Java源文件编译后?class文g复制到这个目录中?/p>

  四、相对于当前用户目录的相对\?/p>

  是相对于System.getProperty("user.dir")q回的\径?/p>

  对于一般项目,q是目的根路径。对于JavaEE服务器,q可能是服务器的某个路径。这个ƈ没有l一的规范!

  所以,l对不要使用“相对于当前用L录的相对路径”。然而:

  默认情况下,java.io 包中的类LҎ(gu)当前用户目录来分析相对\径名。此目录ql属?user.dir 指定Q通常?Java 虚拟机的调用目录?/p>

  q就是说Q在使用java.io包中的类Ӟ最好不要用相对\径。否则,虽然在J2SE应用E序中可能还正常,但是CJ2EEE序中,一定会出问题!而且q个路径Q在不同的服务器中都是不同的Q?/p>
Java路径的最l解x案:相对路径d(2)

  相对路径最佛_?/p>

  推荐使用相对于当前classpath的相对\?/p>

  因此Q我们在使用相对路径Ӟ应当使用相对于当前classpath的相对\径?/p>

  ClassLoadercȝgetResource(String name),getResourceAsStream(String name){方法,使用相对于当前项目的classpath的相对\径来查找资源?/p>

  d属性文件常用到的ResourceBundlecȝgetBundle(String path)也是如此?/p>

  通过查看ClassLoadercd其相关类的源代码Q我发现Q它实际上还是用了URI形式的绝对\径。通过得到当前classpath的URI形式的绝对\径,构徏了相对\径的URI形式的绝对\径。(q个实际上是猜想Q因为JDK内部调用了SUN的源代码Q而这些代码不属于JDKQ不是开源的。)

  相对路径本质上还是绝对\?/p>

  因此Q归根结底,Java本质上只能用绝对\径来L资源。所有的相对路径L资源的方法,都不q是一些便利方法。不q是API在底层帮助我们构Zl对路径Q从而找到资源的Q?/p>

  得到classpath和当前类的绝对\径的一些方?/p>

  下面是一些得到classpath和当前类的绝对\径的一些方法。你可能需要用其中的一些方法来得到你需要的资源的绝对\径?/p>

  1QFileTest.class.getResource("")

  得到的是当前cFileTest.class文g的URI目录。不包括自己Q?/p>

  如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/com/test/

  2QFileTest.class.getResource("/")

  得到的是当前的classpath的绝对URI路径?/p>

  如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/

  3QThread.currentThread().getContextClassLoader().getResource("")

  得到的也是当前ClassPath的绝对URI路径?/p>

Java路径的最l解x案:相对路径d(3)

  如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/

  4QFileTest.class.getClassLoader().getResource("")

  得到的也是当前ClassPath的绝对URI路径?/p>

  如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/

  5QClassLoader.getSystemResource("")

  得到的也是当前ClassPath的绝对URI路径?/p>

  如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/

  推荐使用Thread.currentThread().getContextClassLoader().getResource("")来得到当前的classpath的绝对\径的URI表示法?/p>

  Web应用E序中资源的d

  上文中说q,当前用户目录Q即相对于System.getProperty("user.dir")q回的\径?/p>

  对于JavaEE服务器,q可能是服务器的某个路径Q这个ƈ没有l一的规范!

  而不是我们发布的Web应用E序的根目录Q?/p>

  q样Q在Web应用E序中,我们l对不能使用相对于当前用L录的相对路径?/p>

  在Web应用E序中,我们一般通过ServletContext.getRealPath("/")Ҏ(gu)得到Web应用E序的根目录的绝对\径?/p>

  q样Q我们只需要提供相对于Web应用E序根目录的路径Q就可以构徏出定位资源的l对路径?/p>

  q是我们开发Web应用E序时一般所采取的策略?/p>

  通用的相对\径解军_?/p>

  Java中各U相对\径非常多Q不Ҏ(gu)使用Q非常容易出错。因此,我编写了一个便利方法,帮助更容易的解决相对路径问题?/p>

  Web应用E序中用JavaSEq行的资源寻址问题

  在JavaSEE序中,我们一般用classpath来作为存放资源的目的地。但是,在Web应用E序中,我们一般用classpath外面的WEB-INF及其子目录作源文件的存放地?/p>

Java路径的最l解x案:相对路径d(4)

  在Web应用E序中,我们一般通过ServletContext.getRealPath("/")Ҏ(gu)得到Web应用E序的根目录的绝对\径。这P我们只需要提供相对于Web应用E序根目录的路径Q就可以构徏出定位资源的l对路径?/p>

  Web应用E序Q可以作为Web应用E序q行发布和运行。但是,我们也常怼以JavaSE的方式来q行Web应用E序的某个类的mainҎ(gu)。或者,使用JUnit试。这都需要用JavaSE的方式来q行?/p>

  q样Q我们就无法使用ServletContext.getRealPath("/")Ҏ(gu)得到Web应用E序的根目录的绝对\径?/p>

  而JDK提供的ClassLoaderc,

  它的getResource(String name),getResourceAsStream(String name){方法,使用相对于当前项目的classpath的相对\径来查找资源?/p>

  d属性文件常用到的ResourceBundlecȝgetBundle(String path)也是如此?/p>

  它们都只能用相对\径来dclasspath下的资源Q无法定位到classpath外面的资源?/p>

  Classpath外配|文件读取问?/p>

  如,我们使用试驱动开发的Ҏ(gu)Q开发Spring、Hibernate、iBatis{用配|文件的Web应用E序Q就会遇到问题?/p>

  管Spring自己提供了FileSystemQ也是相对于user,dir目录Q来dWeb配置文g的方法,但是l究不是很方ѝ而且与WebE序中的代码使用方式不一_

  至于HibernateQiBatis更ȝ了!只有把配|文件移到classpath下,否则Ҏ(gu)不可能用测试驱动开发!

  怎么办?

  通用的相对\径解军_?/p>

  面对q个问题Q我军_~写一个助手类ClassLoaderUtilQ提供一个便利方法[public static URL getExtendResource(String relativePath)]。在Web应用E序{一切JavaE序中,需要定位classpath外的资源Ӟ都用这个助手类的便利方法,而不使用 Web应用E序Ҏ(gu)的ServletContext.getRealPath("/")Ҏ(gu)来定位资源?/p>

Java路径的最l解x案:相对路径d(5)

  利用classpath的绝对\径,定位所有资?/p>

  q个便利Ҏ(gu)的实现原理,是“利用classpath的绝对\径,定位所有资?#8221;?/p>

  ClassLoadercȝgetResource("")Ҏ(gu)能够得到当前classpath的绝对\径,q是所有JavaE序都拥有的能力Q具有最大的适应性!

  而目前的JDK提供的ClassLoadercȝgetResource(String 相对路径)Ҏ(gu)Q只能接受一般的相对路径。这P使用ClassLoadercȝgetResource(String 相对路径)Ҏ(gu)只能定位到classpath下的资源?/p>

  如果Q它能够接受“../”q样的参敎ͼ允许我们用相对\径来定位classpath外面的资源,那么我们可以定位位|的资源Q?/p>

  当然Q我无法修改ClassLoadercȝq个Ҏ(gu)Q于是,我编写了一个助手类ClassLoaderUtilc,提供了[public static URL getExtendResource(String relativePath)]q个Ҏ(gu)。它能够接受带有“../”W号的相对\径,实现了自由寻找资源的功能?/p>

  通过相对classpath路径实现自由L资源的助手类的源代码Q?/p> import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
*@author沈东良shendl_s@hotmail.com
*Nov29,2006 10:34:34AM
*用来加蝲c,classpath下的资源文gQ属性文件等?br /> *getExtendResource(StringrelativePath)Ҏ(gu)Q?br /> *可以使用../W号来加载classpath外部的资源?br /> */
publicclass ClassLoaderUtil {
  privatestatic Log log=LogFactory.getLog(ClassLoaderUtil.class);
  /**
   *Thread.currentThread().getContextClassLoader().getResource("")
   */
  
  /**
   *加蝲JavacR?使用全限定类?br />    *@paramclassName
   *@return
   */
  publicstatic Class loadClass(String className) {
    try {
     return getClassLoader().loadClass(className);
    } catch (ClassNotFoundException e) {
     thrownew RuntimeException("class not found '"+className+"'", e);
    }
   }
   /**
    *得到cd载器
    *@return
    */
   publicstatic ClassLoader getClassLoader() {
  
    return ClassLoaderUtil.class.getClassLoader();
   }
   /**
    *提供相对于classpath的资源\径,q回文g的输入流
    *@paramrelativePath必须传递资源的相对路径?br />     *@是相对于classpath的\径?br />     *@如果需要查找classpath外部的资源,需要?./来查?br />     *@return 文g输入?br />    *@throwsIOException
   *@throwsMalformedURLException
    */
   publicstatic InputStream getStream(String relativePath)
throws MalformedURLException, IOException {
     if(!relativePath.contains("../")){
     return getClassLoader().getResourceAsStream(relativePath);
      
     }else{
     return ClassLoaderUtil.getStreamByExtendResource(relativePath);
     }
    
   }
   /**
    *
    *@paramurl
    *@return
    *@throwsIOException
    */
   publicstatic InputStream getStream(URL url) throws IOException{
     if(url!=null){
      
        return url.openStream();
      
      
     }else{
       returnnull;
     }
   }
   /**
    *
    *@paramrelativePath必须传递资源的相对路径。是相对于classpath的\径?br />     *@如果需要查找classpath外部的资源,需要?./来查?br />     *@return
    *@throwsMalformedURLException
    *@throwsIOException
    */
   publicstatic InputStream getStreamByExtendResource(String relativePath)
throws MalformedURLException, IOException{
    return ClassLoaderUtil.getStream(
ClassLoaderUtil.getExtendResource(relativePath));
    
    
   }
  
   /**
    *提供相对于classpath的资源\径,q回属性对象,它是一个散列表
    *@paramresource
    *@return
    */
   publicstatic Properties getProperties(String resource) {
    Properties properties = new Properties();
    try {
    properties.load(getStream(resource));
    } catch (IOException e) {
    thrownew RuntimeException("couldn't load properties file'"+resource+"'",e);
    }
    return properties;
   }
   /**
    *得到本Class所在的ClassLoader的Classpat的绝对\径?br />     *URL形式?br />     *@return
    */
   publicstatic String getAbsolutePathOfClassLoaderClassPath(){
    
    
     ClassLoaderUtil.log.info(
ClassLoaderUtil.getClassLoader().getResource("").toString());
     return ClassLoaderUtil.getClassLoader().getResource("").toString();
    
   }
   /**
    *
    *@paramrelativePath 必须传递资源的相对路径。是相对于classpath的\径?br />     *@如果需要查找classpath外部的资源,需要?./来查?br />     *@return资源的绝对URL
   *@throwsMalformedURLException
    */
   publicstatic URL getExtendResource(String relativePath)
throws MalformedURLException{
  
     ClassLoaderUtil.log.info("传入的相对\径:"+relativePath) ;
     //ClassLoaderUtil.log.info(Integer.valueOf(relativePath.indexOf("../"))) ;
     if(!relativePath.contains("../")){
       return ClassLoaderUtil.getResource(relativePath);
      
     }
     String classPathAbsolutePath=ClassLoaderUtil.getAbsolutePathOfClassLoaderClassPath();
     if(relativePath.substring(0, 1).equals("/")){
       relativePath=relativePath.substring(1);
     }
     ClassLoaderUtil.log.info(Integer.valueOf(relativePath.lastIndexOf("../"))) ;
    
     String wildcardString=relativePath.substring(
0,relativePath.lastIndexOf("../")+3);
    relativePath=relativePath.substring(relativePath.lastIndexOf("../")+3);
     int containSum=ClassLoaderUtil.containSum(wildcardString, "../");
     classPathAbsolutePath= ClassLoaderUtil.cutLastString(
classPathAbsolutePath, "/", containSum);
     String resourceAbsolutePath=classPathAbsolutePath+relativePath;
     ClassLoaderUtil.log.info("l对路径Q?+resourceAbsolutePath) ;
     URL resourceAbsoluteURL=new URL(resourceAbsolutePath);
     return resourceAbsoluteURL;
   }
   /**
   *
    *@paramsource
    *@paramdest
    *@return
    */
   privatestaticint containSum(String source,String dest){
     int containSum=0;
     int destLength=dest.length();
     while(source.contains(dest)){
       containSum=containSum+1;
       source=source.substring(destLength);
      
     }
    
    
     return containSum;
   }
   /**
    *
    *@paramsource
    *@paramdest
    *@paramnum
    *@return
    */
   privatestatic String cutLastString(String source,String dest,int num){
     // String cutSource=null;
     for(int i=0;i<num;i++){
       source=source.substring(0, source.lastIndexOf(dest, source.length()-2)+1);
      
      
     }
        
     return source;
   }
   /**
    *
    *@paramresource
    *@return
    */
   publicstatic URL getResource(String resource){
   ClassLoaderUtil.log.info("传入的相对于classpath的\径:"+resource) ;
     return ClassLoaderUtil.getClassLoader().getResource(resource);
   }
   
  /**
   *@paramargs
   *@throwsMalformedURLException
   */
  publicstaticvoid main(String[] args)
throws MalformedURLException {
    
      //ClassLoaderUtil.getExtendResource("../spring/dao.xml");
    //ClassLoaderUtil.getExtendResource("../../../src/log4j.properties");
    ClassLoaderUtil.getExtendResource("log4j.properties");
    
    System.out.println(
ClassLoaderUtil.getClassLoader().getResource("log4j.properties").toString());
  }
}

 

 

  后记

  ClassLoaderUtilcȝpublic static URL getExtendResource(String relativePath)Q虽然很单,但是实可以解决大问题?/p>

  不过q个Ҏ(gu)q是比较陋的。我q想在未来有I时Q进一步增强它的能力。比如,增加Ant风格的匹配符。用**代表多个目录Q?代表多个字符Q?代表一个字W。达到Spring那样的能力,一ơ返回多个资源的URLQ进一步方便大家开发?/p>

  ȝQ?/p>

  1.量不要使用相对于System.getProperty("user.dir")当前用户目录的相对\径。这是一颗定时炸弹,随时可能要你的命?/p>

  2.量使用URI形式的绝对\径资源。它可以很容易的转变为URI,URLQFile对象?/p>

  3.量使用相对classpath的相对\径。不要用绝对\径。用上面ClassLoaderUtilcȝpublic static URL getExtendResource(String relativePath)Ҏ(gu)已经能够使用相对于classpath的相对\径定位所有位|的资源?/p>

  4.l对不要使用编码的l对路径。因为,我们完全可以使用ClassLoadercȝgetResource("")Ҏ(gu)得到当前classpath的绝对\径?/p>

  使用编码的l对路径是完全没有必要的Q它一定会让你ȝ很难看!E序无法移植!

  如果你一定要指定一个绝对\径,那么使用配置文gQ也比硬~码要好得多Q?/p>

  当然Q我q是推荐你用程序得到classpath的绝对\径来D源的l对路径Q?/p>



hummer 2008-07-30 14:41 发表评论
]]>
滚动条位|设|?/title><link>http://www.tkk7.com/hummer008/articles/216777.html</link><dc:creator>hummer</dc:creator><author>hummer</author><pubDate>Wed, 23 Jul 2008 01:29:00 GMT</pubDate><guid>http://www.tkk7.com/hummer008/articles/216777.html</guid><wfw:comment>http://www.tkk7.com/hummer008/comments/216777.html</wfw:comment><comments>http://www.tkk7.com/hummer008/articles/216777.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/hummer008/comments/commentRss/216777.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/hummer008/services/trackbacks/216777.html</trackback:ping><description><![CDATA[1.讄H口滚动条的位置Q?br /> window.scroll(0,document.body.scrollHeight)<br /> <br /> 例,在打开|页时让面处于面底端<br /> <body   onload="window.scroll(0,document.body.scrollHeight)"><br /> <br /> 2.讄lg的滚动条的位|:<br /> <br /> 假设有个输入框,id为TextArea1<br /> Ҏ(gu)一Q?br /> TextArea1.scrollTop=100;//滚动到输入框?00位置<br />  Ҏ(gu)二:<br /> document.getElementById("TextArea1").scrollTop=document.getElementById("TextArea1").scrollHeight; //滚动到输入框的底?br /> <br /> 支持 IE ?FF<br /> onmouseover="this.style.cursor='pointer'" <img src ="http://www.tkk7.com/hummer008/aggbug/216777.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/hummer008/" target="_blank">hummer</a> 2008-07-23 09:29 <a href="http://www.tkk7.com/hummer008/articles/216777.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>js 实用ȝhttp://www.tkk7.com/hummer008/articles/214231.htmlhummerhummerFri, 11 Jul 2008 05:03:00 GMThttp://www.tkk7.com/hummer008/articles/214231.htmlhttp://www.tkk7.com/hummer008/comments/214231.htmlhttp://www.tkk7.com/hummer008/articles/214231.html#Feedback0http://www.tkk7.com/hummer008/comments/commentRss/214231.htmlhttp://www.tkk7.com/hummer008/services/trackbacks/214231.html
function appendImageDIV(){
    if ((etIE || etDOM)) {
        var obody = document.getElementsByTagName('BODY').item(0);       
        var imageDIV = document.createElement("DIV");
        imageDIV.id = WEBTOUCH_IMAGE_DIV_ID;
        imageDIV.style.display = "none";
        imageDIV.style.position = "absolute";
        imageDIV.style.zIndex = 999999999;
        obody.appendChild(imageDIV);       
        var content = '<img src="'+DYNAMIC_AGENT_CHAT_URL+CHAT_OFF_IMAGE+'"  id="'+TAG_FOR_IMAGE+'" />';
        imageDIV.innerHTML = content;
    }
}

2.DIV 屏幕位置不变

<div id="Float21789" style="position: absolute; z-index: 9; width: 190px; top: 200px;
        right: 3px;">
        <center>
            <div id="AD21789" style="width: 190px; height: 90px; text-align: center; float: none;">
                <a target="_blank">
                    <img src="http://community.csdn.net/ui/homepage/images/questions.gif" alt="提问" style="width: 180px;
                        height: 50px; padding-right: 3px;" /></a>
            </div>
        </center>
    </div>

    <script type="text/javascript" language="JavaScript">
    var csdnScrollTop=function(){
        return document.documentElement.scrollTop?document.documentElement.scrollTop:document.body.scrollTop;
        };
        function mymove21789(){
        document.getElementById("Float21789").style.top=csdnScrollTop()+300+'px';document.getElementById("Float21789").style.right=3+'px';setTimeout("mymove21789();",50);
        }
        mymove21789();
    </script>

3.Z件添加方?br />
if (window.addEventListener) {
    window.addEventListener('scroll', playImgFloatPosition, false);
    window.addEventListener('resize', playImgFloatPosition, false);
}
 if (window.attachEvent) {
      window.attachEvent('onscroll', playImgFloatPosition);
      window.attachEvent('onresize', playImgFloatPosition);
}


hummer 2008-07-11 13:03 发表评论
]]>
js~码处理(?http://www.tkk7.com/hummer008/articles/213910.htmlhummerhummerThu, 10 Jul 2008 03:44:00 GMThttp://www.tkk7.com/hummer008/articles/213910.htmlhttp://www.tkk7.com/hummer008/comments/213910.htmlhttp://www.tkk7.com/hummer008/articles/213910.html#Feedback3http://www.tkk7.com/hummer008/comments/commentRss/213910.htmlhttp://www.tkk7.com/hummer008/services/trackbacks/213910.html阅读全文

hummer 2008-07-10 11:44 发表评论
]]>
webwork资源讉K方式http://www.tkk7.com/hummer008/articles/211865.htmlhummerhummerTue, 01 Jul 2008 05:12:00 GMThttp://www.tkk7.com/hummer008/articles/211865.htmlhttp://www.tkk7.com/hummer008/comments/211865.htmlhttp://www.tkk7.com/hummer008/articles/211865.html#Feedback0http://www.tkk7.com/hummer008/comments/commentRss/211865.htmlhttp://www.tkk7.com/hummer008/services/trackbacks/211865.htmlwebwork的JSP Tag提供了访问资源的方式Q例如:

<ww:text name="title"/>

对于资源文g中包含参敎ͼ可以嵌套参数TagQ?/p>

<ww:text name="title"> <ww:param>Webwork</ww:param> <ww:param>JSP Tag</ww:param></ww:text>

׃webwork的view讉K资源的方式,实际上是通过调用ognlStack堆栈栈顶的action对象的getText(...)Ҏ(gu)实现的,所以我们可以直接运用这U方式,例如Q?/p>

<ww:textfield label="%{getText('title')}" name="username"/>

׃JSP Tag不能嵌套Q因此当遇到上面q种情况Q需要在Tag里面讉K资源的时候,我们必采用这U直接通过ognlStack讉Kaction的方?/p>

当我们用FreeMakrer作ؓview的时候,两种方式都可以采?br /> 采用Tag方式Q?/p>

<@ww.text name="title"/>
<@ww.text name="title"> <@ww.param>webwork</@ww.param> <@ww.param>jsp tag</@ww.param></@ww.text>

采用ognlStack方式Q?/p>

${action.getText("title")}

Ҏ(gu)两种方式Q?/p>

<@ww.textfield label="%{getText('title')}" name="username" /><@ww.textfield label="${action.getText('title')}" name="username" />
 


hummer 2008-07-01 13:12 发表评论
]]>
maven2使用(一)http://www.tkk7.com/hummer008/articles/210371.htmlhummerhummerTue, 24 Jun 2008 11:26:00 GMThttp://www.tkk7.com/hummer008/articles/210371.htmlhttp://www.tkk7.com/hummer008/comments/210371.htmlhttp://www.tkk7.com/hummer008/articles/210371.html#Feedback0http://www.tkk7.com/hummer008/comments/commentRss/210371.htmlhttp://www.tkk7.com/hummer008/services/trackbacks/210371.html1.maven2使用(一)

(1) 下蝲开源项?POM.XML) d:\untils
(2) q入 d:\untils 然后 mvn eclipse:eclipse
(3) 导入工程 (建立包依赖关p?
(4) 如果部分插g下蝲不了,可以直接靠到相应目录(m2仓库),POM.XMLd相应的插仉?br /> (5)dCLASSPATH 变量



hummer 2008-06-24 19:26 发表评论
]]>
代理机制学习http://www.tkk7.com/hummer008/articles/209059.htmlhummerhummerThu, 19 Jun 2008 01:06:00 GMThttp://www.tkk7.com/hummer008/articles/209059.htmlhttp://www.tkk7.com/hummer008/comments/209059.htmlhttp://www.tkk7.com/hummer008/articles/209059.html#Feedback0http://www.tkk7.com/hummer008/comments/commentRss/209059.htmlhttp://www.tkk7.com/hummer008/services/trackbacks/209059.html 代理机制



hummer 2008-06-19 09:06 发表评论
]]>
JAVA代理机制http://www.tkk7.com/hummer008/articles/208855.htmlhummerhummerWed, 18 Jun 2008 06:02:00 GMThttp://www.tkk7.com/hummer008/articles/208855.htmlhttp://www.tkk7.com/hummer008/comments/208855.htmlhttp://www.tkk7.com/hummer008/articles/208855.html#Feedback0http://www.tkk7.com/hummer008/comments/commentRss/208855.htmlhttp://www.tkk7.com/hummer008/services/trackbacks/208855.html l 静态代理类Q由E序员创建或q定工兯动生?br /> 源代码,再对其编译。在E序q行前,代理cȝ.class文g已l存在了?br /> l 动态代理类Q在E序q行Ӟq用反射机制动态创成?

可以看出静?span class="hilite1">代理cL一个很不爽的缺点:当如果接口加一个方法(把上面所有的代码的注释给LQ,所有的实现cd代理c里都需要做个实现。这增加了代码的复杂度。动?span class="hilite1">代理可以避免这个缺炏V?/p>

3 。动?span class="hilite1">代理

动?span class="hilite1">代理与普通的代理相比较,最大的好处是接口中声明的所有方法都被{Ud一个集中的Ҏ(gu)中处理(invokeQ,q样Q在接口Ҏ(gu)数量比较多的时候,我们可以q行灉|处理Q而不需要像静?span class="hilite1">代理那样每一个方法进行中转?/font>

动?span class="hilite1">代理c?font color="#ff0000">只能代理接口Q?span class="hilite1">代理c都需要实现InvocationHandlerc,实现invokeҎ(gu)。该invokeҎ(gu)是调用?span class="hilite1">代理接口的所有方法时需要调用的Q该invokeҎ(gu)q回的值是?span class="hilite1">代理接口的一个实现类

代码实例:
  1. package ttitfly.proxy;       
  2.       
  3. import java.lang.reflect.InvocationHandler;       
  4. import java.lang.reflect.Method;       
  5. import java.lang.reflect.Proxy;       
  6. //动?span class="hilite1">代理cd?span class="hilite1">代理接口Q?span class="hilite1">代理c都需要实现InvocationHandlerc,实现invokeҎ(gu)。该invokeҎ(gu)是调用?span class="hilite1">代理接口的所有方法时需要调用的Q该invokeҎ(gu)q回的值是?span class="hilite1">代理接口的一个实现类       
  7. public class DynamicProxy implements InvocationHandler{       
  8.            
  9.     private Object object;        
  10.     //l定关系Q也是兌到哪个接口(与具体的实现cȝ定)的哪些方法将被调用时Q执行invokeҎ(gu)?  
  11.     //Proxy.newProxyInstance的第三个参数是表明这些被拦截的方法执行时需要执行哪个InvocationHandler的invokeҎ(gu)   
  12.     public Object bindRelation(Object object){        
  13.         this.object = object;       
  14.         return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(),this);        
  15.     }        
  16.     //拦截兌的这个实现类的方法被调用时将被执?nbsp;      
  17.     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        
  18.         System.out.println("Welcome");       
  19.         Object result = method.invoke(object, args);        
  20.         return result;       
  21.     }       
  22.       
  23. }       


 

试c:

java 代码
  1. package ttitfly.proxy;       
  2.       
  3. public class TestDynamicProxy {       
  4.     public static void main(String[] args){       
  5.         HelloWorld helloWorld = new HelloWorldImpl();       
  6.         DynamicProxy dp = new DynamicProxy();       
  7.         //在这里绑定的是HelloWorld,也就是HelloWorld是被代理接口。所以绑定关pLQ需要传递一个HelloWorld的实现类的实例化对象?nbsp;      
  8.         HelloWorld helloWorld1 = (HelloWorld)dp.bindRelation(helloWorld);        
  9.         helloWorld1.print();        
  10.         helloWorld1.say();       
  11.            
  12.         //helloWorld2不被拦?  
  13.         HelloWorld helloWorld2 = new HelloWorldImpl();   
  14.         helloWorld2.print();        
  15.         helloWorld2.say();   
  16.            
  17.     }       
  18. }       


hummer 2008-06-18 14:02 发表评论
]]>
java annotation高应用http://www.tkk7.com/hummer008/articles/207702.htmlhummerhummerFri, 13 Jun 2008 08:17:00 GMThttp://www.tkk7.com/hummer008/articles/207702.htmlhttp://www.tkk7.com/hummer008/comments/207702.htmlhttp://www.tkk7.com/hummer008/articles/207702.html#Feedback0http://www.tkk7.com/hummer008/comments/commentRss/207702.htmlhttp://www.tkk7.com/hummer008/services/trackbacks/207702.html阅读全文

hummer 2008-06-13 16:17 发表评论
]]>
Java Annotation入门(?http://www.tkk7.com/hummer008/articles/207699.htmlhummerhummerFri, 13 Jun 2008 08:07:00 GMThttp://www.tkk7.com/hummer008/articles/207699.htmlhttp://www.tkk7.com/hummer008/comments/207699.htmlhttp://www.tkk7.com/hummer008/articles/207699.html#Feedback0http://www.tkk7.com/hummer008/comments/commentRss/207699.htmlhttp://www.tkk7.com/hummer008/services/trackbacks/207699.html 关键?Java,annotation,标注


摘要Q?/span>
本文针对java初学者或者annotation初次使用者全面地说明了annotation的用方法、定义方式、分cR初学者可以通过以上的说明制作简单的annotationE序Q但是对于一些高U的annotation应用Q例如用自定义annotation生成javabean映射xml文gQ还需要进一步的研究和探讨。涉及到深入annotation的内容,作者将在后文《Java Annotation高应用》中谈到?br />
同时Qannotationq行存在两种方式Q运行时、编译时。上文中讨论的都是在q行时的annotation应用Q但在编译时的annotation应用q没有涉及,

一、ؓ什么用AnnotationQ?/span>

在JAVA应用中,我们帔RC些需要用模版代码。例如,Z~写一个JAX-RPC web serviceQ我们必L供一Ҏ(gu)口和实现作ؓ模版代码。如果用annotation对远E访问的Ҏ(gu)代码q行修饰的话Q这个模版就能够使用工具自动生成?br /> 另外Q一些API需要用与E序代码同时l护的附属文件。例如,JavaBeans需要一个BeanInfo Class与一个Bean同时使用/l护Q而EJB则同样需要一个部|描q符。此时在E序中用annotation来维护这些附属文件的信息十分便利而且减少了错误?br />
二、Annotation工作方式Q?/span>

?.0 版之前的Javaq_已经h了一些ad hoc annotation机制。比如,使用transient修饰W来标识一个成员变量在序列化子pȝ中应被忽略。而@deprecatedq个 javadoc tag也是一个ad hoc annotation用来说明一个方法已q时。从Java5.0版发布以来,5.0q_提供了一个正式的annotation功能Q允许开发者定义、用自qannoatationcd。此功能׃个定义annotationcd的语法和一个描qannotation声明的语法,dannotaion 的APIQ一个用annotation修饰的class文gQ一个annotation处理工具QaptQ组成?br /> annotationq不直接影响代码语义Q但是它能够工作的方式被看作cME序的工h者类库,它会反过来对正在q行的程序语义有所影响。annotation可以从源文g、class文g或者以在运行时反射的多U方式被d?br /> 当然annotation在某U程度上使javadoc tag更加完整。一般情况下Q如果这个标记对java文档产生影响或者用于生成java文档的话Q它应该作ؓ一个javadoc tagQ否则将作ؓ一个annotation?br />
三、Annotation使用Ҏ(gu)Q?/span>

1。类型声明方式:
通常Q应用程序ƈ不是必须定义annotationcdQ但是定义annotationcdq难事。Annotationcd声明于一般的接口声明极ؓcMQ区别只在于它在interface关键字前面?#8220;@”W号?br /> annotation cd的每个方法声明定义了一个annotationcd成员Q但Ҏ(gu)声明不必有参数或者异常声明;Ҏ(gu)q回值的cd被限制在以下的范_ primitives、String、Class、enums、annotation和前面类型的数组Q方法可以有默认倹{?br />
下面是一个简单的annotationcd声明Q?br /> 清单1:

    /**
     * Describes the Request-For-Enhancement(RFE) that led
     * to the presence of the annotated API element.
     */
    public @interface RequestForEnhancement {
        int    id();
        String synopsis();
        String engineer() default "[unassigned]";
        String date();    default "[unimplemented]";
    }

代码中只定义了一个annotationcdRequestForEnhancement?br />
2。修饰方法的annotation声明方式Q?/strong>
annotation 是一U修饰符Q能够如其它修饰W(如public、static、finalQ一般用。习惯用法是annotaions用在其它的修饰符前面?annotations?#8220;@+annotationcd+带有括号的成?值列?#8221;l成。这些成员的值必L~译时常量(卛_q行时不变)?br />
AQ下面是一个用了RequestForEnhancement annotation的方法声明:
清单2:

    @RequestForEnhancement(
        id       = 2868724,
        synopsis = "Enable time-travel",
        engineer = "Mr. Peabody",
        date     = "4/1/3007"
    )
    public static void travelThroughTime(Date destination) { ... }


BQ当声明一个没有成员的annotationcd声明Ӟ可用以下方式:
清单3:

    /**
     * Indicates that the specification of the annotated API element
     * is preliminary and subject to change.
     */
    public @interface Preliminary { }


作ؓ上面没有成员的annotationcd声明的简写方式:
清单4:

    @Preliminary public class TimeTravel { ... }


CQ如果在annotations中只有唯一一个成员,则该成员应命名ؓvalueQ?br /> 清单5:

    /**
     * Associates a copyright notice with the annotated API element.
     */
    public @interface Copyright {
        String value();
    }


更ؓ方便的是对于h唯一成员且成员名为value的annotationQ如上文Q,在其使用时可以忽略掉成员名和赋值号Q?Q:
清单6:

    @Copyright("2002 Yoyodyne Propulsion Systems")
    public class OscillationOverthruster { ... }


3。一个用实例:
l合上面所讲的Q我们在q里建立一个简单的Zannotation试框架。首先我们需要一个annotationcd来表C某个方法是一个应该被试工具q行的测试方法?br /> 清单7:

    import java.lang.annotation.*;

    /**
     * Indicates that the annotated method is a test method.
     * This annotation should be used only on parameterless static methods.
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface Test { }


值得注意的是annotaioncd声明是可以标注自qQ这Lannotation被称?#8220;meta-annotations”?br />
在上面的代码中,@Retention(RetentionPolicy.RUNTIME)q个meta-annotation表示了此cd?annotation被虚拟Z留其能够在q行旉过反射被读取。而@Target(ElementType.METHOD)表示此类型的 annotation只能用于修饰Ҏ(gu)声明?br />
下面是一个简单的E序Q其中部分方法被上面的annotation所标注Q?br /> 清单8:

    public class Foo {
        @Test public static void m1() { }
        public static void m2() { }
        @Test public static void m3() {
            throw new RuntimeException("Boom");
        }
        public static void m4() { }
        @Test public static void m5() { }
        public static void m6() { }
        @Test public static void m7() {
            throw new RuntimeException("Crash");
        }
        public static void m8() { }
    }

Here is the testing tool:

    import java.lang.reflect.*;

    public class RunTests {
       public static void main(String[] args) throws Exception {
          int passed = 0, failed = 0;
          for (Method m : Class.forName(args[0]).getMethods()) {
             if (m.isAnnotationPresent(Test.class)) {
                try {
                   m.invoke(null);
                   passed++;
                } catch (Throwable ex) {
                   System.out.printf("Test %s failed: %s %n", m, ex.getCause());
                   failed++;
                }
             }
          }
          System.out.printf("Passed: %d, Failed %d%n", passed, failed);
       }
    }


q个E序从命令行参数中取出类名,q且遍历此类的所有方法,试调用其中被上面的试annotationcd标注q的Ҏ(gu)。在此过E中Z扑և哪些Ҏ(gu)?annotationcd标注q,需要用反的方式执行此查询。如果在调用Ҏ(gu)时抛出异常,此方法被认ؓ已经p|Qƈ打印一个失败报告。最后,打印q行通过/p|的方法数量?br /> 下面文字表示了如何运行这个基于annotation的测试工P

清单9:

    $ java RunTests Foo
    Test public static void Foo.m3() failed: java.lang.RuntimeException: Boom
    Test public static void Foo.m7() failed: java.lang.RuntimeException: Crash
    Passed: 2, Failed 2


四、Annotation分类Q?/span>

Ҏ(gu)annotation的用方法和用途主要分Z下几c:

1。内建Annotation——Java5.0版在java语法中经常用到的内徏AnnotationQ?/strong>
@Deprecated用于修饰已经q时的方法;
@Override用于修饰此方法覆盖了父类的方法(而非重蝲Q;
@SuppressWarnings用于通知java~译器禁止特定的~译警告?br />
下面代码展示了内建Annotationcd的用法:
清单10:

package com.bjinfotech.practice.annotation;

/**
* 演示如何使用java5内徏的annotation
* 参考资料:
* http://java.sun.com/docs/books/tutorial/java/javaOO/annotations.html
* http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html
* http://mindprod.com/jgloss/annotations.html
* @author cleverpig
*
*/
import java.util.List;

public class UsingBuiltInAnnotation {
        //食物c?br />         class Food{}
        //q草c?br />         class Hay extends Food{}
        //动物c?br />         class Animal{
                Food getFood(){
                        return null;
                }
                //使用Annotation声明DeprecatedҎ(gu)
                @Deprecated
                void deprecatedMethod(){
                }
        }
        //马类-l承动物c?br />         class Horse extends Animal{
                //使用Annotation声明覆盖Ҏ(gu)
                @Override
                Hay getFood(){
                        return new Hay();
                }
                //使用Annotation声明止警告
                @SuppressWarnings({"deprecation","unchecked"})
                void callDeprecatedMethod(List horseGroup){
                        Animal an=new Animal();
                        an.deprecatedMethod();
                        horseGroup.add(an);
                }
        }
}


2。开发者自定义AnnotationQ由开发者自定义Annotationcd?/strong>
下面是一个用annotationq行Ҏ(gu)试的sampleQ?br />
AnnotationDefineForTestFunctioncd定义如下Q?br /> 清单11:

package com.bjinfotech.practice.annotation;

import java.lang.annotation.*;
/**
* 定义annotation
* @author cleverpig
*
*/
//加蝲在VM中,在运行时q行映射
@Retention(RetentionPolicy.RUNTIME)
//限定此annotation只能标示Ҏ(gu)
@Target(ElementType.METHOD)
public @interface AnnotationDefineForTestFunction{}


试annotation的代码如下:

清单12:

package com.bjinfotech.practice.annotation;

import java.lang.reflect.*;

/**
* 一个实例程序应用前面定义的AnnotationQAnnotationDefineForTestFunction
* @author cleverpig
*
*/
public class UsingAnnotation {
        @AnnotationDefineForTestFunction public static void method01(){}
        
        public static void method02(){}
        
        @AnnotationDefineForTestFunction public static void method03(){
                throw new RuntimeException("method03");
        }
        
        public static void method04(){
                throw new RuntimeException("method04");
        }
        
        public static void main(String[] argv) throws Exception{
                int passed = 0, failed = 0;
                //被检的cd
                String className="com.bjinfotech.practice.annotation.UsingAnnotation";
                //逐个查此cȝҎ(gu)Q当其方法用annotation声明时调用此Ҏ(gu)
            for (Method m : Class.forName(className).getMethods()) {
               if (m.isAnnotationPresent(AnnotationDefineForTestFunction.class)) {
                  try {
                     m.invoke(null);
                     passed++;
                  } catch (Throwable ex) {
                     System.out.printf("试 %s p|: %s %n", m, ex.getCause());
                     failed++;
                  }
               }
            }
            System.out.printf("试l果Q?通过: %d, p|Q?%d%n", passed, failed);
        }
}


3。用第三方开发的Annotationcd
q也是开发h员所常常用到的一U方式。比如我们在使用Hibernate3.0时就可以利用Annotation生成数据表映配|文Ӟ而不必用Xdoclet?br />
五、ȝQ?/span>

1。前面的文字说明了annotation的用方法、定义方式、分cR初学者可以通过以上的说明制作简单的annotationE序Q但是对于一些高U的 annotation应用Q例如用自定义annotation生成javabean映射xml文gQ还需要进一步的研究和探讨?br />
2。同Ӟannotationq行存在两种方式Q运行时、编译时。上文中讨论的都是在q行时的annotation应用Q但在编译时的annotation应用q没有涉及,因ؓ~译时的annotation要用annotation processing tool?br />


hummer 2008-06-13 16:07 发表评论
]]>
annotation知识(?http://www.tkk7.com/hummer008/articles/207695.htmlhummerhummerFri, 13 Jun 2008 08:00:00 GMThttp://www.tkk7.com/hummer008/articles/207695.htmlhttp://www.tkk7.com/hummer008/comments/207695.htmlhttp://www.tkk7.com/hummer008/articles/207695.html#Feedback0http://www.tkk7.com/hummer008/comments/commentRss/207695.htmlhttp://www.tkk7.com/hummer008/services/trackbacks/207695.html版权声明Q本文可以自p{载,转蝲时请务必以超链接形式标明文章原始出处和作者信息及本声?/span>
作?cleverpig(作者的Blog:http://blog.matrix.org.cn/page/cleverpig)
原文:http://www.matrix.org.cn/resource/article/44/44055_Java+Annotation+Reflect.html
关键?java,annotation,reflect

前言Q?/span>
在上文?a target="_new">《Java Annotation入门?/a>中概要性的介绍了Annotation的定义、用,范围늛较广Q但是深度不够。所以作者在《Java Annotation入门》后Ql整理了Annotation的概念和知识点,与喜Ƣresearch的朋友们׃n?br />
阅读提示Q文中提到的E序成员或者程序元素是一个概念,指组成程序代码的单元Q如cR方法、成员变量?/span>

一、AnnotationI竟是什么?

Annotation提供了一条与E序元素兌M信息或者Q何元数据QmetadataQ的途径。从某些斚w看,annotation像修饰W一栯使用Qƈ应用于包、类型、构造方法、方法、成员变量、参数、本地变量的声明中。这些信息被存储在annotation?#8220;name=value”l构对中。annotationcd是一U接口,能够通过java反射API的方式提供对其信息的讉K?br />
annotation能被用来为某个程序元素(cR方法、成员变量等Q关联Q何的信息。需要注意的是,q里存在着一个基本的潜规则:annotaion不能影响E序代码的执行,无论增加、删除annotationQ代码都始终如一的执行。另外,管一些annotation通过java的反apiҎ(gu)在运行时被访问,而java语言解释器在工作时忽略了q些annotation。正是由于java虚拟机忽略了annotationQ导致了annotationcd在代码中?#8220;不v作用”的;只有通过某种配套的工h会对annotationcd中的信息q行讉K和处理。本文中涵盖标准的annotation和meta-annotationcdQ陪伴这些annotationcd的工hjava~译器(当然要以某种Ҏ(gu)的方式处理它们)?br />
׃上述原因Qannotation在用时十分ѝ一个本地变量可以被一个以NonNull命名的annotationcd所标注Q来作ؓ对这个本地变量不能被赋予null值的断言。而我们可以编写与之配套的一个annotation代码分析工具Q用它来对h前面变量的代码进行解析,q且试验证q个断言。当然这些代码ƈ不必自己~写。在JDK安装后,在JDK/bin目录中可以找到名?#8220;apt”的工P它提供了处理annotation的框Ӟ它启动后扫描源代码中的annotationQƈ调用我们定义好的annotation处理器完成我们所要完成的工作Q比如验证前面例子中的断aQ。说到这里,annotation的强大功能似乎可以替代XDocletq类的工具了Q随着我们的深入,大家会更加坚信这一炏V?br /> 注:详细描述请参看jsr250规范Q?br /> http://www.jcp.org/aboutJava/communityprocess/pfd/jsr250/

二、Annotation的定义:

q段文字开始介lannotation相关技术。在此大家将看到java5.0的标准annotationcdQ这U标准类型就是前文中所说的“内徏”cdQ它们可以直接被javac支持。可喜的是,在java6.0beta版中的javac已经加入了对自定义annotation的支持?br />
1。Annotation的概念和语法Q?/span>

首先Q关键的概念是理解annotation是与一个程序元素相兌信息或者元数据的标注。它从不影响javaE序的执行,但是对例如编译器警告或者像文档生成器等辅助工具产生影响?br />
下面是常用的annotation列表Q我们应该注意在annotation和annotationcd之间的不同:

A.annotationQ?/span>
annotation使用了在java5.0所带来的新语法Q它的行为十分类似public、finalq样的修饰符。每个annotationh一个名字和成员个数>=0。每个annotation的成员具有被UCؓname=value对的名字和|像javabean一PQname=value装蝲了annotation的信息?br />
B.annotationcdQ?/span>
annotationcd定义了annotation的名字、类型、成员默认倹{一个annotationcd可以说是一个特D的java接口Q它的成员变量是受限制的Q而声明annotationcd旉要用新语法。当我们通过java反射api讉KannotationӞq回值将是一个实C该annotationcd接口的对象,通过讉Kq个对象我们能方便的讉K到其annotation成员。后面的章节提到在java5.0的java.lang包里包含?个标准annotationcd?br />
C.annotation成员Q?/span>
annotation的成员在annotationcd中以无参数的Ҏ(gu)的Ş式被声明。其Ҏ(gu)名和q回值定义了该成员的名字和类型。在此有一个特定的默认语法Q允许声明Q何annotation成员的默认|一个annotation可以name=value对作为没有定义默认值的annotation成员的|当然也可以用name=valueҎ(gu)覆盖其它成员默认倹{这一Ҏ(gu)些近似类的承特性,父类的构造函数可以作为子cȝ默认构造函敎ͼ但是也可以被子类覆盖?br />
D.marker annotationcdQ?/span>
一个没有成员定义的annotationcd被称为marker annotation。这Uannotationcd仅用自w的存在与否来ؓ我们提供信息。如后面要说的Override?br />
E.meta-annotationQ?/span>
meta-annotation也称为元annotationQ它是被用来声明annotationcd的annotation。Java5.0提供了一些标准的?annotationcd。下面介l的target、retention是meta-annotation?br />
F.targetQ?/span>
annotation的target是一个被标注的程序元素。target说明了annotation所修饰的对象范_annotation可被用于packages、typesQ类、接口、枚举、annotationcdQ、类型成员(Ҏ(gu)、构造方法、成员变量、枚丑ր|、方法参数和本地变量Q如循环变量、catch参数Q。在annotationcd的声明中使用了target可更加明晰其修饰的目标?br />
G.retentionQ?/span>
annotation的retention定义了该annotation被保留的旉长短Q某些annotation仅出现在源代码中Q而被~译器丢弃;而另一些却被编译在class文g中;~译在class文g中的annotation可能会被虚拟机忽略,而另一些在class被装载时被dQ请注意q不影响class的执行,因ؓannotation与class在用上是被分离的)。用这个meta-annotation可以对annotation?#8220;生命周期”限制?br />
H.metadataQ?/span>
׃metadata被广泛用于各种计算机开发过E中Q所以当我们在这里谈论的metadata卛_数据通常指被annotation装蝲的信息或者annotation本n?br />
2。用标准AnnotationQ?/span>
java5.0在java.lang包中定义?U标准的annotationcdQ?br />
A.OverrideQ?/span>
java.lang.Override是一个marker annotationcdQ它被用作标注方法。它说明了被标注的方法重载了父类的方法,起到了断a的作用。如果我们用了q种annotation在一个没有覆盖父cL法的Ҏ(gu)Ӟjava~译器将以一个编译错误来警示?br /> q个annotaton常常在我们试图覆盖父cL法而确又写错了Ҏ(gu)名时发挥威力?br />
使用Ҏ(gu)极其单:在用此annotation时只要在被修饰的Ҏ(gu)前面加上@Override?br /> 下面的代码是一个用@Override修饰一个企N载父cȝtoStringҎ(gu)Q而又存在拼写错误的sampleQ?br /> 清单1Q?/strong>

@Override
public String toSting() {   // 注意Ҏ(gu)名拼写错?br />     return "[" + super.toString() + "]";
}


B.DeprecatedQ?/span>
同样Deprecated也是一个marker annotation。当一个类型或者类型成员用@Deprecated修饰的话Q编译器不鼓励使用q个被标注的E序元素。而且q种修饰h一定的“延箋?#8221;Q如果我们在代码中通过l承或者覆盖的方式使用了这个过时的cd或者成员,虽然l承或者覆盖后的类型或者成员ƈ不是被声明ؓ@DeprecatedQ但~译器仍然要报警?br /> 值得注意Q@Deprecatedq个annotationcd和javadoc中的@deprecatedq个tag是有区别的:前者是java~译器识别的Q而后者是被javadoc工具所识别用来生成文档Q包含程序成员ؓ什么已l过时、它应当如何被禁止或者替代的描述Q?br /> 在java5.0Qjava~译器仍然象其从前版本那样寻找@deprecatedq个javadoc tagQƈ使用它们产生警告信息。但是这U状况将在后l版本中改变Q我们应在现在就开始用@Deprecated来修饰过时的Ҏ(gu)而不是@deprecated javadoc tag?br /> 清单2Q?/strong>

下面是一D用@Deprecated的代码:
/**
* q里是javadoc的@deprecated声明.
* @deprecated No one has players for this format any more.  Use VHS instead.
*/
@Deprecated public class Betamax { ... }


C.SuppressWarningsQ?/span>
@SuppressWarnings被用于有选择的关闭编译器对类、方法、成员变量、变量初始化的警告。在java5.0Qsun提供的javac~译器ؓ我们提供?Xlint选项来ɾ~译器对合法的程序代码提告,此种警告从某U程度上代表了程序错误。例如当我们使用一个generic collectionc而又没有提供它的cdӞ~译器将提示?unchecked warning"的警告?br />
通常当这U情况发生时Q我们就需要查扑ּ赯告的代码。如果它真的表示错误Q我们就需要纠正它。例如如果警告信息表明我们代码中的switch语句没有覆盖所有可能的caseQ那么我们就应增加一个默认的case来避免这U警告?br /> 总Q有时我们无法避免这U警告,例如Q我们用必d非generic的旧代码交互的generic collectioncLQ我们不能避免这个unchecked warning。此时@SuppressWarningpz上用场了,在调用的Ҏ(gu)前增加@SuppressWarnings修饰Q告诉编译器停止Ҏ(gu)Ҏ(gu)的警告?br /> SuppressWarning不是一个marker annotation。它有一个类型ؓString[]的成员,q个成员的gؓ被禁止的警告名。对于javac~译器来Ԍ?Xlint选项有效的警告名也同样对@SuppressWarings有效Q同时编译器忽略掉无法识别的警告名?br />
annotation语法允许在annotation名后跟括P括号中是使用逗号分割的name=value对用于ؓannotation的成员赋|
清单3Q?/strong>

@SuppressWarnings(value={"unchecked","fallthrough"})
public void lintTrap() { /* sloppy method body omitted */ }


在这个例子中SuppressWarnings annotationcd只定义了一个单一的成员,所以只有一个简单的value={...}作ؓname=value寏V又׃成员值是一个数l,故用大括号来声明数l倹{?br />
注意Q我们可以在下面的情况中~写annotationQ当annotation只有单一成员Qƈ成员命名?value="。这时可以省?value="。比如将上面的SuppressWarnings annotationq行~写Q?br /> 清单4Q?/strong>

@SuppressWarnings({"unchecked","fallthrough"})

如果SuppressWarnings所声明的被止警告个数Z个时Q可以省d括号Q?br />

@SuppressWarnings("unchecked")


3。Annotation语法Q?/span>

在上一个章节中Q我们看C写marker annotation和单一成员annotation的语法。下面本人来介绍一下完整的语法Q?br />
annotation?#8220;@+annotationcd名称+(..逗号分割的name-value?..)”l成。其中成员可以按照Q何的序。如果annotationcd定义了某个成员的默认|则这个成员可以被省略。成员值必Mؓ~译时常量、内嵌的annotation或者数l?br />
下面我们定义一个annotationcd名ؓReviewsQ它有一个由@Review annotation数组构成的成员。这个@Review annotationcd有三个成员:"reviewer"是一个字W串Q?comment" 是一个具有默认值的可选的字符Ԍ"grade"是一个Review.Grade枚Dcd倹{?br /> 清单5Q?/strong>

@Reviews({  // Single-value annotation, so "value=" is omitted here
    @Review(grade=Review.Grade.EXCELLENT,
            reviewer="df"),
    @Review(grade=Review.Grade.UNSATISFACTORY,
            reviewer="eg",
            comment="This method needs an @Override annotation")
})

annotation语法的另一个重要规则是没有E序成员可以有多于一个的同一annotation实例。例如在一个类中简单的攄多个@Review annotation。这也是在上面代码中定义@Reviews annotationcd数组的原因?br />
4。Annotation成员cd和|

annotation成员必须是非I的~译时常量表辑ּ。可用的成员cd为:primitivecd? String, Class, enumeratedcd, annotationcd, 和前面类型的数组?br />
下面我们定义了一个名为UncheckedExceptions 的annotationcdQ它的成员是一个扩展了RuntimeExceptioncȝcLl?br /> 清单6Q?/strong>

@UncheckedExceptions({
    IllegalArgumentException.class, StringIndexOutOfBoundsException.class
})


5。Annotation的目标:

annotation通常被放在类型定义和成员定义的前面。然而它也出现在package、方法参数、本地变量的前面。下面,我们来讨Z下这些不大常用的写法Q?br />
package annotation出现在package声明的前面?br /> 下面的例子package-info.java中不包含M的公q型定义,却包含一个可选的javadoc注释?br /> 清单7Q?/strong>

/**
* This package holds my custom annotation types.
*/
@com.davidflanagan.annotations.Author("David Flanagan")
package com.davidflanagan.annotations;

当package-info.java文g被编译时Q它?yu)生名为包含annotationQ特D的接口Q声明的package-info.class的类。这个接口没有成员,它的名字package-info不是一个合法的java标识Q所以它不能用在java源代码中。这个接口的存在只是单的被看作一个ؓpackage annotation准备的占位符?br />
用于修饰Ҏ(gu)参数、catch参数、本地变量的annotation只是单的出现在这些程序成员的修饰W位|。javacL件格式没有ؓ本地变量或者catch参数存储annotation作准备,所以这些annotationL保留在源代码U别Qsource retentionQ;Ҏ(gu)参数annotation能够保存在类文g中,也可以在保留到运行时?br />
最后,h意,枚Dcd定义中不允许M的修饰符修饰其枚丑ր{?br />
6。Annotation和默认|
在Annotation中,没有默认值的成员必须有一个成员倹{而如何理解默认值是如何被处理就是一个很重要的细节:annotationcd所定义的成员默认D存储在class文g中,不被~译到annotation里面。如果我们修改一个annotationcd使其成员的默认值发生了改变Q这个改变对于所有此cd的annotation中没有明提供成员值的成员产生影响Q即修改了该成员的成员|。即使在annotationcd使其成员的默认D改变后annotation从没被重新编译过Q该cd的annotation(改变前已l被~译?也受到媄响?br />
三、Annotation工作原理Q?/span>

Annotation与反?/span>
在java5.0中Java.lang.reflect提供的反API被扩充了dq行时annotation的能力。让我们回顾一下前面所讲的Q一个annotationcd被定义ؓruntime retention后,它才是在q行时可见,当class文g被装载时被保存在class文g中的annotation才会被虚拟机d。那么reflect是如何帮助我们访问class中的annotation呢?

下文在java.lang.reflect用于annotation的新Ҏ(gu),其中java.lang.reflect.AnnotatedElement是重要的接口Q它代表了提供查询annotation能力的程序成员。这个接口被java.lang.Package、java.lang.Class实现Qƈ间接地被MethodcRConstructorcRjava.lang.reflect的Fieldcd现。而annotation中的Ҏ(gu)参数可以通过MethodcRConstructorcȝgetParameterAnnotations()Ҏ(gu)获得?br />
下面的代码用了AnnotatedElementcȝisAnnotationPresent()Ҏ(gu)判断某个Ҏ(gu)是否h@Unstable annotationQ从而断a此方法是否稳定:
清单8Q?/strong>

import java.lang.reflect.*;

Class c = WhizzBangClass.class;                          
Method m = c.getMethod("whizzy", int.class, int.class);  
boolean unstable = m.isAnnotationPresent(Unstable.class);

isAnnotationPresent()Ҏ(gu)对于查marker annotation是十分有用的Q因为marker annotation没有成员变量Q所以我们只要知道class的方法是否用了annotation修饰可以了。而当处理h成员的annotationӞ我们通过使用getAnnotation()Ҏ(gu)来获得annotation的成员信息(成员名称、成员|。这里我们看C一套优的java annotationpȝQ如果annotation存在Q那么实C相应的annotationcd接口的对象将被getAnnotation()Ҏ(gu)q回Q接着调用定义在annotationcd中的成员Ҏ(gu)可以方便地获得Q何成员倹{?br />
回想一下,前面介绍的@Reviews annotationQ如果这个annotationcd被声明ؓruntime retention的话Q我们通过下面的代码来讉K@Reviews annotation的成员|
清单9Q?/strong>

AnnotatedElement target = WhizzBangClass.class; //获得被查询的AnnotatedElement
// 查询AnnotatedElement的@Reviews annotation信息
Reviews annotation = target.getAnnotation(Reviews.class);
// 因ؓ@Reviews annotationcd的成员ؓ@Review annotationcd的数l,
// 所以下面声明了Review[] reviews保存@Reviews annotationcd的value成员倹{?br /> Review[] reviews = annotation.value();
// 查询每个@Review annotation的成员信?br /> for(Review r : reviews) {
    Review.Grade grade = r.grade();
    String reviewer = r.reviewer();
    String comment = r.comment();
    System.out.printf("%s assigned a grade of %s and comment '%s'%n",
                      reviewer, grade, comment);
}


四、如何自定义AnnotationQ?/span>

1Q详解annotation与接口的异同Q?/span>
因ؓannotationcd是一个非凡的接口Q所以两者之间存在着某些差异Q?br />
A.Annotationcd使用关键字@interface而不是interface?/span>
q个关键字声明隐含了一个信息:它是l承了java.lang.annotation.Annotation接口Qƈ非声明了一个interface?br />
B.Annotationcd、方法定义是独特的、受限制的?/span>
Annotationcd的方法必d明ؓ无参数、无异常抛出的。这些方法定义了annotation的成员:Ҏ(gu)名成Z成员名,而方法返回值成Z成员的类型。而方法返回值类型必Mؓprimitivecd、Classcd、枚丄型、annotationcd或者由前面cd之一作ؓ元素的一l数l。方法的后面可以使用default和一个默认数值来声明成员的默认|null不能作ؓ成员默认|q与我们在非annotationcd中定义方法有很大不同?br /> Annotationcd和它的方法不能用annotationcd的参数、成员不能是generic。只有返回值类型是Class的方法可以在annotationcd中用genericQ因为此Ҏ(gu)能够用类转换各U类型{换ؓClass?br />
C.Annotationcd又与接口有着q似之处?/span>
它们可以定义帔R、静态成员类型(比如枚Dcd定义Q。Annotationcd也可以如接口一般被实现或者ѝ?br />
2Q实例:
下面Q我们将看到如何定义annotationcd的example。它展示了annotationcd声明以及@interface与interface之间的不同:
清单10Q?/strong>

package com.davidflanagan.annotations;
import java.lang.annotation.*;

/**
* 使用annotation来描q那些被标注的成员是不稳定的Q需要更?br /> */
@Retention(RetentionPolicy.RUNTIME)
public @interface Unstable {}


下面的另一个example只定义了一个成员。ƈ通过这个成员命名ؓvalueQ我们可以方便的用这Uannotation的快捷声明方式:
清单11Q?/strong>

/**
* 使用Authorq个annotation定义在程序中指出代码的作?br /> */
public @interface Author {
    /** q回作者名 */
    String value();
}


以下的example更加复杂。Reviews annotationcd只有一个成员,但是q个成员的类型是复杂的:由Review annotationl成的数l。Review annotationcd?个成员:枚Dcd成员grade、表CReview名称的字W串cd成员Reviewer、具有默认值的字符串类型成员Comment?br /> 清单12Q?/strong>

import java.lang.annotation.*;
        
/**
* Reviews annotationcd只有一个成员,
* 但是q个成员的类型是复杂的:由Review annotationl成的数l?br /> */
@Retention(RetentionPolicy.RUNTIME)
public @interface Reviews {
    Review[] value();
}

/**
* Review annotationcd?个成员:
* 枚Dcd成员grade?br />   * 表示Review名称的字W串cd成员Reviewer?br />   * h默认值的字符串类型成员Comment?br /> */
public @interface Review {
    // 内嵌的枚丄?br />     public static enum Grade { EXCELLENT, SATISFACTORY, UNSATISFACTORY };

    // 下面的方法定义了annotation的成?br />     Grade grade();                
    String reviewer();          
    String comment() default "";  
}


最后,我们来定义一个annotationҎ(gu)用于|列出类q行中所有的unchecked异常Q上文已l提到这U情况不一定是错误Q。这个annotationcd一个数l作Z唯一的成员。数l中的每个元素都是异常类。ؓ了加强对未检查的异常Q此cd帔R是在q行时抛出)q行报告Q我们可以在代码中对异常的类型进行限Ӟ
清单13Q?/strong>

public @interface UncheckedExceptions {
    Class<? extends RuntimeException>[] value();
}


五、Meta-Annotation

Annotationcd可以被它们自己所标注。Java5.0定义?个标准的meta-annotationcdQ它们被用来提供对其它annotationcd作说明。这些类型和它们所支持的类在java.lang.annotation包中可以扑ֈ。如果需要更详细的信息可以参考jdk5.0手册?br />
1Q再谈Target
作ؓmeta-annotationcd的Target,它描qCannotation所修饰的程序成员的cd。当一个annotationcd没有TargetӞ它将被作为普通的annotation看待。当它修饰一个特定的E序成员Ӟ它将发挥其应用的作用Q例如:Override用于修饰Ҏ(gu)Ӟ增加了@Targetq个meta-annotation׃ɾ~译器对annotation作检查,从而去掉修饰错误类型的Override?br />
Target meta-annotationcd有唯一的value作ؓ成员。这个成员的cd是java.lang.annotation.ElementType[]cd的,ElementTypecd是可以被标注的程序成员的枚Dcd?br />
2QRetention的用?/span>
我们在文章的开头曾l提到过RetentionQ但是没有详l讲解。Retention描述了annotation是否被编译器丢弃或者保留在class文gQ如果保留在class文g中,是否在class文g被装载时被虚拟机d。默认情况下Qannotation被保存在class文g中,但在q行时ƈ不能被反访问。Retentionh三个取|source、class、runtimeQ这些取值来自java.lang.annotation.RetentionPolicy的枚丄型倹{?br />
Retention meta-annotationcd有唯一的value作ؓ成员Q它的取值来自java.lang.annotation.RetentionPolicy的枚丄型倹{?br />
3QDocumented
Documented是一个meta-annotationcdQ用于描q其它类型的annotation应该被作标注的程序成员的公共APIQ因此可以被例如javadoc此类的工h档化?br />
Documented是一个marker annotationQ没有成员?br />
4QInherited
@Inherited meta-annotation也是一个marker annotationQ它阐述了某个被标注的类型是被承的。如果一个用了@Inherited修饰的annotationcd被用于一个classQ则q个annotation被用于该class的子cR?br />
注意Q@Inherited annotationcd是被标注q的class的子cLl承。类q不从它所实现的接口承annotationQ方法ƈ不从它所重蝲的方法承annotation?br />
值得思考的是,当@Inherited annotationcd标注的annotation的Retention是RetentionPolicy.RUNTIMEQ则反射API增强了这U承性。如果我们用java.lang.reflectL询一个@Inherited annotationcd的annotationӞ反射代码查将展开工作Q检查class和其父类Q直到发现指定的annotationcd被发玎ͼ或者到辄l承l构的顶层?br />
六、ȝQ?/span>

本文几乎覆盖了所有的Annotation的概念和知识点,从annotation的定义、语法到工作原理、如何自定义annotationQ直至meta-annotation。其中也h一些配套的代码片断可参考,虽然不是很多Q但是可谓言意赅、着光点,本h认ؓ用好annotation的关键还在于使用。希望本手册能够帮助大家用好annotationQ这也是本h的最大快乐?br />

hummer 2008-06-13 16:00 发表评论
]]>
利用AOP实现CACHE机制??http://www.tkk7.com/hummer008/articles/205756.htmlhummerhummerWed, 04 Jun 2008 03:37:00 GMThttp://www.tkk7.com/hummer008/articles/205756.htmlhttp://www.tkk7.com/hummer008/comments/205756.htmlhttp://www.tkk7.com/hummer008/articles/205756.html#Feedback0http://www.tkk7.com/hummer008/comments/commentRss/205756.htmlhttp://www.tkk7.com/hummer008/services/trackbacks/205756.html
cache.put(new Element(key,(Serializable)value));

攑օ~存中的value必须序列化,Java原生cd char、int Q原生类型的包装cString、Character、Integer、Number...和集合List的实现类ArrayList都已l实CSerializable接口Q它们都可以直接攑ֈ~存中。这里要注意的是Q在Ҏ(gu)q回gl常用到的IteratorQƈ没有实现Serializable接口Q所以Cache 不能~存q回值类型ؓIterator的方法?br />

 q有一点要注意的是Q如果我们要做缓存的Ҏ(gu)是在bean的生命周期的初始化阶D调用的Q例如setterQinitQ,此时Ҏ(gu)~存拦截器还没被调用执行Q那么缓存将不v作用Q如做了下面的配|:

<bean id="OrganizationManagerMethodCache" class="org.springframework.aop.framework.ProxyFactoryBean">
   <property name="target">
   <bean class="com.wzj.rbac.ServiceFacade.OrganizationManager" init-method="init" autowire="byName"/>
   </property>
   <property name="interceptorNames">
   <list>
   <value>methodCachePointCut</value>
   </list>
   </property>
   </bean>
   在init初始Ҏ(gu)里面调用的缓存方法将失效?

hummer 2008-06-04 11:37 发表评论
]]>
利用AOP实现CACHE机制http://www.tkk7.com/hummer008/articles/205589.htmlhummerhummerTue, 03 Jun 2008 08:43:00 GMThttp://www.tkk7.com/hummer008/articles/205589.htmlhttp://www.tkk7.com/hummer008/comments/205589.htmlhttp://www.tkk7.com/hummer008/articles/205589.html#Feedback0http://www.tkk7.com/hummer008/comments/commentRss/205589.htmlhttp://www.tkk7.com/hummer008/services/trackbacks/205589.html 1.首先配置ehcache.xml

<ehcache>

    <diskStore path="java.io.tmpdir"/>
   
    <defaultCache  
        maxElementsInMemory="10000"    
        eternal="false"                        
        timeToIdleSeconds="120"       
        timeToLiveSeconds="120"   
        overflowToDisk="true"         
    />  

    <cache name="org.taha.cache.METHOD_CACHE"
        maxElementsInMemory="300"
        eternal="false"
        timeToIdleSeconds="60"
        timeToLiveSeconds="60"
        overflowToDisk="true"
        />

</ehcache>

 //defaultCache  一定要有不然解析报?/p>

2. spring-ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans default-autowire="byName">

 <bean id="cacheManager"
  class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">

  <property name="configLocation">
   <value>classpath:ehcache.xml</value>
  </property>
 </bean>


 <bean id="methodCache"
  class="org.springframework.cache.ehcache.EhCacheFactoryBean">

  <property name="cacheManager">
   <ref local="cacheManager" />
  </property>

  <property name="cacheName">
   <value>org.taha.cache.METHOD_CACHE</value>
  </property>

 </bean>


 <bean id="methodCacheInterceptor"
  class="com.infowarelab.cem.easytouch.web.interceptor.MethodCacheInterceptor">

  <property name="cache">

   <ref local="methodCache" />

  </property>

 </bean>

 

 <bean id="methodCachePointCut"
  class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">

  <property name="advice">

   <ref local="methodCacheInterceptor" />

  </property>

  <property name="patterns">

   <list>

    <value>.*methodOne</value>

    <value>.*methodTwo</value>   //匚wmethodTwo的方?nbsp;   
    <value>.*cache.*</value>      //匚w?cache开头的Ҏ(gu)

   </list>

  </property>

 </bean>

 

 <bean id="myBean"
  class="org.springframework.aop.framework.ProxyFactoryBean">

  <property name="target">

   <bean class="com.infowarelab.cem.easytouch.web.interceptor.MyBean" />

  </property>

  <property name="interceptorNames">

   <list>

    <value>methodCachePointCut</value>

   </list>

  </property>

 </bean>
 
 
 

</beans>


 3 MethodCacheInterceptor 代码

package com.infowarelab.cem.easytouch.web.interceptor;

import java.io.Serializable;

import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.beans.factory.InitializingBean;

public class MethodCacheInterceptor implements MethodInterceptor,

InitializingBean {

 private Cache cache;

 /**
  *
  * sets cache name to be used
  *
  */

 public void setCache(Cache cache) {

  this.cache = cache;

 }

 /*
  *
  * (non-Javadoc)
  *
  *
  *
  * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
  *
  */

 public Object invoke(MethodInvocation invocation) throws Throwable {

  String targetName = invocation.getThis().getClass().getName();

  String methodName = invocation.getMethod().getName();

  Object[] arguments = invocation.getArguments();

  Object result;

  String cacheKey = getCacheKey(targetName, methodName, arguments);

  Element element = cache.get(cacheKey);

  if (element == null) {

   // call target/sub-interceptor

   result = invocation.proceed();

   // cache method result

   element = new Element(cacheKey, (Serializable) result);

   cache.put(element);

  }

  return element.getValue();

 }

 /**
  *
  * creates cache key: targetName.methodName.argument0.argument1...
  *
  */

 private String getCacheKey(String targetName, String methodName,

 Object[] arguments) {

  StringBuffer sb = new StringBuffer();

  sb.append(targetName).append(".").append(methodName);

  if ((arguments != null) && (arguments.length != 0)) {

   for (int i = 0; i < arguments.length; i++) {

    sb.append(".").append(arguments[i]);

   }

  }

  return sb.toString();

 }

 /*
  *
  * (non-Javadoc)
  *
  *
  *
  * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
  *
  */

 public void afterPropertiesSet() throws Exception {

  // TODO Auto-generated method stub

 }

}


4 MyBean 代码部分

package com.infowarelab.cem.easytouch.web.interceptor;

import com.infowarelab.cem.easytouch.service.ConfigdbInfoService;

public class MyBean {
 
 
 private ConfigdbInfoService configdbInfoService;
 

 public String  methodOne(String siteId,String name){
 
     String cityName=configdbInfoService.getCityNameByIp("192.168.1.92");
    
  return ""+siteId+name+cityName;
 }
 
 public String  methodTwo(String siteId,String name,String pwd){
  
  String cityName=configdbInfoService.getCountryNameByIp("192.168.1.92");
  
  return ""+siteId+name+cityName;
 }

 public void setConfigdbInfoService(ConfigdbInfoService configdbInfoService) {
  this.configdbInfoService = configdbInfoService;
 }
 
 
 
}


5.CopyOfLogin 代码 试 AOP 代码


package com.infowarelab.cem.easytouch.web.action.api;

import com.infowarelab.cem.easytouch.web.interceptor.MyBean;

/**
 *
 * @author hummer.hu
 * @date:2008-4-24
 *
 */
public class CopyOfLogin extends ApiBaseAction {

 
 
 private MyBean myBean;
 

 public String execute() {

 
  
  myBean.methodOne("5555555", "aaaa");
  myBean.methodTwo("6666666", "aaaa", "bbbb");
  return "login";
  
  
 }
 public void setMyBean(MyBean myBean) {
  this.myBean = myBean;
 }

 
 
}



hummer 2008-06-03 16:43 发表评论
]]>
IP地址怺转化http://www.tkk7.com/hummer008/articles/205357.htmlhummerhummerMon, 02 Jun 2008 08:27:00 GMThttp://www.tkk7.com/hummer008/articles/205357.htmlhttp://www.tkk7.com/hummer008/comments/205357.htmlhttp://www.tkk7.com/hummer008/articles/205357.html#Feedback0http://www.tkk7.com/hummer008/comments/commentRss/205357.htmlhttp://www.tkk7.com/hummer008/services/trackbacks/205357.htmlpublic class IPUtil {
 
 
 public static int IPToInt(String ipAddress)
 {
  String[]   ipqi_ary=ipAddress.split("\\.");    
  int ip0= new Integer(ipqi_ary[0]).intValue();
  int ip1= new Integer(ipqi_ary[1]).intValue();
  int ip2= new Integer(ipqi_ary[2]).intValue();
  int ip3= new Integer(ipqi_ary[3]).intValue();
     return ip0*256*256*256+ip1*256*256+ip2*256+ip3;
 }

 public static String IntToIP(int ipAddress)
 {
     long ui1 = ipAddress & 0xFF000000;
  ui1 = ui1 >> 24;
  long ui2 = ipAddress & 0x00FF0000;
  ui2 = ui2 >> 16;
  long ui3 = ipAddress & 0x0000FF00;
  ui3 = ui3 >> 8;
  long ui4 = ipAddress & 0x000000FF;
  String IPstr = "";
  IPstr = String.valueOf(ui1) + "." + String.valueOf(ui2) + "."
    + String.valueOf(ui3) + "." + String.valueOf(ui4);
  return IPstr;
 }

 public static void  main(String args[]){
  
  String ipAddress="58.17.128.0";
  
  int ipInt=IPUtil.IPToInt(ipAddress);
  
  System.out.println("String to int :"+ipInt);
  
  System.out.println("int to String :"+IPUtil.IntToIP(ipInt));
 }
 
}



hummer 2008-06-02 16:27 发表评论
]]>
postҎ(gu)调用java接口 http://www.tkk7.com/hummer008/articles/205341.htmlhummerhummerMon, 02 Jun 2008 07:13:00 GMThttp://www.tkk7.com/hummer008/articles/205341.htmlhttp://www.tkk7.com/hummer008/comments/205341.htmlhttp://www.tkk7.com/hummer008/articles/205341.html#Feedback1http://www.tkk7.com/hummer008/comments/commentRss/205341.htmlhttp://www.tkk7.com/hummer008/services/trackbacks/205341.html // urlParam=http://192.168.1.92/easycall/cmd?funcName=check;

private String getBillingForEasytouch(String urlParam){
  
  String result="";
  try{
  URL url = new URL(urlParam);     
  URLConnection connection = url.openConnection();
  connection.setDoOutput(true);
  OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), "utf-8");    
  
  Integer easytouchServiceId = easyTouchConfig
  .getInteger(Constants.CEM_EASYTOUCH_SERVICE_ID);

  String pwd = easyTouchConfig
  .getString(Constants.BILLING_FOR_EASYTOUCH_PWD);  
  out.write("c=siteId:"+siteId+",pwd:"+pwd+",serviceId:"+easytouchServiceId+"&s=0");    
  out.flush();
  out.close();

   BufferedReader in = new BufferedReader(new InputStreamReader(
     connection.getInputStream()));
   String line;
   while ((line = in.readLine()) != null) {
    result += line;
   }
   in.close();
   
   
  }
  catch(Exception e){
   
  }
  
  return result;
 }



hummer 2008-06-02 15:13 发表评论
]]>
性能问题排查http://www.tkk7.com/hummer008/articles/201824.htmlhummerhummerWed, 21 May 2008 01:32:00 GMThttp://www.tkk7.com/hummer008/articles/201824.htmlhttp://www.tkk7.com/hummer008/comments/201824.htmlhttp://www.tkk7.com/hummer008/articles/201824.html#Feedback0http://www.tkk7.com/hummer008/comments/commentRss/201824.htmlhttp://www.tkk7.com/hummer008/services/trackbacks/201824.html一 ȝ概要:
1.首先解决问题的方向不?没有证实靠猜就盲目优化SQL语句.(其实SQL语句性能不慢?猜测 in(11,22,33,...) 语句的性能问题)
2.Ҏ(gu)已经发现的问题熟视无?明明知道面展现有性能问题(IT性能?FIREFOX正常没有引v_的重?
3.在自己写USQL语句优化无结果的情况?重新审视q去走过的弯?br /> 4.不要放过每个l节,自己思\一定要清晰,坚持是胜利?/p>

 

?实际操作q程:
1.数据库环?192.168.0.70  cem_vcc
2.需要优化的SQL语句

  基本SQL  A:    select vl.*  from vccrawlog vl,
   cem_cc_operator op,
   cem_cc_operator_acd_group ag
   where op.user_id=ag.user_id and ag.site_id=op.site_id
   and ag.site_id=2010010                       
   and auto_rec_name is not null and is_rec_deleted=0  and endtime is not null
                        and  vl.site_id=2010010
                        and acd_group_id in
                        (542,632,622,862,752,692,702,822,552,722,532,662,812,562,642,782,832,732,872,802,792,742,712,652) and ( (callee_id =op.site_extension and call_type=0 ) or( caller_id =op.site_extension and call_type=1  ))
                        order by sequence   desc;

要求 1.A语句需要进?COUNT(*) 操作
     2.A语句需要进?分页


业务要说? 查询VCCRAWLOG满所有acd_group_id in
                        (542,632,622,862,752,692,702,822,552,722,532,662,812,562,642,782,832,732,872,802,792,742,712,652) 里面座席数据.


http://localhost:8080/vcc10/page/listRecords.action?&site=8ins


mysql 命o

show create table vccrawlog;
show index from vccrawlog;

SQL_NO_CACHE 不用~存

select DISTINCT


*************************************************
 1.COUNT语句

select sum(cnt) from
(
select count(*) cnt from vccrawlog vl, cem_cc_operator op, cem_cc_operator_acd_group ag
where op.user_id=ag.user_id and ag.site_id=op.site_id
  and vl.site_id=op.site_id and vl.caller_id =op.site_extension and vl.call_type=1
  and ag.site_id=2010010 and vl.auto_rec_name is not null and vl.is_rec_deleted=0  and vl.endtime is not null
  and ag.acd_group_id in (542,632,622,862,752,692,702,822,552,722,532,662,812,562,642,782,832,732,872,802,792,742,712,652)
union all
select count(*) cnt from vccrawlog vl, cem_cc_operator op, cem_cc_operator_acd_group ag
where op.user_id=ag.user_id and ag.site_id=op.site_id
  and vl.site_id=op.site_id and vl.callee_id =op.site_extension and vl.call_type=0
  and ag.site_id=2010010 and vl.auto_rec_name is not null and vl.is_rec_deleted=0  and vl.endtime is not null
  and ag.acd_group_id in (542,632,622,862,752,692,702,822,552,722,532,662,812,562,642,782,832,732,872,802,792,742,712,652)
) a;

说明 通过union all 可以分别利用 caller_id ?callee_id索引


****************************************************


2 .countSql:

select sum(cnt) from
(
select count(*) cnt from vccrawlog vl, ( select op.site_id,op.site_extension from cem_cc_operator op, cem_cc_operator_acd_group ag
where op.user_id=ag.user_id and ag.site_id=op.site_id
  and ag.site_id=2010010
  and ag.acd_group_id in (542,632,622,862,752,692,702,822,552,722,532,662,812,562,642,782,832,732,872,802,792,742,712,652)
  union select 2010010,20100108888 ) operators
  where vl.site_id=operators.site_id and vl.caller_id =operators.site_extension and vl.call_type=1
  and vl.auto_rec_name is not null and vl.is_rec_deleted=0  and vl.endtime is not null
 
union all
select count(*) cnt from vccrawlog vl, ( select op.site_id,op.site_extension from cem_cc_operator op, cem_cc_operator_acd_group ag
where op.user_id=ag.user_id and ag.site_id=op.site_id
  and ag.site_id=2010010
  and ag.acd_group_id in (542,632,622,862,752,692,702,822,552,722,532,662,812,562,642,782,832,732,872,802,792,742,712,652)
  union select 2010010,20100108888 ) operators
  where vl.site_id=operators.site_id and vl.callee_id =operators.site_extension and vl.call_type=0
  and vl.auto_rec_name is not null and vl.is_rec_deleted=0  and vl.endtime is not null
) a;

说明:
select op.site_id,op.site_extension from cem_cc_operator op, cem_cc_operator_acd_group ag
       where op.user_id=ag.user_id and ag.site_id=op.site_id    and ag.site_id=2010010
       and ag.acd_group_id in (542,632,622,862,752,692,702,822,552,722,532,662,812,562,642,782,832,732,872,802,792,742,712,652)
       union select 2010010,20100108888

可以L大量的重复数?/p>

******************************************************************************


面性能排查:

  1.逐步执行
    <script language="javascript">
        alert('aaaaaaa');
    </script>

   2.暂时删除觉得没有问题的部?/p>


 



hummer 2008-05-21 09:32 发表评论
]]>
mysql explain 分析说明http://www.tkk7.com/hummer008/articles/200045.htmlhummerhummerMon, 12 May 2008 08:36:00 GMThttp://www.tkk7.com/hummer008/articles/200045.htmlhttp://www.tkk7.com/hummer008/comments/200045.htmlhttp://www.tkk7.com/hummer008/articles/200045.html#Feedback0http://www.tkk7.com/hummer008/comments/commentRss/200045.htmlhttp://www.tkk7.com/hummer008/services/trackbacks/200045.html
table
昄q一行的数据是关于哪张表?

type
q是重要的列Q显C接用了何种cd。从最好到最差的q接cd为const、eq_reg、ref、range、indexhe和ALL

possible_keys
昄可能应用在这张表中的索引。如果ؓI,没有可能的烦引。可以ؓ相关的域从WHERE语句中选择一个合适的语句

key
实际使用的烦引。如果ؓNULLQ则没有使用索引。很的情况下,MYSQL会选择优化不的烦引。这U情况下Q可以在SELECT语句中用USE INDEXQindexnameQ来强制使用一个烦引或者用IGNORE INDEXQindexnameQ来强制MYSQL忽略索引

key_len
使用的烦引的长度。在不损q性的情况下,长度短好

ref
昄索引的哪一列被使用了,如果可能的话Q是一个常?

rows
MYSQL认ؓ必须查的用来q回h数据的行?

Extra
关于MYSQL如何解析查询的额外信息。将在表4.3中讨论,但这里可以看到的坏的例子是Using temporary和Using filesortQ意思MYSQLҎ(gu)不能使用索引Q结果是索会很慢




extra列返回的描述的意?

Distinct
一旦MYSQL扑ֈ了与行相联合匚w的行Q就不再搜烦?

Not exists
MYSQL优化了LEFT JOINQ一旦它扑ֈ了匹配LEFT JOIN标准的行Q?

׃再搜索了

Range checked for each

RecordQindex map:#Q?
没有扑ֈ理想的烦引,因此对于从前面表中来的每一个行l合QMYSQL查用哪个烦引,q用它来从表中返回行。这是用烦引的最慢的q接之一

Using filesort
看到q个的时候,查询需要优化了。MYSQL需要进行额外的步骤来发现如何对q回的行排序。它Ҏ(gu)q接cd以及存储排序键值和匚w条g的全部行的行指针来排序全部行

Using index
列数据是从仅仅用了索引中的信息而没有读取实际的行动的表q回的,q发生在对表的全部的h列都是同一个烦引的部分的时?

Using temporary
看到q个的时候,查询需要优化了。这里,MYSQL需要创Z个时表来存储结果,q通常发生在对不同的列集进行ORDER BY上,而不是GROUP BY?

Where used
使用了WHERE从句来限制哪些行与下一张表匚w或者是q回l用戗如果不惌回表中的全部行,q且q接cdALL或indexQ这׃发生Q或者是查询有问?




不同q接cd的解释(按照效率高低的顺序排序)

system
表只有一行:system表。这是constq接cd的特D情?

const
表中的一个记录的最大D够匹配这个查询(索引可以是主键或惟一索引Q。因为只有一行,q个值实际就是常敎ͼ因ؓMYSQL先读q个值然后把它当做常数来对待

eq_ref
在连接中QMYSQL在查询时Q从前面的表中,Ҏ(gu)一个记录的联合都从表中d一个记录,它在查询使用了烦引ؓ主键或惟一键的全部时?

ref
q个q接cd只有在查询用了不是惟一或主键的键或者是q些cd的部分(比如Q利用最左边前缀Q时发生。对于之前的表的每一个行联合Q全部记录都从表中d。这个类型严重依赖于Ҏ(gu)索引匚w的记录多—越越?

range
q个q接cd使用索引q回一个范围中的行Q比如?gt;?lt;查找东西时发生的情况

index
q个q接cd对前面的表中的每一个记录联合进行完全扫描(比ALL更好Q因为烦引一般小于表数据Q?

ALL
q个q接cd对于前面的每一个记录联合进行完全扫描,q一般比较糟p,应该量避免


hummer 2008-05-12 16:36 发表评论
]]>
hibernate~存理(? http://www.tkk7.com/hummer008/articles/192118.htmlhummerhummerFri, 11 Apr 2008 03:27:00 GMThttp://www.tkk7.com/hummer008/articles/192118.htmlhttp://www.tkk7.com/hummer008/comments/192118.htmlhttp://www.tkk7.com/hummer008/articles/192118.html#Feedback0http://www.tkk7.com/hummer008/comments/commentRss/192118.htmlhttp://www.tkk7.com/hummer008/services/trackbacks/192118.htmlhibernate可以用两U不同的对象~存Qfirst-level cache ?second-level cache。first-level cache和Session对象兌Q而second-level cache是和Session Factory对象兌?/span>

        ~省圎ͼhibernate已经使用Z每个事务?/span>first-level cache?/span> Hibernate?/span>first-level cache主要是减在一个事务内?/span>sql查询数量。例如,如果一个对象在同一个事务内被修改多ơ,hibernate只生成一个包括所有修改的 UPDATE SQL语句。ؓ了减数据流动,second-level cache?/span>Session FactoryU的不同事务之间保持load的对象,q些对象Ҏ(gu)个应用可用,不只是对当前用户正在q行的查询。这P每次查询返回已l?/span>load在缓?/span>里的对象Q避免一个或更多潜在的数据库事务?/span>

下蝲ehcacheQhibernate3.2必须要ehcache1.2以上才能支持。可以修改log4j配置文glog4j.logger.net.sf.hibernate.cache=debug查看日志

1.在类路径?span style="font-family: Arial">ehcache.xmlQ?/p>

<ehcache>    
     <diskStore path="java.io.tmpdir"/>
      <defaultCache
         maxElementsInMemory="10000"
         eternal="false"
         overflowToDisk="true"
         timeToIdleSeconds="120"
         timeToLiveSeconds="120"
         diskPersistent="false"
         diskExpiryThreadIntervalSeconds="120"/>       
   
</ehcache>

2.applicationContext-hibernate.xml?/span>Hibernate SessionFactory配置Q?/span>

           <property name="hibernateProperties">
             <props>
                 <prop key="hibernate.dialect">@HIBERNATE-DIALECT@</prop>
                 <!--<prop key="hibernate.show_sql">true</prop>-->
                 <prop key="hibernate.max_fetch_depth">3</prop>
                 <prop key="hibernate.hibernate.use_outer_join">true</prop>
                 <prop key="hibernate.jdbc.batch_size">10</prop>
                 <prop key="hibernate.cache.use_query_cache">true</prop>
                 <prop         key="hibernate.cache.use_second_level_cache">true</prop>
                 <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>                

             </props>
        
          </bean>
说明Q如果不讄查询~存Q那?/span>hibernate只会~存使用load()Ҏ(gu)获得的单个持久化对象Q如果想~存使用findall()?/span> list()?/span>Iterator()?/span>createCriteria()?/span>createQuery(){方法获得的数据l果集的话,需要设|?/span> hibernate.cache.use_query_cache true 才行

.对于"query cache"Q需要在E序里编码:

         getHibernateTemplate().setCacheQueries(true);
         return getHibernateTemplate().find(hql);



hummer 2008-04-11 11:27 发表评论
]]>
hibernate~存理(一)http://www.tkk7.com/hummer008/articles/192109.htmlhummerhummerFri, 11 Apr 2008 03:14:00 GMThttp://www.tkk7.com/hummer008/articles/192109.htmlhttp://www.tkk7.com/hummer008/comments/192109.htmlhttp://www.tkk7.com/hummer008/articles/192109.html#Feedback0http://www.tkk7.com/hummer008/comments/commentRss/192109.htmlhttp://www.tkk7.com/hummer008/services/trackbacks/192109.html  

下蝲ehcacheQhibernate3.2必须要ehcache1.2以上才能支持。可以修改log4j配置文glog4j.logger.net.sf.hibernate.cache=debug查看日志


< ehcache>
    < diskStore path="c:\\ehcache\"/>
    < defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        overflowToDisk="true"  
        />
       
    < !-- 讄Categorycȝ~存的数据过期策?-->
    < cache name="org.qiujy.domain.cachedemo.Category"
        maxElementsInMemory="100"
        eternal="true"
        timeToIdleSeconds="0"
        timeToLiveSeconds="0"
        overflowToDisk="false"
        />
       
     < !-- 讄Categorycȝproducts集合的缓存的数据q期{略 -->
     < cache name="org.qiujy.domain.cachedemo.Category.products"
        maxElementsInMemory="500"
        eternal="false"
        timeToIdleSeconds="300"
        timeToLiveSeconds="600"
        overflowToDisk="true"
        />
       
    < cache name="org.qiujy.domain.cachedemo.Product"
        maxElementsInMemory="500"
        eternal="false"
        timeToIdleSeconds="300"
        timeToLiveSeconds="600"
        overflowToDisk="true"
        />
   
< /ehcache>

配置的元素说明:
元素或属?描述
< diskStore> 讄~存数据文g的存攄?
< defaultCache> 讄~存的默认数据过期策?
< cache> 讑֮具体的命名缓存的数据q期{略
每个命名~存代表一个缓存区域,每个~存区域有各自的数据q期{略。命名缓存机制得用戯够在每个cM及类的每个集合的_度上设|数据过期策略?
cache元素的属?nbsp; 
name 讄~存的名?它的取gؓcȝ全限定名或类的集合的名字
maxInMemory 讄Z内存的缓存中可存攄对象最大数?
eternal 讄对象是否为永久的,true表示怸q期,此时忽略timeToIdleSeconds和timeToLiveSeconds属?
默认值是false
timeToIdleSeconds 讄对象I闲最长时?过q个旉,对象q期。当对象q期?EHCache会把它从~存中清除?br /> 如果此gؓ0,表示对象可以无限期地处于I闲状态?
timeToLiveSeconds 讄对象生存最长时?过q个旉,对象q期?br /> 如果此gؓ0,表示对象可以无限期地存在于缓存中?
overflowToDisk 讄Z内在的缓存中的对象数目达C限后,是否把溢出的对象写到Z盘的缓存中



hummer 2008-04-11 11:14 发表评论
]]>
构徏WEBTEST工程http://www.tkk7.com/hummer008/articles/191521.htmlhummerhummerTue, 08 Apr 2008 08:03:00 GMThttp://www.tkk7.com/hummer008/articles/191521.htmlhttp://www.tkk7.com/hummer008/comments/191521.htmlhttp://www.tkk7.com/hummer008/articles/191521.html#Feedback0http://www.tkk7.com/hummer008/comments/commentRss/191521.htmlhttp://www.tkk7.com/hummer008/services/trackbacks/191521.html构徏WEBTEST工程

1.       http://webtest.canoo.com/webtest/manual/Downloads.html 下蝲webTest相关?/span> build.zip

q?/span>unzip?/span> d:"dev"webtest目录

2.       安装 ant 下蝲ant的网址Q?/span>http://ant.apache.org/ (version 1.7.0)

ANT_HOME=d:"dev"ant

PATH=…%ANT_HOME%"bin

3.       使用 ANT 创徏webtest工程先进?/span>命oH口

d:"dev>ant –f webtest"webtest.xml wt.createProject

创徏成功默认myWebTestProject 工程

4.       RUN demo tests

d:"dev"myWebTestProject>ant

5.       test report à览器自动会打开试报告

6.       把工E导?/span>eclipse

googleWebTest.xml 文g如下

具体的资?/span> http://webtest.canoo.com/webtest/manual/stepIndex.html

WebtestҎ(gu)ȝ如下:

1.       webtest模拟Firefox?/span> Internet Explorer方式执行JavaScript.

2.       不接收格式不正确?/span>HTML

3.       Ҏ(gu)扩展和整?/span>

4.       webtest是纯java~写?/span>,可以q行在有JDK的Q何机器上.

5.       完美的结果报?/span>,特别列出出错case的原?/span>



hummer 2008-04-08 16:03 发表评论
]]>
selenium亲自RUN的实例(转蝲Q?/title><link>http://www.tkk7.com/hummer008/articles/185725.html</link><dc:creator>hummer</dc:creator><author>hummer</author><pubDate>Wed, 12 Mar 2008 08:14:00 GMT</pubDate><guid>http://www.tkk7.com/hummer008/articles/185725.html</guid><wfw:comment>http://www.tkk7.com/hummer008/comments/185725.html</wfw:comment><comments>http://www.tkk7.com/hummer008/articles/185725.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/hummer008/comments/commentRss/185725.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/hummer008/services/trackbacks/185725.html</trackback:ping><description><![CDATA[<p><br /> 一些准备:JRE1.5+ ?览器要?/p> <p><br /> Windows<br /> 如果你用的是Windows XP 或者是Windows2003Q你可以使用IE 览器,或者安装Mozilla Firefox 或者Opera览器?<br /> 如果你是用的是Windows2000Q如果想使用IE览器,你就需要安装reg.exeQ但是如果用Firefox不需要。我们徏议(但不是必)你的浏览器执行路径加到你的PATH环境变量中(如果你不知道如何你的浏览器安装目录加到PATH中,那么你就必须你的浏览器安装到标准\径下QFirefox的标准\径:"c:\Program Files\Mozilla Firefox\firefox.exe"QIE览器的标准路径Q?c:\Program Files\Internet Explorer\iexplore.exe"Q?/p> <p> </p> <p>1. 先去 http://selenium-rc.openqa.org/download.jsp 下蝲selenium包。解压?</p> <p>2. 用命令行来到解压的文件夹下: \selenium-remote-control-0.9.2\selenium-server-0.9.2</p> <p>3. q行Q?java -jar selenium-server.jar 启动selenium server</p> <p>4. 在Eclipse创徏一个项目,在项目的build path里面加上junit.jar和selenium-java-client-driver.jarQ这个在刚解压的包里面)</p> <p>5. 然后在Eclipse里运?“Run As -> unit Test”卛_看到自动化的范例</p> <p> </p> <p>最后粘贴一下那个测试程?/p> <p> </p> <p>import com.thoughtworks.selenium.DefaultSelenium;<br /> import com.thoughtworks.selenium.Selenium;</p> <p>import junit.framework.TestCase;</p> <p>public class GoogleTest extends TestCase {<br />     private Selenium selenium;</p> <p>    public void setUp() throws Exception {<br />         String url = "http://www.google.com";<br />         selenium = new DefaultSelenium("localhost", 4444, "*firefox", url);  //4444 is default server port </p> <p>   selenium.start();      <br />     }</p> <p>    protected void tearDown() throws Exception {<br />         selenium.stop();<br />     }</p> <p>    public void testGoogle() throws Throwable {<br />         selenium.open("http://www.google.com/webhp?hl=en");</p> <p>        assertEquals("Google", selenium.getTitle());<br />         selenium.type("q", "Selenium OpenQA");<br />         assertEquals("Selenium OpenQA", selenium.getValue("q"));<br />         selenium.click("btnG");<br />         selenium.waitForPageToLoad("5000");<br />         assertEquals("Selenium OpenQA - Google Search", selenium.getTitle());<br />     }<br /> } </p> <p><br /> 相关资料Q?nbsp;<br /> </p> <p><a href="http://www.tkk7.com/becky/archive/2008/03/06/184267.html">http://www.tkk7.com/becky/archive/2008/03/06/184267.html</a><br /> </p> <p>http://www.javaeye.com/topic/160592 </p> <p> </p> <img src ="http://www.tkk7.com/hummer008/aggbug/185725.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/hummer008/" target="_blank">hummer</a> 2008-03-12 16:14 <a href="http://www.tkk7.com/hummer008/articles/185725.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://gjwlgzs.com" target="_blank">þþȹ͵ۺ</a>| <a href="http://taoh2517.com" target="_blank">AV˾þԭ</a>| <a href="http://3838dydy.com" target="_blank">91˳վ߹ۿ18</a>| <a href="http://cnlawedu.com" target="_blank">Ů˽Ƶwww</a>| <a href="http://yanyingqiang.com" target="_blank">ƷѾþþþþþþ </a>| <a href="http://www-188588.com" target="_blank">Ļ뱬AV</a>| <a href="http://jjesqc.com" target="_blank">Ļ</a>| <a href="http://wdjiuye.com" target="_blank">Ļۺ234</a>| <a href="http://44od.com" target="_blank">Av߲</a>| <a href="http://yanhx.com" target="_blank">޹Ļ߹ۿ </a>| <a href="http://an930.com" target="_blank">AVƬ</a>| <a href="http://www2626cf.com" target="_blank">߹ۿwwwƵ</a>| <a href="http://whlnrsqsie.com" target="_blank">95˾Ѹ</a>| <a href="http://qzapp88.com" target="_blank">91վѹۿ</a>| <a href="http://wwwyy763.com" target="_blank">Ļȫ</a>| <a href="http://jybelt.com" target="_blank">ҹaëƬ</a>| <a href="http://baicaijia666.com" target="_blank">ƷҹѸ </a>| <a href="http://sdyzzs.com" target="_blank">aƵ</a>| <a href="http://sh-shule.com" target="_blank">ϺƷAV߲</a>| <a href="http://8099456.com" target="_blank">24СʱѿƬ</a>| <a href="http://sczssc.com" target="_blank">ƬƵ</a>| <a href="http://wxxwy.com" target="_blank">͹ƷƵƷ</a>| <a href="http://wcnmgb.com" target="_blank">ȫëƬѲ</a>| <a href="http://ttvv77.com" target="_blank">޾Ʒר</a>| <a href="http://fanqi5.com" target="_blank">AVþþƷ</a>| <a href="http://ranjihua.com" target="_blank">þ˽˹ƷvA</a>| <a href="http://taoduoduo666.com" target="_blank">˳վ18ֹþӰԺ</a>| <a href="http://8884493.com" target="_blank">˳ɫ99999߹ۿ</a>| <a href="http://zzttt04.com" target="_blank">ɫ͵͵޵һۺ</a>| <a href="http://666za.com" target="_blank">þù</a>| <a href="http://hxpc28.com" target="_blank">þþþþԻAV</a>| <a href="http://xww678.com" target="_blank">õĻ2019 </a>| <a href="http://977446.com" target="_blank">椸ֻƵ</a>| <a href="http://cjsyw123.com" target="_blank">ŷƷպһҹҹ </a>| <a href="http://cangtuyuan.com" target="_blank">պaƵ</a>| <a href="http://haidiaori.com" target="_blank">91Ʒˬž߹ۿ</a>| <a href="http://jdvgo.com" target="_blank">լоƷһ߹ۿ</a>| <a href="http://dszb0099.com" target="_blank">ҹ޾ƷӰ</a>| <a href="http://wlzp88.com" target="_blank">ƬվɫƬѹۿcn </a>| <a href="http://ziguang1688.com" target="_blank">99ѹۿƵ</a>| <a href="http://zgdhuibao.com" 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>