<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Rory's Blog
    Happy study,Happy work,Happy life
    posts - 22,  comments - 46,  trackbacks - 0
    xstream是個好東西。對于配置文件的讀取很方便。在mybog中我就用到了。不過今天打算用yupoo的api來做相冊。發(fā)現(xiàn)xstream對于xmlnode的attribute解析支持不是那么的好。
    對于這種節(jié)點格式的非常的簡單
    <result>
    ????
    <page>1</page>
    ????
    <pages>1</pages>
    ????
    <perpage>100</perpage>
    ????
    <total>19</total>
    ????
    <photos>
    ????????
    <photo>
    ????????????
    <id>ff8080810fc8ac78010fd3f158d40a52</id>
    ????????????
    <owner>ff8080810f1a387b010f1a83d6530dfc</owner>
    ????????????
    <title>Gmail-2</title>
    ????????????
    <host>4</host>
    ????????????
    <dir>20061230</dir>
    ????????????
    <filename>231905_1463411198</filename>
    ????????
    </photo>
    ????
    </photos>
    </result>

    簡單的alias一下就可以讀到值了
    File?file?=?new?File("src/test/java/com/jdkcn/test/result.xml");
    BufferedReader?reader?
    =?new?BufferedReader(new?InputStreamReader(new?FileInputStream(file),?"UTF-8"));
    XStream?stream?
    =?new?XStream();
    stream.alias(
    "result",?YupooResult.class);
    stream.alias(
    "photo",YupooPhoto.class);
    YupooResult?result?
    =?(YupooResult)stream.fromXML(reader);
    可是Yupoo的api返回的xmlrpc的結(jié)果是這樣的
    <result?page="1"?pages="1"?perpage="100"?total="19">
    ????
    <photos>
    ????????
    <photo?id="ff8080810fc8ac78010fd3f158d40a52"
    ????????????owner
    ="ff8080810f1a387b010f1a83d6530dfc"?title="Gmail-2"?host="4"
    ????????????dir
    ="20061230"?filename="231905_1463411198"?/>
    ????
    </photos>
    </result>
    這樣就load不到值了。沒法去mailist里面找答案,果然有人問。
    Hello,
    
    I am not sure about the subject but here is what I needed help for:
    
    XML:
    
    <field name="value">I am a Field.</field>
    
    I have already tried several structures and nothing seem to work.
    
    Is this possible for XStream? :)
    
    How is the Java class form to support this?
    
    Thanks!




    有人回答是看Converter的文檔。果然找到答案了。
    自己寫一個converter就可以了。
    下面是我的converter
    package?com.jdkcn.xstream;

    import?java.util.ArrayList;
    import?java.util.List;

    import?com.jdkcn.yupoo.YupooPhoto;
    import?com.jdkcn.yupoo.YupooResult;
    import?com.thoughtworks.xstream.converters.Converter;
    import?com.thoughtworks.xstream.converters.MarshallingContext;
    import?com.thoughtworks.xstream.converters.UnmarshallingContext;
    import?com.thoughtworks.xstream.io.HierarchicalStreamReader;
    import?com.thoughtworks.xstream.io.HierarchicalStreamWriter;

    /**
    ?*?
    @author?<a?href="mailto:rory.cn@gmail.com">somebody</a>
    ?*?
    @since?Jan?16,?2007?6:12:35?PM
    ?*?
    @version?$Id?YupooResultConverter.java$
    ?
    */
    public?class?YupooResultConverter?implements?Converter?{
    ????
    /*?(non-Javadoc)
    ?????*?@see?com.thoughtworks.xstream.converters.Converter#marshal(java.lang.Object,?com.thoughtworks.xstream.io.HierarchicalStreamWriter,?com.thoughtworks.xstream.converters.MarshallingContext)
    ?????
    */
    ????
    public?void?marshal(Object?obj,?HierarchicalStreamWriter?writer,?MarshallingContext?context)?{
    ????????
    //?FIXME?unfinish.
    ????}

    ????
    /*?(non-Javadoc)
    ?????*?@see?com.thoughtworks.xstream.converters.Converter#unmarshal(com.thoughtworks.xstream.io.HierarchicalStreamReader,?com.thoughtworks.xstream.converters.UnmarshallingContext)
    ?????
    */
    ????
    public?Object?unmarshal(HierarchicalStreamReader?reader,?UnmarshallingContext?context)?{
    ????????YupooResult?result?
    =?new?YupooResult();
    ????????result.setPage(
    new?Integer(reader.getAttribute("page")));
    ????????result.setPages(
    new?Integer(reader.getAttribute("pages")));
    ????????result.setPerpage(
    new?Integer(reader.getAttribute("perpage")));
    ????????result.setTotal(
    new?Integer(reader.getAttribute("total")));
    ????????reader.moveDown();
    ????????List
    <YupooPhoto>?photos?=?new?ArrayList<YupooPhoto>();
    ????????
    while(reader.hasMoreChildren())?{
    ????????????reader.moveDown();
    ????????????YupooPhoto?photo?
    =?new?YupooPhoto();
    ????????????photo.setDir(reader.getAttribute(
    "dir"));
    ????????????photo.setFilename(reader.getAttribute(
    "filename"));
    ????????????photo.setHost(reader.getAttribute(
    "host"));
    ????????????photo.setId(reader.getAttribute(
    "id"));
    ????????????photo.setOwner(reader.getAttribute(
    "owner"));
    ????????????photo.setTitle(reader.getAttribute(
    "title"));
    ????????????photos.add(photo);
    ????????????reader.moveUp();
    ????????}
    ????????result.setPhotos(photos);
    ????????
    return?result;
    ????}
    ????
    /*?(non-Javadoc)
    ?????*?@see?com.thoughtworks.xstream.converters.ConverterMatcher#canConvert(java.lang.Class)
    ?????
    */
    ????
    public?boolean?canConvert(Class?clazz)?{
    ????????
    return?clazz.equals(YupooResult.class);
    ????}
    }

    然后調(diào)用的地方修改一下就ok了。
    XStream?stream?=?new?XStream();
    stream.registerConverter(
    new?YupooResultConverter());
    stream.alias(
    "result",?YupooResult.class);



    參考:
    http://xstream.codehaus.org/converter-tutorial.html

    2007年1月18日更新。
    這里感謝網(wǎng)友 Ivan Chen(西濱)?的提示。原來新版的xstream可以簡單的解決了。在1.2.1的doc里面找到了這個兩個方法。

    useAttributeFor

    public void useAttributeFor(java.lang.String?fieldName,
                                java.lang.Class?type)
    Use an XML attribute for a field or a specific type.

    Parameters:
    fieldName - the name of the field
    type - the Class of the type to be rendered as XML attribute
    Throws:
    XStream.InitializationException - if no AttributeMapper is available
    Since:
    1.2

    useAttributeFor

    public void useAttributeFor(java.lang.Class?type)
    Use an XML attribute for an arbotrary type.

    Parameters:
    type - the Class of the type to be rendered as XML attribute
    Throws:
    XStream.InitializationException - if no AttributeMapper is available
    Since:
    1.2

    這兩個方法都是從1.2開始支持的。
    也不用自己寫converter了。這樣就可以了
    ????????stream.alias("result",?YupooResult.class);
    ????????stream.useAttributeFor(
    "page",?Integer.class);
    ????????stream.useAttributeFor(
    "pages",?Integer.class);
    ????????stream.useAttributeFor(
    "perpage",?Integer.class);
    ????????stream.useAttributeFor(
    "total",?Integer.class);
    ????????stream.alias(
    "photo",?YupooPhoto.class);
    ????????stream.useAttributeFor(
    "id",?String.class);
    ????????stream.useAttributeFor(
    "owner",?String.class);
    ????????stream.useAttributeFor(
    "title",?String.class);
    ????????stream.useAttributeFor(
    "host",?String.class);
    ????????stream.useAttributeFor(
    "dir",?String.class);
    ????????stream.useAttributeFor(
    "filename",?String.class);

    創(chuàng)造共用協(xié)議:署名,非商業(yè),保持一致
    ?? 除經(jīng)特別注明外,本文章版權(quán)歸莫多泡泡所有.
    署名,非商業(yè)用途,保持一致.???somebody(莫多)
    posted @ 2007-01-17 18:24 莫多 閱讀(8011) | 評論 (2)編輯 收藏

    ? 上周更新了一下myblog,添加了一個Filter,做統(tǒng)計訪問用??墒呛髞戆l(fā)現(xiàn)出現(xiàn)亂碼問題了。找了很久都沒有找到問題。debug的時候看到 CharacterEncodingFilter確實是執(zhí)行了。不過就是沒有效果。執(zhí)行之前是ISO-8859-1編碼的,執(zhí)行之后還是, CharacterEncodingFilter就沒有起到作用。后來終于找到問題的原因了。原來是Filter配置先后順序的原因。
    ?????? 剛開始的配置是這樣的:

    ???? < filter-mapping >
    ????????
    < filter-name > requestCounterFilter </ filter-name >
    ????????
    < url-pattern > *.jhtml </ url-pattern >
    ????
    </ filter-mapping >
    ??
    ????
    < filter-mapping >
    ????????
    < filter-name > encodingFilter </ filter-name >
    ????????
    < url-pattern > /dwr/* </ url-pattern >
    ????
    </ filter-mapping >
    ????
    ????
    < filter-mapping >
    ????????
    < filter-name > encodingFilter </ filter-name >
    ????????
    < url-pattern > *.jhtml </ url-pattern >
    ????
    </ filter-mapping >
    ????
    ????
    < filter-mapping >
    ????????
    < filter-name > encodingFilter </ filter-name >
    ????????
    < url-pattern > *.jsp </ url-pattern >
    ????
    </ filter-mapping >

    ? 先經(jīng)過那個統(tǒng)計的filter然后再經(jīng)過編碼的filter。這樣的話編碼的filter就不起作用了。只要吧編碼的filter放到最前面就沒有問題了。改成這樣就好。

    ???? < filter-mapping >
    ????????
    < filter-name > encodingFilter </ filter-name >
    ????????
    < url-pattern > /dwr/* </ url-pattern >
    ????
    </ filter-mapping >
    ????
    ????
    < filter-mapping >
    ????????
    < filter-name > encodingFilter </ filter-name >
    ????????
    < url-pattern > *.jhtml </ url-pattern >
    ????
    </ filter-mapping >
    ????
    ????
    < filter-mapping >
    ????????
    < filter-name > encodingFilter </ filter-name >
    ????????
    < url-pattern > *.jsp </ url-pattern >
    ????
    </ filter-mapping >
    ????
    ????
    < filter-mapping >
    ????????
    < filter-name > requestCounterFilter </ filter-name >
    ????????
    < url-pattern > *.jhtml </ url-pattern >
    ????
    </ filter-mapping >


    以后大家一定要注意啊。順序問題也是很重要的。
    創(chuàng)造共用協(xié)議:署名,非商業(yè),保持一致?? 除經(jīng)特別注明外,本文章版權(quán)歸莫多泡泡所有.
    署名,非商業(yè)用途,保持一致.???somebody(莫多)

    posted @ 2006-12-27 10:37 莫多 閱讀(2703) | 評論 (3)編輯 收藏
    昨天晚上配置myblog的rewrite。發(fā)現(xiàn)一個奇怪的問題。由于現(xiàn)在使用的這個pjblog,為了讓搜索引擎收錄的連接有效。我想把原來的asp連接rewrite到我的新程序上面。所以有這樣一條規(guī)則。

    ????<rule>
    ????????
    <from>^/article.asp\?id=(.*)$</from>
    ????????
    <to?type="redirect">/entry/$1.jhtml</to>
    ????
    </rule>
    ???? 但是我這樣的連接總是匹配不到,只要去掉那個?就可以了。這個正則表達式是沒有問題的。/article.asp?id=64是可以匹配的到的。
    ??? 后來看3.0的manual (http://tuckey.org/urlrewrite/manual/3.0/)才發(fā)現(xiàn)原來是這個的問題。

    <urlrewrite> element

    The top level element.

    AttributePossible ValueExplanation
    default-match-type
    (optional)
    regex (default)All rules and thier conditions will be processed using the Java Regular Expression engine (unless match-type is specified on a rule).
    wildcardAll rules and thier conditions will be processed using the Wildcard Expression engine (unless match-type is specified on a rule).
    decode-using
    (optional)
    utf8 (default)When URL is decoded UTF-8 will be used.
    nullDo not decode.
    [encoding]Any string representing a supported character encoding eg, ISO-8859-1. See Java Charset Object for more info.
    use-query-string
    (optional)
    false (default)The query string will not be appended to the url that the "from" element matches against.
    trueThe query string will be appended to the url that the "from" element matches against.
    use-context
    (optional)
    false (default)The context path will not be added to the url that the "from" element matches against.
    trueThe context path will be added to the url that the "from" element matches against.

    就是那個use-query-string 的問題,默認的是不使用query-string就是把?后面的都忽略了。所以就不能匹配到了。只要在<urlrewrite>里面加一個屬性就可以了。
    <urlrewrite?use-query-string="true">
    ????
    </urlrewrite>

    創(chuàng)造共用協(xié)議:署名,非商業(yè),保持一致?? 除經(jīng)特別注明外,本文章版權(quán)歸莫多泡泡所有.
    署名,非商業(yè)用途,保持一致.???somebody(莫多)

    posted @ 2006-12-12 10:33 莫多 閱讀(2358) | 評論 (0)編輯 收藏

    ??????我們的項目用到了xmlrpc,不過還是用的2.x版本的。由于xmlrpc3.x地推出。提供了NULL,Serializable等的支持,將原來的Hashtable改成了Map,Vector改成了List。都是不錯的進步。所以我們決定從xmlrpc2.x升級到xmlrpc3.x.
    ??????在spring里面有幾個ServiceExporter,org.springframework.remoting.rmi.RmiServiceExporter、org.springframework.remoting.caucho.HessianServiceExporter、org.springframework.remoting.caucho.BurlapServiceExporter。不過沒有xmlrpc的serviceExporter,原來我們是自己封裝的XmlRpcServer,用servlet提供服務(wù)。(eg:http://localhost:8080/community/service/xmlrpc)沒有和spring集成雖然用了spring。
    ??? 考慮到spring的便利以及配置的同意我決定將xmlrpcService放入spring中。xmlrpc3.x和xmlrpc2.x的代碼基本上沒有一樣的。改了很多東西。除了類型變化之外,還添加了對異常的支持。詳細信息請參照xmlrpc3.x源代碼。
    XmlRpcServiceExporter.java

    package ?com.jdkcn.xmlrpc;

    import ?javax.servlet.ServletException;

    /**
    ?*?
    @author ?<a?href="mailto:rory.cn@gmail.com">somebody</a>
    ?*?
    @since ?2006-9-27?03:59:22?pm
    ?*?
    @version ?$Id?XmlRpcServiceExporter.java$
    ?
    */
    public ? class ?XmlRpcServiceExporter? extends ?RemoteExporter? implements
    ????????Controller,?InitializingBean?{
    ????
    ????
    private ?XmlRpcServletServer?server;
    ????
    ????
    public ?String?serviceName;
    ????
    ????
    public ?Resource?configFile;
    ????
    ????
    public ?Boolean?enabledForExtensions;
    ????
    ????
    public ? void ?setEnabledForExtensions(Boolean?enabledForExtensions)?{
    ????????
    this .enabledForExtensions? = ?enabledForExtensions;
    ????}

    ????
    public ? void ?setConfigFile(Resource?configFile)?{
    ????????
    this .configFile? = ?configFile;
    ????}

    ????
    public ?String?getServiceName()?{
    ????????
    return ?serviceName;
    ????}

    ????
    public ? void ?setServiceName(String?serviceName)?{
    ????????
    this .serviceName? = ?serviceName;
    ????}

    ????
    public ?XmlRpcServletServer?getXmlRpcServletServer()?{
    ????????
    return ?server;
    ????}
    ????
    ????
    /* ?(non-Javadoc)
    ?????*?@see?org.springframework.web.servlet.mvc.Controller#handleRequest(javax.servlet.http.HttpServletRequest,?javax.servlet.http.HttpServletResponse)
    ?????
    */
    ????
    public ?ModelAndView?handleRequest(HttpServletRequest?request,
    ????????????HttpServletResponse?response)?
    throws ?Exception?{
    ????????
    if ?( ! WebContentGenerator.METHOD_POST.equals(request.getMethod()))?{
    ????????????
    throw ? new ?ServletException( " XmlRpcServiceExporter?only?supports?POST?requests " );
    ????????}
    ????????server.execute(request,?response);
    ????????
    return ? null ;
    ????}

    ????
    /* ?(non-Javadoc)
    ?????*?@see?org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
    ?????
    */
    ????
    public ? void ?afterPropertiesSet()? throws ?Exception?{
    ????????server?
    = ? new ?XmlRpcServletServer();
    ????????server.setHandlerMapping(newXmlRpcHandlerMapping());
    ????????
    if ?(enabledForExtensions != null )?{
    ????????????((XmlRpcServerConfigImpl)?server.getConfig()).setEnabledForExtensions(enabledForExtensions.booleanValue());
    ????????}
    ????????
    ????}

    ????
    /** ?Creates?a?new?handler?mapping.?The?default?implementation?loads
    ?????*?a?property?file?from?the?resource
    ?????*?
    ?????
    */
    ????
    protected ?XmlRpcHandlerMapping?newXmlRpcHandlerMapping()? throws ?XmlRpcException?{
    ????????
    ????????SpringHandlerMapping?mapping?
    = ? new ?SpringHandlerMapping(getServiceInterface());
    ????????mapping.addHandler(getServiceName(),?getServiceInterface());
    ????????mapping.setTagetObject(getProxyForService());
    ????????
    return ?mapping;
    ????}
    ????
    }

    spring配置文件
    ????<bean?id="accountService"??class="com.jdkcn.service.impl.AccountServiceImpl">
    ????
    </bean>
    ????????
    <bean?name="rpcAccountService"?class="com.jdkcn.xmlrpc.XmlRpcServiceExporter">
    ????????
    <property?name="service">
    ????????????
    <ref?bean="accountService"/>
    ????????
    </property>
    ????????
    <property?name="serviceName">
    ????????????
    <value>jdkcn.accountService</value>
    ????????
    </property>
    ????????
    <property?name="enabledForExtensions">
    ????????????
    <value>true</value>
    ????????
    </property>
    ????????
    <property?name="serviceInterface">
    ????????????
    <value>com.jdkcn.service.AccountService</value>
    ????????
    </property>
    ????
    </bean>
    然后映射一個地址就可以通過xmlrpc訪問服務(wù)了
    ????<bean?id="urlMapping"?class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    ????????
    <property?name="mappings">
    ????????????
    <props>?
    ????????????????
    <prop?key="/account">rpcAccountService</prop>
    ????????????
    </props>
    ????????
    </property>
    ????
    </bean>
    web.xml
    ????<context-param>
    ????????
    <param-name>contextConfigLocation</param-name>
    ????????
    <param-value>
    ????????????classpath:spring/global.xml
    ????????
    </param-value>
    ????
    </context-param>
    ????
    ????
    <listener>
    ????????
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    ????
    </listener>

    ????????
    <servlet>
    ????????????
    <servlet-name>service</servlet-name>
    ????????????
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    ????????
    </servlet>

    ????????
    <servlet-mapping>
    ????????????
    <servlet-name>service</servlet-name>
    ????????????
    <url-pattern>/service/xmlrpc3/*</url-pattern>
    ????????
    </servlet-mapping>
    然后我們的service地址就是這樣的http://localhost:8080/service/xmlrpc3/account

    希望對大家有用,這里提供project下載。包含一個client程序。com.jdkcn.xmlrpc.Client

    點擊下載完整代碼

    創(chuàng)造共用協(xié)議:署名,非商業(yè),保持一致?? 除經(jīng)特別注明外,本文章版權(quán)歸莫多泡泡所有.
    署名,非商業(yè)用途,保持一致.???somebody(莫多)
    posted @ 2006-10-22 16:12 莫多 閱讀(2193) | 評論 (0)編輯 收藏
    不知道大家有沒有碰到,還是沒有這種需求。就是用like來查詢,我們沒有用Lucene,Compass這種全文索引的方案,我們只是簡單的添加%進行l(wèi)ike查詢。用戶搜索的時候就使用*和?來代表任意和一個。所以要對"%"和"_"進行轉(zhuǎn)義,我們使用的是oracle數(shù)據(jù)庫。sql語句看起來可能是這樣的。
    SELECT?*?FROM?t_user?where?nickname?like?'%Goo\_D'?escape?'\'
    這里對_進行轉(zhuǎn)義了。因為用戶昵稱包含下劃線,如果不進行轉(zhuǎn)義就表示一個任意字符。有時候我們可能還需要對%進行轉(zhuǎn)義。同樣的方法在%前加\% 但是比起普通的like語句。多了一個聲明轉(zhuǎn)義符的語句。所以我們會想到這樣的語句
    DetachedCriteria?criteria?=?DetachedCriteria.forClass(User.class);
    criteria.add(Restrictions.like(
    "nickname",?user.getNickname()+"'?escape'\"));
    但是這樣是不管用的。
    接下來可能會想到使用Hibernate3的原生sql查詢,其實我們不需要這樣做。我們還是使用Criteria條件查詢。
    criteria.add(Restrictions.sqlRestriction("{alias}.nickname?like???escape'/'",?StringUtil.escapeSQLLike(user.getNickname()),?Hibernate.STRING));
    這樣Hibernate產(chǎn)生的語句就是我們想要的語句了。
    ????/**
    ?????*?轉(zhuǎn)義like語句中的
    ?????*?<code>'_'</code><code>'%'</code>
    ?????*?將<code>'?'</code>轉(zhuǎn)成sql的<code>'/_'</code>
    ?????*?將<code>'%'</code>轉(zhuǎn)成sql的<code>'/%'</code>
    ?????*?<p>
    ?????*???例如搜索<code>?aa*bb?c_d%f</code>將轉(zhuǎn)化成<br/>
    ?????*???<code>_aa%bb_c/_d/%f</code>
    ?????*?</p>
    ?????*?
    @param?likeStr
    ?????*?
    @return
    ?????*?
    @author?<a?href="http://jdkcn.com">somebody</a>
    ?????
    */
    ????
    public?static?String?escapeSQLLike(String?likeStr)?{
    ????????String?str?
    =?StringUtils.replace(likeStr,?"_",?"/_");
    ????????str?
    =?StringUtils.replace(str,?"%",????"/%");
    ????????str?
    =?StringUtils.replace(str,?"?",?"_");
    ????????str?
    =?StringUtils.replace(str,?"*",?"%");
    ????????
    return?str;
    ????}

    創(chuàng)造共用協(xié)議:署名,非商業(yè),保持一致?? 除經(jīng)特別注明外,本文章版權(quán)歸莫多泡泡所有.
    署名,非商業(yè)用途,保持一致.???somebody(莫多)
    posted @ 2006-10-16 23:29 莫多 閱讀(2504) | 評論 (1)編輯 收藏

    ? jspark 的這篇文章《開發(fā)階段eclipse下面的spring容器的啟動優(yōu)化 》講到如何加快spring的啟動速度。非常感謝jspark. 一下是引用的原文:

    ? 最近在負責(zé)一個大項目,項目組成員包括項目經(jīng)理大概10個人左右。項目技術(shù)用struts+spring+hibernate實現(xiàn)。項目的規(guī)模相對來說是比較大的,總共有10大模塊,每個大模塊又分為有十幾個、甚至幾十個小模塊。開發(fā)工具用eclipse,由于在開發(fā)階段,項目開發(fā)成員需要頻繁重啟服務(wù)器。在啟動服務(wù)器的時候,每次啟動時間總是會超過1分鐘。記得以前在做另外一個項目時,啟動時間不到5秒鐘,相差了10倍,而且項目規(guī)模是差不多的。

    ??? 從初步分析來說,應(yīng)該是hibernate解釋hbm.xml時花費時間,或者可能是spring容器啟動并解釋所有的bean配置文件。診斷了一下,發(fā)現(xiàn)1分鐘消耗的時間主要分布在hibernate解釋hbm.xml花費5秒;spring容器從啟動到解釋bean配置文件竟然花了58秒,真是太囂張了。當(dāng)時非常懷疑spring的效率問題。企圖從網(wǎng)上搜索相關(guān)資料,看看有什么優(yōu)化措施。

    ??? 首先是找到了hibernate的啟動優(yōu)化 http://www.hibernate.org/194.html? 里面的主要思想是通過將xml序列花到本地的文件里,每次讀取的時候根據(jù)情況,從本地文件讀取并反序列化,節(jié)省了hibernate xml的解析時間。按照這個方式測試了一下,發(fā)現(xiàn)hibernate的啟動時間從5秒降低到3秒,但是這個優(yōu)化對于整個啟動過程是杯水車薪的,毫無用處。

    ??? 沒辦法,又仔細查看了spring的資料,終于發(fā)現(xiàn)spring的容器是提供了lazy-load的,即默認的缺省設(shè)置是bean沒有l(wèi)azy- load,該屬性處于false狀態(tài),這樣導(dǎo)致spring在啟動過程導(dǎo)致在啟動時候,會默認加載整個對象實例圖,從初始化ACTION配置、到 service配置到dao配置、乃至到數(shù)據(jù)庫連接、事務(wù)等等。這么龐大的規(guī)模,難怪spring的啟動時間要花將近1分鐘。嘗試了一下,把beans的 default-lazy-init改為true就,再次啟動,速度從原來的55秒,降到8秒鐘??!Great!雖然是非常小一個改動,但是影響確實非常大。一個項目組10個人,假若每個人一天平均需要在eclipse下啟動測試服務(wù)器50次。那么一天項目組需要重啟500次,每次節(jié)省50秒的話,就是 25000秒,將近幾個小時,差不多一個工作日,多么可觀的數(shù)字!

    ?? 不過在運行期間第一次點頁面的時候,由于spring做了lazy-load,現(xiàn)在就需要啟動一部分需要的beans,所以稍微慢2-3秒鐘,但是明顯比等幾十秒要快很多,值得一鑒。

    ??? 以上是針對開發(fā)階段的spring容器啟動優(yōu)化,在部署到實際環(huán)境中,倒是沒必要設(shè)置為lazy-load。畢竟部署到實際環(huán)境中不是經(jīng)常的事,每次啟動1分鐘倒不是大問題。

    我這里要提醒的是不是說有的beans都能設(shè)置default-lazy-init成為true.對于scheduler的bean不能用lazy-init

    < beans? default-lazy-init ="true" >
    ????
    ????
    < bean? class ="org.springframework.scheduling.quartz.SchedulerFactoryBean" >
    ????????
    < property? name ="triggers" >
    ????????????
    < list >
    ????????????????
    < ref? bean ="buildHtmlTrigger" />
    ????????????????
    < ref? bean ="askTrigger" />
    ????????????????
    < ref? bean ="mailSenderTrigger" />
    ????????????????
    < ref? bean ="topicDetailBuildTrigger" />
    ????????????????
    < ref? bean ="forumBuildTrigger" />
    ????????????????
    < ref? bean ="topicBuildTrigger" />
    ????????????
    </ list >
    ????????
    </ property >
    ????
    </ bean >
    </ beans >




    這樣的話。所有的scheduler就都不管用了。所以請大家要注意。

    < beans >
    ????
    ????
    < bean? class ="org.springframework.scheduling.quartz.SchedulerFactoryBean" >
    ????????
    < property? name ="triggers" >
    ????????????
    < list >
    ????????????????
    < ref? bean ="buildHtmlTrigger" />
    ????????????????
    < ref? bean ="askTrigger" />
    ????????????????
    < ref? bean ="mailSenderTrigger" />
    ????????????????
    < ref? bean ="topicDetailBuildTrigger" />
    ????????????????
    < ref? bean ="forumBuildTrigger" />
    ????????????????
    < ref? bean ="topicBuildTrigger" />
    ????????????
    </ list >
    ????????
    </ property >
    ????
    </ bean >
    </ beans >


    ?

    posted @ 2006-08-10 10:59 莫多 閱讀(3333) | 評論 (2)編輯 收藏

    ???? 雖然項目全部采用了UTF-8編碼,所有的源文件*.java,*.jsc,*.html,*.ftl都采用了UTF-8編碼??墒沁€是出現(xiàn)了亂碼問題。很是不爽,后來找到了tomcat,和resin的配置。

    1. Tomcat的配置。(conf/server.xml)
      ????<!--?Define?a?non-SSL?HTTP/1.1?Connector?on?port?8080?-->
      ????
      <Connector?port="80"?maxHttpHeaderSize="8192"
      ???????????????maxThreads
      ="150"?minSpareThreads="25"?maxSpareThreads="75"
      ???????????????enableLookups
      ="false"?redirectPort="8443"?acceptCount="100"
      ???????????????connectionTimeout
      ="20000"?disableUploadTimeout="true"?URIEncoding="UTF-8"/>
    2. Resin的配置。(conf/resin.conf)

      character-encoding

      Resin 1.1
      child of: resin, server, host-default, host, web-app-default, web-app
      default: The default value is ISO-8859-1.

      Specifies the default character encoding for the environment.

      <web-app id='/'>
        <character-encoding>shift_jis</character-encoding>
        ...
      
      </web-app>
      

    ???? 這個是resin doc里面的我是在web-app-default里面加上了encoding的配置

    ???? < web-app-default >
    ??????
    < character-encoding > UTF-8 </ character-encoding >
    ??????
    ????
    </ web-app-default >

    希望對你的項目有幫助。

    創(chuàng)造共用協(xié)議:署名,非商業(yè),保持一致 ?? 除經(jīng)特別注明外,本文章版權(quán)歸莫多泡泡所有.
    署名,非商業(yè)用途,保持一致.???somebody(莫多)??

    posted @ 2006-07-22 18:13 莫多 閱讀(1860) | 評論 (4)編輯 收藏
    項目中多個項目需要同時引用一個靜態(tài)資源,所以就想到配置不同的虛擬目錄指到同一個目錄。于是有下面的配置:
    ????<!--?configures?the?default?host,?matching?any?host?name?-->
    ????
    <host?id=""?root-directory=".">
    ??????
    <!--
    ?????????-?configures?an?explicit?root?web-app?matching?the
    ?????????-?webapp's?ROOT
    ????????
    -->
    ??????
    <web-app?id="/"?document-directory="webapps/ROOT"/>
    ??????
    <web-app?id="/community/jsvm2"?document-directory="D:\\projects\\FelooComponents\\jsvm2"/>
    ??????
    <web-app?id="/passport/jsvm2"?document-directory="D:\\projects\\FelooComponents\\jsvm2"/>
    ????
    </host>

    ?????? 但是發(fā)現(xiàn)這樣只有后面一個管用(http://localhost:8080/passport/jsvm2)這個是可以,可是(http://localhost:8080/community/jsvm2)就不行,很是郁悶。只要后面的document-directory不是同一個目錄就成。
    ?????? 后來在resin的doc里面看到path的配置

    path-mapping

    child of: web-app-default, web-app

    Maps url patterns to real paths. If using a server like IIS, you may need to match the server's path aliases.

    AttributeMeaningdefault
    url-patternA pattern matching the url: /foo/*, /foo, or *.foo
    url-regexpA regular expression matching the url
    real-pathThe prefix of the real path. When used with url-regexp, allows substitution variables like $1.

    <web-app id='/'>
                <path-mapping url-pattern='/resin/*'
                real-path='e:\resin'/>
                <path-mapping url-regexp='/~([^/]*)'
                real-path='e:\home$1'/>
                </web-app>
                

    改正這樣的配置就ok了。

    ????????<web-app?id="/community"?document-directory="D:\\projects\\FelooCommunityWeb">
    ??????????
    <path-mapping?url-pattern='jsvm2/*'
    ??????????????
    real-path='D:\\projects\\FelooComponents\\jsvm2'/>
    ??????
    </web-app>
    ??????
    ????????????
    <web-app?id="/passport"?document-directory="D:\\projects\\FelooPassportWeb">
    ??????????
    <path-mapping?url-pattern='jsvm2/*'
    ??????????????
    real-path='D:\\projects\\FelooComponents\\jsvm2'/>
    ??????
    </web-app>
    創(chuàng)造共用協(xié)議:署名,非商業(yè),保持一致?? 除經(jīng)特別注明外,本文章版權(quán)歸莫多泡泡所有.
    署名,非商業(yè)用途,保持一致.???somebody(莫多)
    posted @ 2006-07-18 19:41 莫多 閱讀(2912) | 評論 (0)編輯 收藏

    自從換工作之后就沒有研究過DWR了。下載了最新的DWR2.0M2版本。2.0加了很多東西,也有不少變化的地方。最容易看到的變化就是包名的變化了,由 uk.ltd.getahead 變成了 org.directwebremoting 。
    ?????? ?換上了新的配置

    ???? < 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 >
    ????????
    < load-on-startup > 1 </ load-on-startup >
    ????
    </ servlet >

    啟動服務(wù),抱錯了。

    java.lang.IllegalArgumentException: DefaultContainer can't find a classes
    ? ? ? ?at org.directwebremoting.impl.DefaultContainer.getBean(DefaultContainer.java:216)
    ? ? ? ?at org.directwebremoting.annotations.AnnotationsConfigurator.configure(AnnotationsConfigurator.java:50)
    ? ? ? ?at org.directwebremoting.servlet.DwrServlet.init(DwrServlet.java:121)

    ????? 在DWR的Maillist里面搜索了一下,還有答案,原來DWR2.0 加入了JDK5的注釋(annotations).DwrServlet初始化的時候會去檢查注釋的類,找不到就抱錯了。如果你不用annotations也可以忽略掉這個錯誤。不過看起來總是不爽。有人提出了方案。這樣就ok了。

    ???? < 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 > classes </ param-name >
    ???????????
    < param-value > java.lang.Object </ param-value >
    ????????
    </ init-param >
    ????????
    < load-on-startup > 100 </ load-on-startup >
    ????
    </ servlet >

    創(chuàng)造共用協(xié)議:署名,非商業(yè),保持一致 ?? 除經(jīng)特別注明外,本文章版權(quán)歸莫多泡泡所有.
    署名,非商業(yè)用途,保持一致.???somebody(莫多)??

    posted @ 2006-07-17 02:11 莫多 閱讀(2890) | 評論 (0)編輯 收藏
    首先感謝JScud提供的好文章?!?a class="" title="" target="">使用FreeMarker生成Html靜態(tài)文件(實例)》
    ????? 在我們的項目中也用到了Freemarker生成靜態(tài)文件。不過這里我要說的是編碼的問題。我們的項目使用的都是UTF-8編碼,我直接使用 飛云小俠 提供的方法生成的文件在UTF-8編碼下察看是亂碼,而GBK正常(后來發(fā)現(xiàn)因為我用的中文操作系統(tǒng)所以用GBK查看正常)。
    ????? 當(dāng)然我把Freemarker的配置都改成了UTF-8,我的模版文件也是UTF-8編碼的。下面是原來的代碼
    ????public?void?setTemplatePath(Resource?templatePath)?{
    ????????
    this.templatePath?=?templatePath;
    ????????
    //設(shè)置freemarker的參數(shù)
    ????????freemarkerCfg?=?new?Configuration();
    ????????
    try?{
    ????????????freemarkerCfg.setDirectoryForTemplateLoading(
    this.templatePath.getFile());
    ????????????freemarkerCfg.setObjectWrapper(
    new?DefaultObjectWrapper());
    ????????????freemarkerCfg.setDefaultEncoding(
    "UTF-8");
    ????????}?
    catch?(IOException?ex)?{
    ????????????
    throw?new?SystemException("No?Directory?found,please?check?you?config.");
    ????????}
    ????}
    ????/**
    ?????*?生成靜態(tài)文件
    ?????*?
    @param?templateFileName?模版名稱eg:(biz/order.ftl)
    ?????*?
    @param?propMap?用于處理模板的屬性O(shè)bject映射?
    ?????*?
    @param?htmlFilePath?要生成的靜態(tài)文件的路徑,相對設(shè)置中的根路徑,例如?"/biz/2006/5/"?
    ?????*?
    @param?htmlFileName?要生成的文件名,例如?"123.htm"?
    ?????*?
    @return
    ?????
    */
    ????
    private?boolean?buildHtml(String?templateFileName,Map?propMap,?String?htmlFilePath,String?htmlFileName){
    ????????
    try?{
    ????????????Template?template?
    =?freemarkerCfg.getTemplate(templateFileName);
    ????????????template.setEncoding(
    "UTF-8");
    ????????????
    //創(chuàng)建生成文件目錄
    ????????????creatDirs(buildPath.getFilename(),htmlFilePath);
    ????????????File?htmlFile?
    =?new?File(buildPath?+?htmlFilePath?+?htmlFileName);
    ????????????Writer?out?
    =?new?BufferedWriter(new?OutputStreamWriter(new?FileOutputStream(htmlFile)));
    ????????????template.process(propMap,out);
    ????????????out.flush();
    ????????????
    return?true;
    ????????}?
    catch?(TemplateException?ex){
    ????????????log.error(
    "Build?Error"+templateFileName,ex);
    ????????????
    return?false;
    ????????}?
    catch?(IOException?e)?{
    ????????????log.error(
    "Build?Error"+templateFileName,e);
    ????????????
    return?false;
    ????????}
    ????????
    ????}
    下面是修改之后的代碼
    ????/**
    ?????*?生成靜態(tài)文件
    ?????*?
    @param?templateFileName?模版名稱eg:(biz/order.ftl)
    ?????*?
    @param?propMap?用于處理模板的屬性O(shè)bject映射?
    ?????*?
    @param?htmlFilePath?要生成的靜態(tài)文件的路徑,相對設(shè)置中的根路徑,例如?"/biz/2006/5/"?
    ?????*?
    @param?htmlFileName?要生成的文件名,例如?"123.htm"?
    ?????*?
    @return
    ?????
    */
    ????
    private?boolean?buildHtml(String?templateFileName,Map?propMap,?String?htmlFilePath,String?htmlFileName){
    ????????
    try?{
    ????????????Template?template?
    =?freemarkerCfg.getTemplate(templateFileName);
    ????????????template.setEncoding(
    "UTF-8");
    ????????????
    //創(chuàng)建生成文件目錄
    ????????????creatDirs(buildPath.getFilename(),htmlFilePath);
    ????????????File?htmlFile?
    =?new?File(buildPath?+?htmlFilePath?+?htmlFileName);
    ????????????Writer?out?
    =?new?BufferedWriter(new?OutputStreamWriter(new?FileOutputStream(htmlFile),"UTF-8"));
    ????????????template.process(propMap,out);
    ????????????out.flush();
    ????????????
    return?true;
    ????????}?
    catch?(TemplateException?ex){
    ????????????log.error(
    "Build?Error"+templateFileName,ex);
    ????????????
    return?false;
    ????????}?
    catch?(IOException?e)?{
    ????????????log.error(
    "Build?Error"+templateFileName,e);
    ????????????
    return?false;
    ????????}
    ????????
    ????}
    原因就在于OutputStreamWriter的不同構(gòu)造方法

    OutputStreamWriter(OutputStream?out)
    ??????????創(chuàng)建使用默認字符編碼的 OutputStreamWriter。
    OutputStreamWriter(OutputStream?out, String?charsetName)
    ??????????創(chuàng)建使用指定字符集的 OutputStreamWriter。

    ?
    這個是中文JDK的文檔說明,剛開始我使用默認的構(gòu)造函數(shù),所以使用了系統(tǒng)默認的編碼,GBK,所以在生成靜態(tài)文件的時候把UTF-8內(nèi)容用GBK編碼寫入了,所以在UTF-8下瀏覽就有問題。

    還有關(guān)于修改模版文件同樣也要注意這個問題。
    ????public?String?loadTemplate(String?templateName)?{
    ????????StringBuffer?sb?
    =?new?StringBuffer();
    ????????
    try?{
    ????????????File?file?
    =?new?File(templatePath+"/"+templateName);
    ????????????BufferedReader?reader?
    =?new?BufferedReader(new?InputStreamReader(new?FileInputStream(file),"UTF-8"));
    ????????????String?line?
    =?reader.readLine();
    ????????????
    while(line?!=?null)????{
    ????????????????sb.append(line);
    ????????????????sb.append(
    "\r\n");
    ????????????????line?
    =?reader.readLine();
    ????????????}
    ????????????reader.close();
    ????????}?
    catch?(IOException?e)?{
    ????????????
    throw?new?SystemException("Loading?template?Error:",e);
    ????????}
    ????????
    return?sb.toString();
    ????}
    ????public?void?saveTemplate(String?templateName,?String?templateContent)?{
    ????????
    try?{
    ????????????File?file?
    =?new?File(templatePath?+?"/"?+?templateName);
    ????????????Writer?out?
    =?new?BufferedWriter(new?OutputStreamWriter(new?FileOutputStream(file),"UTF-8"));
    ????????????out.write(templateContent);
    ????????????out.flush();
    ????????????
    //扔出templatesave事件
    ????????????TemplateSaveEvent?evt?=?new?TemplateSaveEvent();
    ????????????evt.setTemplateName(templateName);
    ????????????dispatchTemplateEvent(evt);
    ????????}?
    catch?(IOException?e)?{
    ????????????
    throw?new?SystemException("Write?template?Error",e);
    ????????}
    ????}

    posted @ 2006-06-21 10:46 莫多 閱讀(2872) | 評論 (0)編輯 收藏
    在以前的項目中對于一些資源的配置基本上都是通過spring的IOC注入一個目錄的地址字符串。而這樣的問題是,對于開發(fā)中的團隊來說還是很有問題的,因為每個可能都配置一個不同的本地目錄,而發(fā)布到服務(wù)器之后又有不同的目錄。這樣造成每個人提交了配置文件之后其他人都可能需要修改配置文件才能正確啟動服務(wù)。這確實很令人煩勞。
    ???? 最近看《Professional Java Development with the Spring Framework》時看到了spring對底層資源的抽象,才找到了完美解決方案。
    ???? 原來的代碼:
    ????private?String?templatePath;
    ????
    public?void?setTemplatePath(String?templatePath)?{
    ????????
    this.templatePath?=?templatePath;
    ????}
    ????
    public?void?initListener()?{
    ????????TemplateEventListener?templateListener?
    =?new?TemplateEventListener(){
    ????????????
    public?void?handleTemplateEvent(TemplateEventSupport?evt)?{
    ????????????????
    //?添加事件到隊列中
    ????????????????queue.offer(evt);
    ????????????????
    if(log.isDebugEnabled()){
    ????????????????????log.debug(
    "Add?Template?about:"?+?evt.getTemplateName());
    ????????????????}
    ????????????}
    ????????????
    ????????};
    ????????
    ????????
    //注冊模版監(jiān)聽事件
    ????????templateManager.addEventListener(Constants.TEMPLATE_SAVE_EVENT,?templateListener,false);
    ????????
    ????????
    ????????
    //設(shè)置freemarker的參數(shù)
    ????????freemarkerCfg?=?new?Configuration();
    ????????
    try?{
    ????????????freemarkerCfg.setDirectoryForTemplateLoading(
    new?File(templatePath));
    ????????????freemarkerCfg.setObjectWrapper(
    new?DefaultObjectWrapper());
    ????????????freemarkerCfg.setDefaultEncoding(
    "UTF-8");
    ????????}?
    catch?(IOException?ex)?{
    ????????????
    throw?new?SystemException("No?Directory?found,please?check?you?config.");
    ????????}
    ????}
    配置文件

    ????
    <bean?id="buildHtmlService"?class="cn.jdk.leaf.service.impl.BuildHtmlServiceImpl"?init-method="initListener">
    ????????
    <property?name="templatePath"><value>${templatePath}</value></property>
    ????
    </bean>
    templatePath.path=D:/template
    使用spring對底層資源的抽象只要把templatePath改成Resource就可以了
    ????private?Resource?templatePath;
    ????
    public?void?setTemplatePath(Resource?templatePath)?{
    ????????
    this.templatePath?=?templatePath;
    ????}
    ????
    public?void?initListener()?{
    ????????????TemplateEventListener?templateListener?
    =?new?TemplateEventListener(){
    ????????????
    public?void?handleTemplateEvent(TemplateEventSupport?evt)?{
    ????????????????
    //?添加事件到隊列中
    ????????????????queue.offer(evt);
    ????????????????
    if(log.isDebugEnabled()){
    ????????????????????log.debug(
    "Add?Template?about:"?+?evt.getTemplateName());
    ????????????????}
    ????????????}
    ????????????
    ????????};????
    ????????
    //注冊模版監(jiān)聽事件
    ????????templateManager.addEventListener(Constants.TEMPLATE_SAVE_EVENT,?templateListener,false);
    ????????
    ????????
    ????????
    //設(shè)置freemarker的參數(shù)
    ????????freemarkerCfg?=?new?Configuration();
    ????????
    try?{
    ????????????freemarkerCfg.setDirectoryForTemplateLoading(templatePath.getFile());
    ????????????freemarkerCfg.setObjectWrapper(
    new?DefaultObjectWrapper());
    ????????????freemarkerCfg.setDefaultEncoding(
    "UTF-8");
    ????????}?
    catch?(IOException?ex)?{
    ????????????
    throw?new?SystemException("No?Directory?found,please?check?you?config.");
    ????????}
    ????}
    bean的配置不變,只要修改properties文件就可以了。
    ????<bean?id="buildHtmlService"?class="cn.jdk.leaf.service.impl.BuildHtmlServiceImpl"?init-method="initListener">
    ????????
    <property?name="templatePath"><value>${templatePath}</value></property>
    ????
    </bean>
    把properties文件修改成
    templatePath.path=template
    在webcontext目錄下面建立一個template目錄就可以了。在部署到服務(wù)器的時候需要部署到一個特定的目錄只要修改這個配置文件為
    templatePath.path=file:/D:/template
    這樣就可以了。

    創(chuàng)造共用協(xié)議:署名,非商業(yè),保持一致??除經(jīng)特別注明外,本文章版權(quán)歸莫多泡泡所有.
    署名,非商業(yè)用途,保持一致.???somebody(莫多)???
    posted @ 2006-06-11 23:01 莫多 閱讀(1882) | 評論 (2)編輯 收藏
    上篇文章:《今天發(fā)現(xiàn)一個hibernate的bug,或者說一個應(yīng)該注意的地方比較合適 》里面我提到了Hibernate查詢需要注意的一個問題。今天發(fā)現(xiàn)了一個最好的解決辦法。如果大家現(xiàn)在用Hibernate,相信大家都回用到DetachedCriteria.關(guān)于DetachedCriteria查詢請查看http://dev.yesky.com/241/2033241.shtml。
    ????? DetachedCriteria給我們的Hibernate查詢帶來了很多方便,但是如果你帶上排序信息就會出現(xiàn)我的上一篇文章里面說的那種錯誤,今天發(fā)現(xiàn)一個很好的解決方法,其實也很簡單。就是先把傳入的帶Order信息的DetachedCriteria去掉order信息查詢數(shù)據(jù)總條數(shù),然后再把Order加回來查詢滿足條件的對象。通過查看Hibernate的源代碼發(fā)現(xiàn)Criteria的實現(xiàn)CriteriaImpl發(fā)現(xiàn)其實addOrder是給private List orderEntries = new ArrayList();這個List加值。這個List里面放的是OrderEntry對象。這個OrderEntry里面放了一個criteria 和 order.

    ????
    ????public?PaginationSupport?findPageByCriteria(final?DetachedCriteria?detachedCriteria,?final?int?pageSize,?final?int?startIndex)?{
    ????????
    return?(PaginationSupport)?getHibernateTemplate().execute(new?HibernateCallback()?{
    ????????????
    public?Object?doInHibernate(Session?session)?throws?HibernateException?{
    ????????????????Criteria?criteria?
    =?detachedCriteria.getExecutableCriteria(session);
    ????????????????CriteriaImpl?impl?
    =?(CriteriaImpl)?criteria;
    ????????????????List?orderEntrys?
    =?new?ArrayList();
    ????????????????
    try{
    ????????????????????Field?field?
    =?CriteriaImpl.class.getDeclaredField("orderEntries");
    ????????????????????
    //Get?orders
    ????????????????????orderEntrys?=?(List)?field.get(impl);
    ????????????????????
    //Remove?orders
    ????????????????????field.set(criteria,new?ArrayList());
    ????????????????}
    catch(Exception?ex){
    ????????????????????ex.printStackTrace();
    ????????????????????
    //TODO?xxxx
    ????????????????}
    ????????????????
    int?totalCount?=?((Integer)?criteria.setProjection(Projections.rowCount())
    ????????????????????????.uniqueResult()).intValue();
    ????????????????criteria.setProjection(
    null);
    ????????????????
    ????????????????
    try{
    ????????????????????Field?field?
    =?CriteriaImpl.class.getDeclaredField("orderEntries");
    ????????????????????
    //Add?orders?return
    ????????????????????for(int?i=0;?i<orderEntrys.size();?i++){
    ????????????????????????List?innerOrderEntries?
    =?(List)?field.get(criteria);
    ????????????????????????innerOrderEntries.add(orderEntrys.get(i));
    ????????????????????}
    ????????????????}
    catch(Exception?ex){
    ????????????????????ex.printStackTrace();
    ????????????????????
    //TODO?cccc
    ????????????????}
    ????????????????List?items?
    =?criteria.setFirstResult(startIndex).setMaxResults(pageSize).list();
    ????????????????PaginationSupport?ps?
    =?new?PaginationSupport(items,?totalCount,?pageSize,
    ????????????????????????startIndex);
    ????????????????
    return?ps;
    ????????????}
    ????????},?
    true);
    ????}
    希望大家多多交流
    posted @ 2006-05-29 23:29 莫多 閱讀(5068) | 評論 (12)編輯 收藏
    現(xiàn)在的系統(tǒng)中雖然使用了。Hibernate但是沒有使用Hibernate的關(guān)聯(lián)關(guān)系來進行數(shù)據(jù)庫操作。所有的管理操作都是單獨實現(xiàn)的。所以也不能用Criteria.add()這種方式去查詢關(guān)聯(lián)的一方。所以只能用Native SQL去查詢結(jié)果返回對象了。按照Hibernate3的reference里面說的

    16.1.?使用SQLQuery

    對原生SQL查詢執(zhí)行的控制是通過SQLQuery接口進行的,通過執(zhí)行Session.createSQLQuery()獲取這個接口。最簡單的情況下,我們可以采用以下形式:

    List cats = sess.createSQLQuery("select * from cats")
        .addEntity(Cat.class)
        .list();

    這個查詢指定了:

    • SQL查詢字符串

    • 查詢返回的實體

    這里,結(jié)果集字段名被假設(shè)為與映射文件中指明的字段名相同。對于連接了多個表的查詢,這就可能造成問題,因為可能在多個表中出現(xiàn)同樣名字的字段。下面的方法就可以避免字段名重復(fù)的問題:

    List cats = sess.createSQLQuery("select {cat.*} from cats cat")
        .addEntity("cat", Cat.class)
        .list();

    這個查詢指定了:

    • SQL查詢語句,它帶一個占位符,可以讓Hibernate使用字段的別名.

    • 查詢返回的實體,和它的SQL表的別名.

    addEntity()方法將SQL表的別名和實體類聯(lián)系起來,并且確定查詢結(jié)果集的形態(tài)。

    addJoin()方法可以被用于載入其他的實體和集合的關(guān)聯(lián).

    List cats = sess.createSQLQuery(
            "select {cat.*}, {kitten.*} from cats cat, cats kitten where kitten.mother = cat.id"
        )
        .addEntity("cat", Cat.class)
        .addJoin("kitten", "cat.kittens")
        .list();

    原生的SQL查詢可能返回一個簡單的標(biāo)量值或者一個標(biāo)量和實體的結(jié)合體。

    Double max = (Double) sess.createSQLQuery("select max(cat.weight) as maxWeight from cats cat")
            .addScalar("maxWeight", Hibernate.DOUBLE);
            .uniqueResult();

    除此之外,你還可以在你的hbm文件中描述結(jié)果集映射信息,在查詢中使用。

    List cats = sess.createSQLQuery(
            "select {cat.*}, {kitten.*} from cats cat, cats kitten where kitten.mother = cat.id"
        )
        .setResultSetMapping("catAndKitten")
        .list();

    后來我使用了命名SQL查詢方式。

    16.3.?命名SQL查詢

    可以在映射文檔中定義查詢的名字,然后就可以象調(diào)用一個命名的HQL查詢一樣直接調(diào)用命名SQL查詢.在這種情況下,我們 需要調(diào)用addEntity()方法.

    <sql-query name="persons">
        <return alias="person" class="eg.Person"/>
        SELECT person.NAME AS {person.name},
               person.AGE AS {person.age},
               person.SEX AS {person.sex}
        FROM PERSON person
        WHERE person.NAME LIKE :namePattern
    </sql-query>
    List people = sess.getNamedQuery("persons")
        .setString("namePattern", namePattern)
        .setMaxResults(50)
        .list();

    我覺得這種發(fā)式比較好。這樣寫出來的sql可以很整齊。我們的數(shù)據(jù)庫使用的是oracle,不過按照這上面的寫法發(fā)現(xiàn)sql語句有錯誤。
    后來拿到控制臺執(zhí)行也抱錯。因為原來都用sqlserver,而sqlserver都是可以的。后來發(fā)現(xiàn)是表不能有別名改成這樣就好了。
    ????????????SELECT?T_PAY.sys_id?as?{pay.sysId},
    ???????????????????T_PAY.sys_flag?
    as?{pay.sysFlag},
    ???????????????????T_PAY.sys_domain?
    as?{pay.sysDomain},
    ???????????????????T_PAY.sys_owner?
    as?{pay.sysOwner},
    ???????????????????T_PAY.sys_create_date?
    as?{pay.sysCreateDate},
    ???????????????????T_PAY.sys_update_date?
    as?{pay.sysUpdateDate},
    ???????????????????T_PAY.pay_id?
    as?{pay.payId},
    ???????????????????T_PAY.pay_name?
    as?{pay.payName},
    ???????????????????T_PAY.pay_type_id?
    as?{pay.payTypeId},
    ???????????????????T_PAY.pay_date?
    as?{pay.payDate},
    ???????????????????T_PAY.money_type_id?
    as?{pay.moneyTypeId},
    ???????????????????T_PAY.amount?
    as?{pay.amount},
    ???????????????????T_PAY.payer_id?
    as?{pay.payerId},
    ???????????????????T_PAY.payer_name?
    as?{pay.payerName},
    ???????????????????T_PAY.accept_id?
    as?{pay.acceptId},
    ???????????????????T_PAY.accept_name?
    as?{pay.acceptName},
    ???????????????????T_PAY.pay_state_id?
    as?{pay.payStateId},
    ???????????????????T_PAY.remark?
    as?{pay.remark}
    ????????????
    FROM???T_PAY
    ????????????
    JOIN???T_BIZ_PAY
    ????????????
    ON???????T_PAY.pay_id?=?T_BIZ_PAY.pay_id
    ????????????
    WHERE??T_BIZ_PAY.biz_id?=?:bizId
    ? 這里要特別的提醒一下大家千萬不要把主鍵忘了。剛開始我就忘了主鍵,后來調(diào)試了半天才找出原因來。

    這樣在sping里面用回調(diào)查詢一下就ok了。真的很方便.
    ????public?List?getPaysByBizId(final?String?bizId)?{
    ????????
    return?(List)getHibernateTemplate().execute(new?HibernateCallback(){
    ????????????
    public?Object?doInHibernate(Session?session)throws?HibernateException{
    ????????????????Query?query?
    =?session.getNamedQuery("find.pays.by.bizid");
    ????????????????query.setParameter(
    "bizId",bizId);
    ????????????????
    return?query.list();
    ????????????}
    ????????},
    true);
    ????}
    posted @ 2006-05-26 10:33 莫多 閱讀(3793) | 評論 (0)編輯 收藏
    今天把myblog用sql server部署了一下,可是發(fā)現(xiàn)分頁查詢的時候出現(xiàn)錯誤,看控制臺報錯說語句有錯,由來發(fā)現(xiàn)分頁的時候先查詢總記錄數(shù)目的那條語句出錯了
    select?count(*)?as?y0_?from?myblog_Blog?this_?inner?join?myblog_Blog_Category?categories3_?on?this_.id=categories3_.blogId?inner?join?myblog_Category?category1_?on?categories3_.categoryId=category1_.id?where?category1_.id=??order?by?this_.postTime?desc
    ????? 原來開發(fā)的時候我是用的mysql,沒有任何問題。原因就在最后面的order by 語句,sql server 在select count(*)里面不能用 order by。然后跟蹤代碼發(fā)現(xiàn):
    ????public?PaginationSupport?getBlogsByCategoryByPage(final?String?categoryId,?final?int?startIndex,?final?int?pageSize)?{
    ????????
    return?(PaginationSupport)?getHibernateTemplate().execute(new?HibernateCallback()?{
    ????????????
    public?Object?doInHibernate(Session?session)?throws?HibernateException?{
    ????????????????Criteria?criteria?
    =?session.createCriteria(Blog.class);
    ????????????????Criteria?cateCriteria?
    =?criteria.createCriteria("categories");
    ????????????????cateCriteria.add(Expression.eq(
    "id",categoryId));
    ????????????????criteria.addOrder(Order.desc(
    "postTime"));
    ????????????????
    int?totalCount?=?((Integer)?criteria.setProjection(Projections.rowCount())
    ????????????????????????.uniqueResult()).intValue();
    ????????????????criteria.setProjection(
    null);
    ????????????????
    ????????????????List?items?
    =?criteria.setFirstResult(startIndex).setMaxResults(pageSize).list();
    ????????????????List?blogs?
    =?new?ArrayList();
    ????????????????
    for(Iterator?ite?=?items.iterator();?ite.hasNext();)?{
    ????????????????????Object[]?objs?
    =?(Object[])ite.next();
    ????????????????????blogs.add(objs[
    1]);
    ????????????????}
    ????????????????PaginationSupport?ps?
    =?new?PaginationSupport(blogs,?totalCount,?pageSize,?startIndex);
    ????????????????
    return?ps;
    ????????????}
    ????????},?
    true);
    ????}
    原來問題就在Criteria.addOrder(Order.desc("postTime"));這句話的位置上面,int totalCount = ((Integer) criteria.setProjection(Projections.rowCount())
    ??????.uniqueResult()).intValue();
    這句話的時候就會生成上面那句話,如果在這之前addOrder就會出現(xiàn)問題,如果你用mysql不會出現(xiàn)問題,如果你用sql server就會報錯。解決方法就是把addOrder語句放到totalCount下面就可以了。
    ????public?PaginationSupport?getBlogsByCategoryByPage(final?String?categoryId,?final?int?startIndex,?final?int?pageSize)?{
    ????????
    return?(PaginationSupport)?getHibernateTemplate().execute(new?HibernateCallback()?{
    ????????????
    public?Object?doInHibernate(Session?session)?throws?HibernateException?{
    ????????????????Criteria?criteria?
    =?session.createCriteria(Blog.class);
    ????????????????Criteria?cateCriteria?
    =?criteria.createCriteria("categories");
    ????????????????cateCriteria.add(Expression.eq(
    "id",categoryId));
    ????????????????
    int?totalCount?=?((Integer)?criteria.setProjection(Projections.rowCount())
    ????????????????????????.uniqueResult()).intValue();
    ????????????????criteria.setProjection(
    null);
    ????????????????
    ????????????????
    /*
    ?????????????????*?Fix?a?bug?,Order?must?add?after?get?the?totalCount,
    ?????????????????*?beacuse?SqlServer?not?support?order?by?in?the?select?count(*).
    ?????????????????
    */
    ????????????????criteria.addOrder(Order.desc(
    "postTime"));
    ????????????????List?items?
    =?criteria.setFirstResult(startIndex).setMaxResults(pageSize).list();
    ????????????????List?blogs?
    =?new?ArrayList();
    ????????????????
    for(Iterator?ite?=?items.iterator();?ite.hasNext();)?{
    ????????????????????Object[]?objs?
    =?(Object[])ite.next();
    ????????????????????blogs.add(objs[
    1]);
    ????????????????}
    ????????????????PaginationSupport?ps?
    =?new?PaginationSupport(blogs,?totalCount,?pageSize,?startIndex);
    ????????????????
    return?ps;
    ????????????}
    ????????},?
    true);
    ????}

    這樣生成的sql語句就是這樣的。
    select?count(*)?as?y0_?from?myblog_Blog?this_?inner?join?myblog_Blog_Category?categories3_?on?this_.id=categories3_.blogId?inner?join?myblog_Category?category1_?on?categories3_.categoryId=category1_.id?where?category1_.id=?

    以后大家也要注意了。呵呵。
    posted @ 2006-05-21 22:49 莫多 閱讀(6451) | 評論 (4)編輯 收藏
    我們的項目比較特殊,基本上每天都要發(fā)布一次。為了不影響系統(tǒng)的正常使用,我們的做法是在下班之前把打包好的war放到服務(wù)器的一個目錄下面(eg:d:\bak)。然后用windows的計劃任務(wù)在晚上12點自動部署系統(tǒng),也就是net stop tomcat,刪除xx.war,刪除xx,然后把d:\bak\xx.war拷貝到webapps下面。然后再net start tomcat。這樣在第二天來的上班的時候就可以使用升級過的系統(tǒng)了。也不會影響其他人的使用,不需要中斷操作。
    ??? 關(guān)于項目的一個配置我的前幾篇文章我也提到過,那個upload的問題就不會發(fā)生了。還有就是關(guān)于項目開發(fā)中的一些問題。比如數(shù)據(jù)庫的連接地址,upload directory的配置等,這些在團隊中的每個人都是不一樣的,那么在發(fā)布的時候都要改成服務(wù)器上的正確配置,如果一個月部署一次這到?jīng)]有什么。但是像我們這樣每天部署就不是那么輕松了。而且如果一時不注意很容易造成配置的不正確。所以對于很多配置文件我們都有兩份。一份是用戶自己開發(fā)用的,一份是部署到服務(wù)器的配置,這樣在開發(fā)的時候團隊中的每個人都不一樣,關(guān)于服務(wù)器的配置都是一樣的,在發(fā)布的時候是用的服務(wù)器的配置而不是用開發(fā)用的配置。eg:web.xml(個人的配置)web-dest.xml 而關(guān)鍵的配置也就是下面這段。
    web.xml
    ????<context-param>
    ????????
    <param-name>contextConfigLocation</param-name>
    ????????
    <param-value>
    ????????????classpath:spring/*_context.xml,
    ????????????classpath:spring/global.xml?

    ????????
    </param-value>
    ????
    </context-param>
    web-dest.xml
    ????<context-param>
    ????????
    <param-name>contextConfigLocation</param-name>
    ????????
    <param-value>
    ????????????classpath:spring/*_context.xml,
    ????????????classpath:spring/global-dest.xml,
    ????????????classpath:spring/scheduler.xml
    ????????
    </param-value>
    ????
    </context-param>
    注意到其中不一樣的。dest里少了scheduler.xml這個主要是定時執(zhí)行的一些任務(wù),一般在開發(fā)的時候都不需要,去掉也可以提升速度,也不會出現(xiàn)那么多的log。還有就是發(fā)布的web.xml用了global-dest.xml這個是關(guān)于spring的總的配置。
    global.xml
    ????<bean?id="dataSource"?class="org.apache.commons.dbcp.BasicDataSource"?destroy-method="close">
    ????????
    <property?name="driverClassName"><value>net.sourceforge.jtds.jdbc.Driver</value></property>
    ????????
    <property?name="url">
    ????????????
    <value>jdbc:jtds:sqlserver://192.168.0.240:1433/fivefortunes;SelectMethod=cursor</value>
    ????????????
    </property>
    ????????
    <property?name="username"><value>sa</value></property>
    ????????
    <property?name="password"><value></value></property>
    ????
    </bean>
    ????
    ????
    <bean?id="dataSource2"?class="org.apache.commons.dbcp.BasicDataSource"?destroy-method="close">
    ????????
    <property?name="driverClassName"><value>net.sourceforge.jtds.jdbc.Driver</value></property>
    ????????
    <property?name="url">
    ????????????
    <value>jdbc:jtds:sqlserver://192.168.0.240:1433/outmail;SelectMethod=cursor</value>
    ????????????
    </property>
    ????????
    <property?name="username"><value>sa</value></property>
    ????????
    <property?name="password"><value></value></property>
    ????
    </bean>
    ????
    ????
    <bean?id="customDataSource"?class="org.apache.commons.dbcp.BasicDataSource"?destroy-method="close">
    ????????
    <property?name="driverClassName"><value>net.sourceforge.jtds.jdbc.Driver</value></property>
    ????????
    <property?name="url">
    ????????????
    <value>jdbc:jtds:sqlserver://192.168.0.240:1433/custom;SelectMethod=cursor</value>
    ????????????
    </property>
    ????????
    <property?name="username"><value>sa</value></property>
    ????????
    <property?name="password"><value></value></property>
    ????
    </bean>
    global-dest.xml
    ????<bean?id="dataSource"?class="org.apache.commons.dbcp.BasicDataSource"?destroy-method="close">
    ????????
    <property?name="driverClassName"><value>net.sourceforge.jtds.jdbc.Driver</value></property>
    ????????
    <property?name="url">
    ????????????
    <value>jdbc:jtds:sqlserver://192.168.0.5:1433/fivefortunes;SelectMethod=cursor</value>
    ????????????
    </property>
    ????????
    <property?name="username"><value>sa</value></property>
    ????????
    <property?name="password"><value></value></property>
    ????
    </bean>
    ????
    ????
    <bean?id="dataSource2"?class="org.apache.commons.dbcp.BasicDataSource"?destroy-method="close">
    ????????
    <property?name="driverClassName"><value>net.sourceforge.jtds.jdbc.Driver</value></property>
    ????????
    <property?name="url">
    ????????????
    <value>jdbc:jtds:sqlserver://192.168.0.5:1433/outmail;SelectMethod=cursor</value>
    ????????????
    </property>
    ????????
    <property?name="username"><value>sa</value></property>
    ????????
    <property?name="password"><value></value></property>
    ????
    </bean>
    ????
    ????
    <bean?id="customDataSource"?class="org.apache.commons.dbcp.BasicDataSource"?destroy-method="close">
    ????????
    <property?name="driverClassName"><value>net.sourceforge.jtds.jdbc.Driver</value></property>
    ????????
    <property?name="url">
    ????????????
    <value>jdbc:jtds:sqlserver://192.168.0.5:1433/custom;SelectMethod=cursor</value>
    ????????????
    </property>
    ????????
    <property?name="username"><value>sa</value></property>
    ????????
    <property?name="password"><value></value></property>
    ????
    </bean>
    還有關(guān)于一些properties文件我們采用了用ant部署的時候改名字來達到目的。
    build.xml
    ????????<move?file="${dist.dir}/mail.properties"?tofile="${dist.dir}/mail-dev.properties"?/>
    ????????
    <copy?file="${dist.dir}/mail-dest.properties"?tofile="${dist.dir}/mail.properties"?/>
    ????????
    <move?file="${dist.dir}/upload.properties"?tofile="${dist.dir}/upload-dev.properties"?/>
    ????????
    <copy?file="${dist.dir}/upload-dest.properties"?tofile="${dist.dir}/upload.properties"?/>

    這個是在war之前做的,大家眼看也就明白吧,就是把xx-dest.properties,改名成xx.propeties。在打完包之后
    ????????<move?file="${dist.dir}/mail-dev.properties"?tofile="${dist.dir}/mail.properties"?/>
    ????????
    <move?file="${dist.dir}/upload-dev.properties"?tofile="${dist.dir}/upload.properties"?/>
    這樣就達到了我們無憂的目的了。只要每天部署的時候保證程序能正常運行,ant war一下就安心部署吧。
    以上就是全部內(nèi)容,如果有什么不正確歡迎砸板磚。
    posted @ 2006-04-28 22:27 莫多 閱讀(2699) | 評論 (3)編輯 收藏
    前面一篇文章提到通過webwork的interceptor給webwork的action設(shè)置初始值,

    如何給webwork的action里的Field設(shè)置初始值

    jdev說到"為什么要放在這里,而不是放到系統(tǒng)配置文件中,然后在系統(tǒng)設(shè)置界面中提供設(shè)置",后來我就用spring來注入了?,F(xiàn)在就把值放入properties文件中了。

    ????<bean?id="propertyPlaceholderConfigurer"?class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    ??????
    <property?name="locations">
    ????????
    <list>
    ??????????
    <value>classpath:mail.properties</value>
    ??????????
    <value>classpath:upload.properties</value>
    ????????
    </list>
    ??????
    </property>
    ????
    </bean>
    ????
    <!--?收發(fā)外部郵箱?author:somebody-->
    ????
    <bean?id="outMailManager"?class="cn.com.fivefortunes.mail.manager.impl.OutMailManagerImpl">
    ????????
    <property?name="javaMailSender"><ref?bean="javaMailSender"/></property>
    ????????
    <property?name="attachementDirectory"><value>${mail.attachementDirectory}</value></property>
    ????????
    <property?name="uploadFileDirectory"><value>${upload.directory}</value></property>
    ????????
    <property?name="outMailHibernateManager"><ref?bean="outMailHibernateManager"/></property>
    ????????
    <property?name="outMailAccountManager"><ref?bean="outMailAccountManager"/></property>
    ????
    </bean>
    這樣把uploadFileDirectory放入mananger中去了。在properties里面配置一下就ok了。

    upload.directory
    =D:\\tomcat5\\webapps\\files
    mail.attachementDirectory
    =D:\\tomcat5\\webapps\\files
    上次還有網(wǎng)友這樣說到"return ServletActionContext.getServletContext().getRealPath("/");

    你這樣換了部署環(huán)境每次都要改
    而且也該是
    D://tomcat5//webapps//files"
    也許很多人都以為這是最好的方式,可是實際情況不是這樣,我們的uploadfile目錄已經(jīng)有3G的文件,而基本上每天我們都要發(fā)布新的webapp,如果把uploadfile目錄放到webapp的一個子目錄,每次部署的時候都要先把uploadfile copy出來然后再部署。所以我們這么做就是把upload目錄放到其他目錄不影響uploadfile目錄里面的文件。關(guān)于我們項目的部署見我的下一篇文章。謝謝大家。如果您有什么更好的方法請您指教。
    posted @ 2006-04-22 11:21 莫多 閱讀(1195) | 評論 (0)編輯 收藏
    剛才在tss上看到Joe發(fā)布的消息,DWR允許異步調(diào)用Javascript了。DWR 2.0 builds on this to allow you to asynchronously call Javascript code from Java. Reverse Ajax makes writing interactive applications much easier.
    值得去看看。
    posted @ 2006-04-12 09:23 莫多 閱讀(322) | 評論 (0)編輯 收藏
    Rss,Atom,基本上是Web2.0的基本特征,今天終于有時間決定實現(xiàn)一下。對于動態(tài)的Rss,Atom其實就是選取最新的內(nèi)容,迭迨一下生成一個固定格式的xml文件就可以了。其實也很簡單。
    ?????? 我用webwork2,用freemarker做模版,在網(wǎng)上找了一個標(biāo)準(zhǔn)的Rss2.0格式就生成我的模版文件rss.ftl
    <?xml?version="1.0"?encoding="UTF-8"?>
    <rss?version="2.0">
    <channel>
    <title><![CDATA[我的小站]]></title>
    <link>http://leaf.jdk.cn/</link>
    <description><![CDATA[泡出好心情,泡出好技術(shù)]]></description>
    <language>zh-cn</language>
    <copyright><![CDATA[Copyright?2006?PaoPao?v4.0]]></copyright>
    <webMaster><![CDATA[rory.cn@gmail.com?(Rory?Ye)]]></webMaster>
    <generator>PaoPao?v4.0</generator>?
    ????
    <image>
    ????????
    <title>我的小站</title>?
    ????????
    <url>http://leaf.jdk.cn/logo.gif</url>?
    ????????
    <link>http://leaf.jdk.cn</link>?
    ????????
    <description>莫多泡泡2006</description>?
    ????
    </image>
    ????
    <#list?blogs?as?blog>
    ????
    <item>
    ????????
    <link>http://leaf.jdk.cn/entry.action?entryId=${blog.id}</link>
    ????????
    <title><![CDATA[${blog.title}]]></title>
    ????????
    <author>${blog.authorMail}(${blog.author})</author>
    ????????
    <category><![CDATA[?${blog.categories}?]]></category>
    ????????
    <pubDate>${blog.pubDate}</pubDate>
    ????????
    <guid>http://leaf.jdk.cn/entry.action?id=${blog.id}</guid>????
    ????????
    <description><![CDATA[${blog.content}]]></description>
    ????
    </item>
    ????
    </#list>
    </channel>
    </rss>
    我在rss.action里面去取blogs就可以了。
    ????public?String?execute()?throws?Exception?{
    ????????PaginationSupport?ps?
    =?blogManager.getBlogsByPage(0);
    ????????blogs?
    =?new?ArrayList();
    ????????
    ????????
    for(Iterator?ite?=?ps.getItems().iterator();?ite.hasNext();){
    ????????????Blog?blog?
    =?(Blog)ite.next();
    ????????????WrapRssBlog?wrapBlog?
    =?new?WrapRssBlog();
    ????????????wrapBlog.setId(blog.getId());
    ????????????wrapBlog.setAuthor(blog.getAuthor().getNickname());
    ????????????wrapBlog.setAuthorMail(blog.getAuthor().getMail());
    ????????????wrapBlog.setTitle(blog.getTitle());
    ????????????wrapBlog.setContent(StringUtil.extractText(blog.getContent()));
    ????????????wrapBlog.setPubDate(DateUtil.formatRssDate(blog.getPostTime()));
    ????????????StringBuffer?sb?
    =?new?StringBuffer();
    ????????????
    for(Iterator?ite2?=?blog.getCategories().iterator();?ite2.hasNext();){
    ????????????????Category?cate?
    =?(Category)?ite2.next();
    ????????????????sb.append(
    "?")
    ??????????????????.append(cate.getName());
    ????????????}
    ????????????wrapBlog.setCategories(sb.toString());
    ????????????blogs.add(wrapBlog);
    ????????}
    ????????
    return?super.execute();
    ????}
    這里把blog包裝了一下,主要是處理了一下日期,內(nèi)容,還有把分類拼成字符串。關(guān)于日期的處理,參考了飛云小俠寫的rss日期的研究。實現(xiàn)代碼如下。
    ????public?static?String?formatRssDate(Date?date){
    ????????SimpleDateFormat?sdf?
    =?new?SimpleDateFormat("EEE,?d?MMM?yyyy?HH:mm:ss?z",Locale.US);
    ????????
    //TODO?TimeZone
    ????????SimpleTimeZone?zone?=?new?SimpleTimeZone(8,"GMT");
    ????????sdf.setTimeZone(zone);
    ????????
    return?sdf.format(date);
    ????}
    這樣就得到了這樣的日期
    Thu, 6 Apr 2006 16:01:36 GMT
    做好了這些,配置一下action
    ????????<action?name="rss"?class="cn.jdk.leaf.action.RssAction">????????
    ????????????
    <result?name="success"?type="freemarker">/WEB-INF/pages/rss.ftl</result>
    ????????
    </action>
    不過像這樣配置的話,你訪問http://xxx.xxx.com/rss.action看到的不是一個xml
    因為返回結(jié)果的contentType是text/html.而不是xml,這樣是不行的。看了一下webwork源碼。原來可以這樣簡單的解決。改成這樣配置就可以了。
    ????????<action?name="rss"?class="cn.jdk.leaf.action.RssAction">
    ????????????
    <result?name="success"?type="freemarker">
    ????????????????
    <param?name="location">/WEB-INF/pages/rss.ftl</param>
    ????????????????
    <param?name="contentType">application/xml</param>
    ????????????
    </result>
    ????????
    </action>

    簡單吧。其實你還可以把這個contentType改成其他類型的。比如excle的。這樣用戶執(zhí)行就可以得到一個xls文件。哈哈。
    posted @ 2006-04-10 22:40 莫多 閱讀(1350) | 評論 (2)編輯 收藏
    以前一直都沒有試過,前幾天打算把wordpress換成自己寫的程序,就想到了數(shù)據(jù)的導(dǎo)入和導(dǎo)出,首先想到的是用數(shù)據(jù)庫工具來導(dǎo)。可是覺得有些麻煩,我自己的程序是用spring+hibernate的。后來我就試了一下spring的JdbcTemplate,就和HibernateTemplate一樣的好用。首先增加一個連接到wp數(shù)據(jù)庫的dataSource
    ????<bean?id="dataSource2"?class="org.springframework.jdbc.datasource.DriverManagerDataSource"?destroy-method="close">
    ????????
    <property?name="driverClassName"><value>org.hibernate.dialect.MySQLDialect</value></property>
    ????????
    <property?name="url">
    ????????????
    <value>jdbc:mysql://192.168.0.240:3306/wordpressωuseUnicode=true&amp;characterEncoding=utf8</value>
    ????????????
    </property>
    ????????
    <property?name="username"><value>root</value></property>
    ????????
    <property?name="password"><value></value></property>
    ????
    </bean>

    ??? 然后在轉(zhuǎn)換程序里面get這個dataSource,new 一個JdbcTemplate(dataSource2),這樣就ok了。很簡單吧。

    ????public?void?testCopyData()?throws?Exception{
    ????????DataSource?ds?
    =?(DataSource)applicationContext.getBean("dataSource2");
    ????????
    ????????CategoryManager?cateManager?
    =?(CategoryManager)?applicationContext.getBean("categoryManager");
    ????????
    ????????JdbcTemplate?jt?
    =?new?JdbcTemplate(ds);
    ????????System.out.println(
    "Total?posts:"+jt.queryForInt("select?count(*)?from?wp_posts"));
    ????????assertNotNull(ds);
    ????????
    ????????List?cates?
    =?jt.queryForList("select?*?from?wp_categories");
    ????????
    int?i=?0;
    ????????
    for(Iterator?ite?=?cates.iterator();?ite.hasNext();){
    ????????????i
    ++;
    ????????????Map?result?
    =?(Map)?ite.next();
    ????????????Category?cate?
    =?new?Category();
    ????????????cate.setName((String)result.get(
    "cat_name"));
    ????????????cate.setOrder(i);
    ????????????
    if(i==1)
    ????????????????cate.setDefaultCategory(
    true);
    ????????????cateManager.saveCategory(cate);
    ????????????System.out.println(
    "cat_name:"+result.get("cat_name")+"\n");
    ????????}
    ????}
    posted @ 2006-04-07 00:03 莫多 閱讀(3598) | 評論 (7)編輯 收藏
    只是自己的想法,不對不要扔雞蛋哦。

    今天突發(fā)奇想的實現(xiàn)一個小小的cache。把分類categories放入map中,cache起來。
    ????private?void?cache()?{
    ????????
    if(log.isDebugEnabled()){
    ????????????log.debug(
    "Starting?cache?the?categories");
    ????????}
    ????????cacheCategoryMap?
    =?new?HashMap();
    ????????cacheCategoryMap.put(
    "categories",categoryDao.getCategories());
    ????}

    然后我想在interceptor里面把categories寫到ognlvaluestack里面這樣我在ftl里面就可以<#list categories>....</#list>了。因為這個是在每個頁面的header.ftl里面的。我也就不需要再每個action里面去get一下了。
    剛開始我implements Interceptor

    ????????final?OgnlValueStack?stack?=?ActionContext.getContext().getValueStack();
    ????????stack.setValue(
    "categories"?,categoryManager.getCategories());
    ????????
    return?invocation.invoke();
    可是這樣也不可以。后來我想到是不是action執(zhí)行完畢之后就把stack中的這個值清空了我又用了。AroundInterceptor 我想在after里面去設(shè)置不就可以了。
    ????protected?void?after(ActionInvocation?dispatcher,?String?result)?throws?Exception?{
    ????????
    final?OgnlValueStack?stack?=?ActionContext.getContext().getValueStack();
    ????????stack.setValue(
    "categories"?,categoryManager.getCategories());
    ????}
    可是這樣還是不可以。我暈了。我想是不是要在action里面聲明一下categories。
    ????private?List?categories;

    ????
    public?List?getCategories()?{
    ????????
    return?categories;
    ????}


    ????
    public?void?setCategories(List?categories)?{
    ????????
    this.categories?=?categories;
    ????}

    然后在before里面去get就可以了。
    ????protected?void?before(ActionInvocation?invocation)?throws?Exception?{
    ????????
    final?OgnlValueStack?stack?=?ActionContext.getContext().getValueStack();
    ????????stack.setValue(
    "categories"?,categoryManager.getCategories());
    ????}

    總算實現(xiàn)了。不過還要在每個action里面聲明一下categories,這樣還是很不好的。剛才有人建議用filter。我在試試吧.


    http://leaf.jdk.cn/index.php/archives/91
    posted @ 2006-03-21 11:37 莫多 閱讀(1139) | 評論 (0)編輯 收藏

    http://wiki.caucho.com
    真是不好意思。我去注冊了一下??赡苁侵形年欠Q的問題吧。
    nickname我用了。中文。

    它是用的MediaWiki

    http://leaf.jdk.cn/index.php/archives/82

    posted @ 2006-03-21 10:48 莫多 閱讀(303) | 評論 (0)編輯 收藏
    前兩天在做javamail的時候發(fā)現(xiàn)原來的上傳的action把上傳文件的路徑寫在action里面了。那個目錄是服務(wù)器上的地址,真bad smell。我就想把它改成可以配置的。我給uploadaction添加了一個string 的字段uploadDirectory。在action的配置文件里面給設(shè)置了初始值。
            <action name="fileupload" class="cn.com.fivefortunes.upload.FileUpload">
                
    <param name="uploadDirectory">D:\tomcat5\webapps\files</param> <!–D:\temp –>
                
    <result name="success" type="freemarker">/upload/upload.ftl</result>
                
    <interceptor-ref name="fileUpload"/>
                
    <interceptor-ref name="params"/>
            
    </action>

    可是這樣我還是不可以debug的時候發(fā)現(xiàn)uploadDirectory是null。不知道怎么回事情了。就到http://wiki.opensymphony.com 來search了一下,沒想到真有。
    How do I get static parameters into my action
    這個就是我的問題。原來是要加上一個inteceptor。
    <action name="fileupload" class="cn.com.fivefortunes.upload.FileUpload">
                
    <param name="uploadDirectory">D:\tomcat5\webapps\files</param><!– D:\temp –>
                
    <result name="success" type="freemarker">/upload/upload.ftl</result>
                
    <interceptor-ref name="fileUpload"/>
                
    <interceptor-ref name="params"/>
                
    <interceptor-ref name="static-params"/>
            
    </action>

    這樣就可以了。不過還是覺得不怎么爽。發(fā)布的時候還是要記得修改那個xwork的配置文件。
    posted @ 2006-03-16 15:26 莫多 閱讀(1039) | 評論 (4)編輯 收藏

    <2006年3月>
    2627281234
    567891011
    12131415161718
    19202122232425
    2627282930311
    2345678

    常用鏈接

    留言簿(1)

    隨筆分類(27)

    隨筆檔案(22)

    Friends

    搜索

    •  

    積分與排名

    • 積分 - 62542
    • 排名 - 845

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 国产在线jyzzjyzz免费麻豆| 亚洲sm另类一区二区三区| 在线视频网址免费播放| 国产午夜免费秋霞影院| 亚洲国产成人AV在线播放| 成人免费一级毛片在线播放视频| 亚洲色图.com| 久操视频在线免费观看| 亚洲乳大丰满中文字幕| 中文日本免费高清| 国产成A人亚洲精V品无码| 久久久久国产精品免费看| 亚洲AV日韩AV永久无码久久| 91人人区免费区人人| 亚洲成a人片在线网站| 一区二区无码免费视频网站 | 激情小说亚洲图片| 日本免费一区二区三区最新vr| 亚洲人av高清无码| 亚洲成网777777国产精品| 九九热久久免费视频| 亚洲成色999久久网站| 思思re热免费精品视频66| 亚洲欧美日韩综合久久久| 免费精品国产自产拍观看| h视频在线免费观看| 久久精品国产亚洲av麻豆色欲| 色影音免费色资源| 国产精品无码亚洲一区二区三区| 免费一级毛片女人图片| 在线观看片免费人成视频无码| 亚洲精品影院久久久久久| 国产精品酒店视频免费看| 怡红院免费全部视频在线视频| 亚洲毛片在线免费观看| 国产v片免费播放| 一级毛片在线免费看| 国产精品亚洲精品久久精品 | 在线毛片片免费观看| 亚洲av产在线精品亚洲第一站| 伊在人亚洲香蕉精品区麻豆|