blogjava-凯发k8网页登录

blogjava-凯发k8网页登录http://www.blogjava.net/usherlight/category/28648.html天平山上白云泉,云自无心水自闲。何必奔冲山下去,更添波浪向人间!zh-cnthu, 19 nov 2009 06:35:30 gmtthu, 19 nov 2009 06:35:30 gmt60解决struts2上传文件大小限制的方法http://www.blogjava.net/usherlight/archive/2009/11/19/302910.html云自无心水自闲云自无心水自闲thu, 19 nov 2009 05:44:00 gmthttp://www.blogjava.net/usherlight/archive/2009/11/19/302910.htmlhttp://www.blogjava.net/usherlight/comments/302910.htmlhttp://www.blogjava.net/usherlight/archive/2009/11/19/302910.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/302910.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/302910.html

        1000000
        image/gif,image/jpeg,image/jpg,image/png


但是我设置了之后并没有作用。
后来,仔细查看日志后才发现错误是commons-fileupload里面的文件大小限制引起了错误。
在struts.xml中,添加

解决问题!



云自无心水自闲 2009-11-19 13:44
]]>
extjs tree json struts2 的所有示例源代码和war文件下载http://www.blogjava.net/usherlight/archive/2009/09/01/293417.html云自无心水自闲云自无心水自闲tue, 01 sep 2009 03:07:00 gmthttp://www.blogjava.net/usherlight/archive/2009/09/01/293417.htmlhttp://www.blogjava.net/usherlight/comments/293417.htmlhttp://www.blogjava.net/usherlight/archive/2009/09/01/293417.html#feedback5http://www.blogjava.net/usherlight/comments/commentrss/293417.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/293417.htmlextjs tree json struts2中我介绍了如何异步加载一个extjs的树,但是很多网友留言说不能成功操作。现在我自己做了一个所有源代码的包,供大家下载。
有几点事项请大家注意
1、blogjava的文件上载要求单个文件不能超过4m,所以,我把web-inf目录下的所有jar文件删除了。
所有jar文件的列表是:
commons-beanutils-1.7.0.jar
commons-collections-3.2.jar
commons-digester-1.6.jar
commons-lang-2.3.jar
commons-logging-1.1.jar
dom4j-1.6.1.jar
ezmorph-1.0.4.jar
freemarker-2.3.8.jar
javassist-3.8.1.jar
json-lib-2.2.1-jdk15.jar
log4j-1.2.13.jar
ognl-2.6.11.jar
struts2-core-2.0.11.jar
xml-apis-1.0.b2.jar
xwork-2.0.4.jar
注意红色标记的那个jar文件是上次随笔中遗漏了的。这个文件是需要的。
2、blogjava要求上传文件不能是war文件,所以我把war文件改成了rar后缀。
文件的url:



云自无心水自闲 2009-09-01 11:07
]]>
struts2中的conventions插件http://www.blogjava.net/usherlight/archive/2009/08/24/292372.html云自无心水自闲云自无心水自闲mon, 24 aug 2009 06:25:00 gmthttp://www.blogjava.net/usherlight/archive/2009/08/24/292372.htmlhttp://www.blogjava.net/usherlight/comments/292372.htmlhttp://www.blogjava.net/usherlight/archive/2009/08/24/292372.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/292372.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/292372.html 假设有一个类:com.example.actions.helloworld,
struts2会自动搜索所有实现了com.opensymphony.xwork2.action接口或者在struts.xml中 指定的包下的类。
现存helloworld只是一个pojo,但是他在actions包下,这样struts2就认可这是一个action.
那么url会是什么呢?是hello-world,类似于:http://localhost:8080//hello-world.action.
如果你不喜欢这样的自动分配的url,那么可以在里面的方法使用@action来改变
@action("/helloworld")
public void execute() throws exception {
    return "success";
}

云自无心水自闲 2009-08-24 14:25
]]>
struts2中zeroconfig和codebehind下的stream类型返回http://www.blogjava.net/usherlight/archive/2009/01/06/250149.html云自无心水自闲云自无心水自闲tue, 06 jan 2009 09:30:00 gmthttp://www.blogjava.net/usherlight/archive/2009/01/06/250149.htmlhttp://www.blogjava.net/usherlight/comments/250149.htmlhttp://www.blogjava.net/usherlight/archive/2009/01/06/250149.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/250149.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/250149.html 

struts2的官方文档看似琳琅满目,但实际上并不完备,许多细节问题并没有深入涉及,部分内容甚至还有错误(可参见:http://www.blogjava.net/usherlight/archive/2008/12/30/249143.html)。这次主要是补充一下,使用了zeroconfig插件情况下,如何返回stream类型的配置。
在zeroconfig+codebehind结合使用的情况下,struts.xml中基本上已经空无一物了。配置基本上使用annotation在java的类中注释完成。

@parent("default")
@result(name="rawfile", value="inputstream", type=streamresult.class, params={"contenttype", "text/html", "inputname", "inputstream", "", "", "buffersize", "1024"})
public class filedownloadaction {
        public string execute() throws exception {
                inputstream = new fileinputstream("c:\\temp\\file.txt");               
        }
        private inputstream inputstream;

        //... getter and setter
}
这里最重要的是result里面params的写法,params后面的大括号中,奇数个字符串是key值,偶数个字符串是value值。
其中,inputname的值-inputstream要和class中的inputstream的属性名一致,而result中的value的值也要与之一致。



云自无心水自闲 2009-01-06 17:30
]]>
struts2文档中一个错误http://www.blogjava.net/usherlight/archive/2008/12/30/249143.html云自无心水自闲云自无心水自闲tue, 30 dec 2008 05:17:00 gmthttp://www.blogjava.net/usherlight/archive/2008/12/30/249143.htmlhttp://www.blogjava.net/usherlight/comments/249143.htmlhttp://www.blogjava.net/usherlight/archive/2008/12/30/249143.html#feedback3http://www.blogjava.net/usherlight/comments/commentrss/249143.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/249143.html的href,结果页面根本不能正确显示,后台log里面出现了一大片的错误,大意是的用法错误。但是我的写法是完全copy在线文档http://struts.apache.org/2.x/docs/a.html
具体内容就是下面这一部分:
"testurlid" namespace="/subscriber" action="customfield" method="delete">
"customfielddefinition.id" value="${id}"/>

经过尝试发现实际上应该这样写: "customfielddefinition.id" value="id"/>
struts2的文档一直被大家所指责,看来这种指责不无道理啊

云自无心水自闲 2008-12-30 13:17
]]>
freemarker中通过struts2标签直接调用java类获得结果值http://www.blogjava.net/usherlight/archive/2008/11/21/241781.html云自无心水自闲云自无心水自闲thu, 20 nov 2008 23:59:00 gmthttp://www.blogjava.net/usherlight/archive/2008/11/21/241781.htmlhttp://www.blogjava.net/usherlight/comments/241781.htmlhttp://www.blogjava.net/usherlight/archive/2008/11/21/241781.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/241781.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/241781.html <@s.set name="val" value="@com.test.utils.property@getinstance().get('value')"/>

然后就可以使用以下的语句在freemarker中取得val的值
<#if (request.apptype)?default("") == "ok">




云自无心水自闲 2008-11-21 07:59
]]>
struts2性能问题的最终解决方法http://www.blogjava.net/usherlight/archive/2008/09/02/226501.html云自无心水自闲云自无心水自闲tue, 02 sep 2008 13:02:00 gmthttp://www.blogjava.net/usherlight/archive/2008/09/02/226501.htmlhttp://www.blogjava.net/usherlight/comments/226501.htmlhttp://www.blogjava.net/usherlight/archive/2008/09/02/226501.html#feedback5http://www.blogjava.net/usherlight/comments/commentrss/226501.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/226501.html通过上两篇文章的研究,
详见:
我的struts2项目性能调优三步曲:http://www.blogjava.net/usherlight/archive/2008/07/01/211869.html
我的struts2项目性能调优三步曲(续):http://www.blogjava.net/usherlight/archive/2008/07/12/214462.html
得出的结论是:影响struts2性能的原因在于ognl的value stack的性能不佳。那么如果解决呢:


* 我首先尝试使用jsf。
一开始选择jsf的原因主要是:
1、stuts2自己提供了jsf的plugin
2、jsf是sun作为标准提出,而且已经通过的。从google的趋势搜索上也可以看出,搜索jsf的人在增多。
3、jsf作为一种以组件为基础的web framework有其独到之处,其内建的和其他许多开源的组件使用起来相当方便、强大。当然,对于不同的应用来说也有不利之处(后面会提到),但是如果能够坚持长期使用,逐渐积累组件库的话,jsf是一个很好的选择。
4、jsf的文档(或者说是书籍)还是比较多的。


经过测试使用后,发现其性能与struts2相比确实提升不少。但是后来遇到了一个问题,所以最后还是放弃了jsf。这个问题是关于jsf的datatable的,jsf提供的datatable其实使用起来很方便,可定制化程度也不错,只是刚好缺少了我所希望的功能(也可能是我不知道如何实现)。我的应用中的datatable是一个动态的结果集,也就是说输出的列是不能预先确定的,而datatable却要求先声明好所有的datacolumn,我不知道如何解决这个问题。所以最后放弃了jsf。


* 我的第二个选择是freemarker
选择freemarker的原因是:
1、freemarker是struts2缺少的模板引擎,struts2的标签大部分是使用freemarker的,使用freemarker的话,连plugin都省去了。
2、freemarker相对比较轻量级、因为他本身只是一个模板引擎,与jsf这样一个大而全的webframework相对,轻巧多了。
3、freemarker的学习起来非常容易,只要把他网站上的document过一遍,基本上就ok了。
4、freemarker虽然体积小,功能还是相当强的,i18n,converter之类的东西基本都全了,至少我所需要的功能全有。
5、freemarker相当灵活,他不象jsf把底层的东西封装了以后,暴露出一些属性可以设置,如果你需要的属性不能设置,你就没有办法了。在freemarker你直接操作最底层的东西,拥有很大的灵活性。当然,牺牲了一些方便性,比如,要用freemarker生成一个下拉框,就需要较多的工作量了。


测试之后,使用freemarker的性能很不错,在大数据量操作的情况下,至少一个数量级的性能提升。

主要原因是freemarker的值直接从action中取得的,所以避开了ognl的stack value.


* 我的最终结论,如果要在struts2中,展示或者操作大量数据,强烈推荐使用freemarker。




云自无心水自闲 2008-09-02 21:02
]]>
struts2 结合 dhtmlx treehttp://www.blogjava.net/usherlight/archive/2008/08/07/220756.html云自无心水自闲云自无心水自闲thu, 07 aug 2008 12:16:00 gmthttp://www.blogjava.net/usherlight/archive/2008/08/07/220756.htmlhttp://www.blogjava.net/usherlight/comments/220756.htmlhttp://www.blogjava.net/usherlight/archive/2008/08/07/220756.html#feedback2http://www.blogjava.net/usherlight/comments/commentrss/220756.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/220756.htmlhttp://dhtmlx.com
现在把struts2结合dhtmlxtree的经验心得整理一下,发表出来:
一、struts.xml

    "-//apache software foundation//dtd struts configuration 2.0//en"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
  

   
       
                /web-inf/menu.jsp
       

   




二、tree.jsp

<%@ taglib prefix="s" uri="/struts-tags"%>
<%
string 
path = request.getcontextpath();
string basepath = request.getscheme()   "://"   request.getservername()   ":"   request.getserverport()   path;
%
>
 
<html>
 
<head>
 
<title>main pagetitle>
 
 
<link rel="stylesheet" type="text/css" href="styles/dhtmlxtree.css">
<script src="scripts/dhtmlxcommon.js">script> 
<script src="scripts/dhtmlxtree.js">script>
 
head>
 
<body onload="loadtree(); " style="padding: 0; margin: 0; overflow: hidden; height: 100%;">
 
 
<script>
string.prototype._dhx_trim = function(){
    return this.replace(/
 /g," ").replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g,"");
}
 
 
/* init tree */
 var tree;
  
function loadtree(){
    tree=new dhtmlxtreeobject("doctree_box","100%","100%",0);
    tree.setimagepath("images/");    
 
    tree.setonclickhandler(
        function(id){ openpathdocs(id); }
    );
    tree.loadxml("
<%=basepath%>/menu.do"); 
 }
 
/* open path funtion */

function openpathdocs(id){
    if (tree.getuserdata(id, "thisurl") != null ){
        window.frames.sampleframe.location.href = "
<%=path%>/"   tree.getuserdata(id, "thisurl")   ".do";
        return;
    }
}
 
function autoselectnode(){
    tree.selectitem(node,true);
    tree.openitem(node);

 
script>
 
 
 
 
<table width="100%" height="100%" cellpadding="0" cellspacing="0" border="0">
    
<tr>
        
<td valign="top" width="276">
            
<div id="doctree_box" style="width: 274px; height: 100%;">div>
        
td>
        
<td width="10" background="images/grid.gif">
            
 
        
td>
        
<td align="right"> 
            
<iframe id="sampleframe" name="sampleframe" width="100%" height="99%" frameborder="0" src="blank.html" style="border: 0px solid #cecece;">iframe>
        
td>
    
tr>
table>
 
 
body>
html>
 

上面的javascript基本上是从dhtmlx的例子中修改而来,理解起来并不复杂,只有
string.prototype._dhx_trim = function(){
 return this.replace(/ /g," ").replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g,"");
}
这一段代码含义不明。


三、action

package demo;
 
public class treemenuaction {
 
    
private string menustring;
 
    
public string execute() {
        stringbuffer buf 
= new stringbuffer();
        buf.append(
""0\">");
        buf.append(
" "java\">");
        buf.append(
" "thinking in java\">");
        buf.append(
" "thisurl\">java_tij.do");
        buf.append(
" ");
        buf.append(
" "head first design pattern\">");
        buf.append(
" "thisurl\">java_hfdp.do");
        buf.append(
" ");
        buf.append(
" ");
        buf.append(
" "fiction\">");
        buf.append(
" "harry porter\">");
        buf.append(
" "thisurl\">fiction_hp.do");
        buf.append(
" ");
        buf.append(
" "oliver twist\">");
        buf.append(
" "thisurl\">fiction_ot.do");
        buf.append(
" ");
        buf.append(
" ");
        buf.append(
"");
         
        menustring 
= buf.tostring();
         
        
return "success";
    }

     
     
    
public string getmenustring() {
        
return menustring;
    }

     
     
    
public void setmenustring(string menustring) {
        
this.menustring = menustring;
    }

}

 

 
四、menu.jsp
 

<%@ page contenttype="text/xml;charset=utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>

<s:property value="menuxmlstring" escape="false"/>


过程是这样的:首先在浏览器地址栏中输入:http://......./tree.jsp
展示tree.jsp,在load函数中调用menu.do

menu.do对应treemenuaction,返回menu.jsp,而menu.jsp只包含menustring的值,注意在menu.jsp中的escape="false"

云自无心水自闲 2008-08-07 20:16
]]>
我的struts2项目性能调优三步曲(续)http://www.blogjava.net/usherlight/archive/2008/07/12/214462.html云自无心水自闲云自无心水自闲sat, 12 jul 2008 10:57:00 gmthttp://www.blogjava.net/usherlight/archive/2008/07/12/214462.htmlhttp://www.blogjava.net/usherlight/comments/214462.htmlhttp://www.blogjava.net/usherlight/archive/2008/07/12/214462.html#feedback3http://www.blogjava.net/usherlight/comments/commentrss/214462.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/214462.html最近,继续研究了struts2性能的调优方法,总结了一下,得出新三步曲:

4. 使用freemarker的最新版本2.3.13,因为在版本2.3.11中,freemarker针对性能进行了改进,以下是freemarker2.3.11的release notes:
2.3.11
date of release: 2007-12-04
this release contains several performance and usability improvements.

5. ognl2.7
所称ognl2.7相对于2.6在性能上有了“显著”的提升,于是下载了2.7以及2.7所需要的javassist-3.8.0.ga.jar

其实,经过上面2个步骤,我并没有发现应用的性能有显著的改善,可能我的页面中从valuestack中的存取操作并不是特别多,也不是特别的复杂,所以,ognl对我的影响并不明显。

6. 最后使用了jprofiler对tomcat进行了监控,最后发现问题在自定义模板上,我将页面的自定义模板全部删除,果然页面的响应速度有了较大的提升。

 



云自无心水自闲 2008-07-12 18:57
]]>
我的struts2项目性能调优三步曲http://www.blogjava.net/usherlight/archive/2008/07/01/211869.html云自无心水自闲云自无心水自闲tue, 01 jul 2008 05:33:00 gmthttp://www.blogjava.net/usherlight/archive/2008/07/01/211869.htmlhttp://www.blogjava.net/usherlight/comments/211869.htmlhttp://www.blogjava.net/usherlight/archive/2008/07/01/211869.html#feedback7http://www.blogjava.net/usherlight/comments/commentrss/211869.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/211869.html 一,根据struts2官方的性能调优说明进行了一些参数的修改。
http://struts.apache.org/2.x/docs/performance-tuning.html
http://cwiki.apache.org/ww/performance-tuning.html

turn off logging and devmode.(关闭logging和devmode)
这个当然没问题,但是全部关闭logging不现实,我只是关闭了struts2相关package的logging

do not use interceptors you do not need.
把struts.xml中不需要的interceptor统统删除

use the correct http headers (cache-control & expires).
不确定应该如何修改

copy the static content from the struts 2 jar when using the ajax theme (dojo) or the calendar tag.
关于这点,后面会提到

create a freemarker.properties file in your web-inf/classes directory.
照做

create the freemarker.properties file and add the following setting (or whatever value you deem fitting):
template_update_delay=60000
照做

enable freemarker template caching
as of struts 2.0.10, setting the property struts.freemarker.templatescache to true will enable the struts internal caching of freemarker templates. this property is set to false by default.
照做

进行上述修改后,发现页面打开的速度并没有明显的提高.

二,此时我已经基本锁定网页打开速度慢的原因与ajax(或者说是dojo)有关。因为dojo的js库大概有450k左右,先尝试使用gzip压缩javascript,减小传输量,看能否加快页面的加载速度
在tomcat的server.xml的connector中添加如下配置,激活gzip功能
 compression="on"
 compressionminsize="2048"
 nocompressionuseragents="gozilla, traviata"
 compressablemimetype="text/html,text/xml,text/javascript,application/x-javascript,application/javascript"
进行上述修改后,发现页面打开的速度还是没有明显的提高.

三,经过上述两个实验,觉得应该是struts2所封闭的dojo的性能问题了。于是引入jquery.
jquery的js文件最小是55k, gzip后应该更小,页面的响应速度明显改善(一个数量级以上的提高),主要原因在于与服务器交互的处理上极大地提升了效率。而且页面处理代码更加简洁明了。

最后,我删除了所有的(如果页面中加入,那么在struts2生成的html中后包含dojo.js),使用jquery来完成所有的ajax和javascript功能。



云自无心水自闲 2008-07-01 13:33
]]>
struts2利用stream直接输出excelhttp://www.blogjava.net/usherlight/archive/2008/06/23/210135.html云自无心水自闲云自无心水自闲mon, 23 jun 2008 12:14:00 gmthttp://www.blogjava.net/usherlight/archive/2008/06/23/210135.htmlhttp://www.blogjava.net/usherlight/comments/210135.htmlhttp://www.blogjava.net/usherlight/archive/2008/06/23/210135.html#feedback13http://www.blogjava.net/usherlight/comments/commentrss/210135.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/210135.html 

在利用网页展示查询结果,经常会遇到要求导出成excel的需求。采用这种方法可以定制输出的格式和内容(还不支持合并单元格和公式),生成真正的excel格式(不是csv)的excel。
一、struts.xml

    "-//apache software foundation//dtd struts configuration 2.0//en"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
  

   

   
       
               
                    application/vnd.ms-excel   
                    excelstream                  
                    filename="standard.xls"
                    1024
               

       

   

二、struts2的 action

package demo;
public class excelaction {
    private inputstream excelstream; // 需要生成getter和setter

    public string execute() throws exception {
        stringbuffer excelbuf = new stringbuffer();
        excelbuf.append("bookname").append("\t").append("year").append("\t").append("author").append("\n");
        excelbuf.append("thinking in java").append("\t").append("2001").append("\t").append("eckel").append("\n");
        excelbuf.append("spring in action").append("\t").append("2005").append("\t").append("rod").append("\n");
        string excelstring = excelbuf.tostring();
        logger.debug("result excel string: " excelstring);
        excelstream = new bytearrayinputstream(excelstring.getbytes(), 0, excelstring.length());
        return "excel";
    }

    // getter and setter
    ...
}

三、jsp页面

<%@ taglib prefix="s" uri="/struts-tags"%>


 
 
 

 

   
      
   

 



云自无心水自闲 2008-06-23 20:14
]]>
用freemarker做模板创建一个struts2自定义标签http://www.blogjava.net/usherlight/archive/2008/04/11/192215.html云自无心水自闲云自无心水自闲fri, 11 apr 2008 08:09:00 gmthttp://www.blogjava.net/usherlight/archive/2008/04/11/192215.htmlhttp://www.blogjava.net/usherlight/comments/192215.htmlhttp://www.blogjava.net/usherlight/archive/2008/04/11/192215.html#feedback4http://www.blogjava.net/usherlight/comments/commentrss/192215.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/192215.html 首先,在web项目的页面根目录下建立目录template
然后创建目录simple和xhtml,以上的目录名是struts2缺省使用的,不同的主题使用相应的目录。然后再创建一个components目录,在这个目录下,创建一个property.ftl。 最后的目录结构如下:
template/simple/components/property.ftl
template/xhtml/components/property.ftl

然后在property.ftl中可以使用freemarker来定义新的模板(freemarker的具体语法可以查看freemarker的官方网站,相当的详细易懂):
<#include "/${parameters.templatedir}/${parameters.theme}/controlheader.ftl" />
<@s.if test="${parameters.value} == null || ${parameters.value} == '' "> 
<@s.else><@s.property value="${parameters.value}" />
<#include "/${parameters.templatedir}/xhtml/controlfooter.ftl" />

以上是一个我自定义的模板,检测结果是否为空字符串,如果是空的话,就输出一个  这样在输出结果时表格的边框线就是完整的了。

定义好之后,在jsp页面中就可以这样使用了:


 


第一行中的目录名从自components开始,struts2会自动在template目录下去寻找,如是主题是simple, 就在simple目录下找。
另外,param的语法要注意一下,%{}里面需要加一对引号


云自无心水自闲 2008-04-11 16:09
]]>
struts2中doubleselect的使用方法http://www.blogjava.net/usherlight/archive/2008/03/27/189145.html云自无心水自闲云自无心水自闲thu, 27 mar 2008 14:08:00 gmthttp://www.blogjava.net/usherlight/archive/2008/03/27/189145.htmlhttp://www.blogjava.net/usherlight/comments/189145.htmlhttp://www.blogjava.net/usherlight/archive/2008/03/27/189145.html#feedback16http://www.blogjava.net/usherlight/comments/commentrss/189145.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/189145.html
上面的例子演示了doubleselect的基本用法,但是其list和doublelist都是固定的。尤其是doublelist的切换使用了3目运算符 ? :,并没有太大的实际使用价值。在实际应用中,list往往是action返回的一个list,listkey和listvalue来显示第一级下拉框,doublelist往往是一个map>,其中map中的key值是第一级下拉框的listkey。
举个例子:
data object:
public class book {
        
private int id;
        
private string name;
        
private int categoryid;

        
// getter and setter..
}


public class category {
        
private int id;
        
private string name;

        
// getter and setter..
}


jsp:
   doublename="bookid" doublelist="bookmap.get(top.id)" doublelistkey="id" doublelistvalue="name" theme="simple"/>

此处要注意的是top的用法,开始我以为top就是指代list的值,所以使用的是bookmap.get(top),但是二级下拉框一直是空白,后来我突然想到说不定top是一个category实例呢,尝试了一下top.id,果然成功了。

action:

public class demoaction {
        
private map<integer, list<book>> bookmap;
        
private list<category> categorylist;

        
public string execute() throws exception {
                categorylist 
= new arraylist<cateogry>();

                category category;
                category 
= new category();
                category.setid(
1);
                category.setname(
"fiction");
                categorylist.add(category);
                category 
= new category();
                category.setid(
2);
                category.setname(
"java");
                categorylist.add(category);

 

                bookmap 
= new hashmap<integer, list<book>>();

                list
<book> booklist = new arraylist<book>();
                book book;
                book 
= new book();
                book.setid(
1);
                book.setname(
"harry porter");
                book.setcategoryid(
1);
                booklist.add(book);

                book 
= new book();
                book.setid(
2);
                book.setname(
"nightmare");
                book.setcategoryid(
1);
                booklist.add(book);

                bookmap.put(
1, booklist);

 

                booklist 
= new arraylist<book>();
                book 
= new book();
                book.setid(
3);
                book.setname(
"thinking in java");
                book.setcategoryid(
2);
                booklist.add(book);
                book 
= new book();
                book.setid(
4);
                book.setname(
"head first design patterns");
                book.setcategoryid(
2);
                booklist.add(book);

                bookmap.put(
2, booklist);


                
return success;
        }

        
// getter and setter..
}





]]>
使用struts2中的ognl表达式显示数据表字典项的值http://www.blogjava.net/usherlight/archive/2008/03/17/186730.html云自无心水自闲云自无心水自闲mon, 17 mar 2008 04:09:00 gmthttp://www.blogjava.net/usherlight/archive/2008/03/17/186730.htmlhttp://www.blogjava.net/usherlight/comments/186730.htmlhttp://www.blogjava.net/usherlight/archive/2008/03/17/186730.html#feedback8http://www.blogjava.net/usherlight/comments/commentrss/186730.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/186730.html 比如在一个图书馆系统中,书籍表(book)会有一个分类字段,这时候我们一般会单独建立一张分类表(category),在书籍表只保存分类表的id。
在用户界面上显示书籍明细的时候,会要求显示categoryid在category表中对应的名称。
这样通常的做法是把book和category两张表进行关联。
但在实际应用中,category一般都是cache在应用服务器端,再使用数据表的连接就不够高效。
我的做法是这样的:在ibatis中使用sqlmap从表中将数据取出,此时不使用数据表的连接。
package com.demo;
public class book {
      
/* 省略了getter和setter方法 */
        private int id;
        
private string name;
        
private int categoryid;
        
private string author;
}


package com.demo;

public class category {
       
private static map<integer, category> cachemap;

        
/* 省略了这两个属性的getter和setter方法 */

        
private int id;
        
private string name;
       
public static category getcategory(int id) {
             init();
            
return cachemap.get(id);
        }
 
        
public static map<integer, category> getcategorymap() {
            init();
           
return cachemap();
        }

       
private init() {
            
if ( cachemap != null ) return;

            
// the code to load category from datebase
            
// 在这里为了演示的需要,使用以下代码

             cachemap 
= new hashmap<integer, category>();
             category category 
= new category();
             category.setid(
1);
             category.setname(
"fiction");
             cachemap.put(
1, category);
 
             category 
= new category();
             category.setid(
2);
             category.setname(
"cartoon");
        }
}



package com.demo;

public class bookaction  {
        
/* 省略了属性的getter和setter方法 */
        book book;

        
public string execute() {
                book 
= new book();
                book.setid(
1);
                book.setname(
"thinking in java");
                book.setcategoryid(
1);
                booklist.add(book);
                
                
return success;                
        }
}

jsp:
<%@ taglib prefix="s" uri="/struts-tags"%>
doctype html public "-//w3c//dtd html 4.01 transitional//en">
<html>
 
<head>
  
<s:head />
 
head>

 
<body>

  
<table border="1">
    
<tr>
     
<td>
      
<s:text name="page.label.username" />
     
td>
     
<td>
      
<s:property value="book.name" />
     
td>
    
tr>
    
<tr>
     
<td>
      
<s:text name="page.label.category" />
     
td>
     
<td>
       
<s:property value="@com.demo.category@getcategory(book.categoryid).getname()"/>td>
    
tr>
 
body>
html>





云自无心水自闲 2008-03-17 12:09
]]>
stuts2中session timeout的处理(备忘)http://www.blogjava.net/usherlight/archive/2008/02/21/181026.html云自无心水自闲云自无心水自闲thu, 21 feb 2008 04:03:00 gmthttp://www.blogjava.net/usherlight/archive/2008/02/21/181026.htmlhttp://www.blogjava.net/usherlight/comments/181026.htmlhttp://www.blogjava.net/usherlight/archive/2008/02/21/181026.html#feedback2http://www.blogjava.net/usherlight/comments/commentrss/181026.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/181026.htmltomcat在后台重起后,所有的session失效。如果客户端继续点击了一个菜单项,发出一个请求。会得到一个exception。

这时候,可以定义一个名为:sessiontimeout的global results

name="sessiontimeout">/web-inf/pages/session_timeout.jsp

这样,所有action的session timeout都会被定向到指定的页面



云自无心水自闲 2008-02-21 12:03
]]>
extjs tree json struts2 http://www.blogjava.net/usherlight/archive/2008/02/19/180590.html云自无心水自闲云自无心水自闲tue, 19 feb 2008 01:27:00 gmthttp://www.blogjava.net/usherlight/archive/2008/02/19/180590.htmlhttp://www.blogjava.net/usherlight/comments/180590.htmlhttp://www.blogjava.net/usherlight/archive/2008/02/19/180590.html#feedback41http://www.blogjava.net/usherlight/comments/commentrss/180590.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/180590.html {"cls":"folder","id":10,"leaf":false,"children":[{"cls":"file","id":11,"leaf":true,"children":null,"text":"s600"},{"cls":"file","id":12,"leaf":true,"children":null,"text":"slk200"}],"text":"benz"}
而extjs需要的数据格式如下:
[{"cls":"folder","id":10,"leaf":false,"children":[{"cls":"file","id":11,"leaf":true,"children":null,"text":"s600"},{"cls":"file","id":12,"leaf":true,"children":null,"text":"slk200"}],"text":"benz"}]
区别很小,就只相差最外面的两个方括号。但是少了这两个方括号,在json中,含义迥然不同,前者表示一个对象,而后者表示一个数组。而extjs中 tree的dataloader需要的数据必须是一个数组。而这样的数据格式是json-plugin自动生成的,无法改变。所以,我最后放弃了json -plugin,转而使用json-lib来解决这个问题。
1. 下载json-lib, http://json-lib.sourceforge.net/
2. lib目录下的jar文件清单:
commons-beanutils-1.7.0.jar
commons-collections-3.2.jar
commons-digester-1.6.jar
commons-lang-2.3.jar
commons-logging-1.1.jar
dom4j-1.6.1.jar
ezmorph-1.0.4.jar
freemarker-2.3.8.jar
javassist-3.8.1.jar
json-lib-2.2.1-jdk15.jar
log4j-1.2.13.jar
ognl-2.6.11.jar
struts2-core-2.0.11.jar
xml-apis-1.0.b2.jar
xwork-2.0.4.jar


首先配置web.xml
xml version="1.0" encoding="utf-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
  xmlns:xsi
="http://www.w3.org/2001/xmlschema-instance"
  xsi:schemalocation
="http://java.sun.com/xml/ns/j2ee
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
>
  
<welcome-file-list>
    
<welcome-file>index.jspwelcome-file>
  
welcome-file-list>
  
<filter>
    
<filter-name>struts2filter-name>
    
<filter-class>org.apache.struts2.dispatcher.filterdispatcherfilter-class>
  
filter>

  
<filter-mapping>
    
<filter-name>struts2filter-name>
    
<url-pattern>/*url-pattern>
  
filter-mapping>
web-app>

然后是struts.xml
xml version="1.0" encoding="utf-8"?>
doctype struts public
    "-//apache software foundation//dtd struts configuration 2.0//en"
    "http://struts.apache.org/dtds/struts-2.0.dtd"
>
   
<struts>
    
<constant name="struts.devmode" value="true"/>
    
<constant name="struts.i18n.encoding" value="utf-8"/>
    
<package name="person" extends="struts-default">
        
<action name="menus" method="execute" class="com.lab.menuaction">
            
<result>/menu.jspresult>
        
action>
    
package>
struts>

3. 树的节点模型(省略了getter,setter)
public class menu {
    
private int id;
    
private string text;
    
private boolean leaf;
    
private string cls;
    
private list<menu> children;
}

4. action
package com.lab;

import java.util.arraylist;
import java.util.list;

import net.sf.json.jsonarray;

public class menuaction {
    
private string menustring;
   
    
private list<menu> menus;
   
    
public string execute() {

        menus 
= new arraylist<menu>();
       
        menu benz 
= new menu();
        benz.settext(
"benz");
        benz.setcls(
"folder");
        benz.setleaf(
false);
        benz.setid(
10);
        menus.add(benz);
       
        list
<menu> benzlist = new arraylist<menu>();
        benz.setchildren(benzlist);
       
        menu menu;
        menu 
= new menu();
        menu.settext(
"s600");
        menu.setcls(
"file");
        menu.setleaf(
true);
        menu.setid(
11);
        benzlist.add(menu);
        menu 
= new menu();
        menu.settext(
"slk200");
        menu.setcls(
"file");
        menu.setleaf(
true);
        menu.setid(
12);
        benzlist.add(menu);
       
        menu bmw 
= new menu();
        bmw.settext(
"bmw");
        bmw.setcls(
"folder");
        bmw.setleaf(
false);
        bmw.setid(
20);
        menus.add(bmw);
       
        list
<menu> bmwlist = new arraylist<menu>();
        bmw.setchildren(bmwlist);
       
        menu 
= new menu();
        menu.settext(
"325i");
        menu.setcls(
"file");
        menu.setleaf(
true);
        menu.setid(
21);
        bmwlist.add(menu);
       
        menu 
= new menu();
        menu.settext(
"x5");
        menu.setcls(
"file");
        menu.setleaf(
true);
        menu.setid(
22);
        bmwlist.add(menu);
       
        jsonarray jsonobject 
= jsonarray.fromobject(menus);
        
try {
            menustring 
= jsonobject.tostring();
        } 
catch (exception e) {
            menustring 
= "ss";
        }

        
return "success";
    }

    
public string getmenustring() {
        
return menustring;
    }

    
public void setmenustring(string menustring) {
        
this.menustring = menustring;
    }
}

5. menu.jsp
<%@ taglib prefix="s" uri="/struts-tags" %>


6. html页面和js
我使用的就是extjs的example中的reorder.html和reorder.js,更改了reorder.js中treeloader的dataurl: menus.action
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<title>reorder treepaneltitle>
<link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css" />

    

     

     
<script type="text/javascript" src="extjs/adapter/ext/ext-base.js">script>
     

 
    
<script type="text/javascript" src="extjs/ext-all.js">script>
<script type="text/javascript" src="reorder.js">script>


<link rel="stylesheet" type="text/css" href="extjs/resources/css/example.css" />
head>
<body>
<script type="text/javascript" src="../examples.js">script>
<h1>drag and drop ordering in a treepanelh1>
<p>this example shows basic drag and drop node moving in a tree. in this implementation there are no restrictions and 
anything can be dropped anywhere except appending to nodes marked 
"leaf" (the files). <br>p>
<p>drag along the edge of the tree to trigger auto scrolling while performing a drag and drop.p>
<p>in order to demonstrate drag and drop insertion points, sorting was <b>notb> enabled.p>
<p>the data for this tree is asynchronously loaded with a json treeloader.p>
<p>the js is not minified so it is readable. see <href="reorder.js">reorder.jsa>.p>

<div id="tree-div" style="overflow:auto; height:300px;width:250px;border:1px solid #c3daf9;">div>

body>
html>



js:
/*
 * ext js library 2.0.1
 * 凯发天生赢家一触即发官网 copyright(c) 2006-2008, ext js, llc.
 * licensing@extjs.com
 *
 * http://extjs.com/license
 
*/

ext.onready(
function(){
    
// shorthand
    var tree = ext.tree;
   
    
var tree = new tree.treepanel({
        el:'tree
-div',
        autoscroll:
true,
        animate:
true,
        enabledd:
true,
        containerscroll: 
true,
        loader: 
new tree.treeloader({
            dataurl:'http:
//localhost:8080/lab/menus.action'
        })
    });

    
// set the root node
    var root = new tree.asynctreenode({
        text: 'ext js',
        draggable:
false,
        id:'source'
    });
    tree.setrootnode(root);

    
// render the tree
    tree.render();
    root.expand();
});

我已经上传了完整的war文件(包含所有源代码),见:



]]>
struts2中实现可编辑的表格http://www.blogjava.net/usherlight/archive/2008/02/12/179717.html云自无心水自闲云自无心水自闲tue, 12 feb 2008 13:06:00 gmthttp://www.blogjava.net/usherlight/archive/2008/02/12/179717.htmlhttp://www.blogjava.net/usherlight/comments/179717.htmlhttp://www.blogjava.net/usherlight/archive/2008/02/12/179717.html#feedback2http://www.blogjava.net/usherlight/comments/commentrss/179717.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/179717.html
public class person {
int id;
string name;
int age;
float height;
}

这是一个pojo,getter和setting省略了。

action中可以这样使用:

public class myaction {
public list getpeoplelist() { … }
public void setpeoplelist( list peoplelist ) { … }

}
在我们使用person类之前,需要添加一个配置文件,myaction-conversion.properties,把这个文件和myaction放在一起。
这个文件里只有一行内容:
element_peoplelist=person
前缀element_是一个常量,表明等号左边的表达式中跟在这个常量后面的是action类中一个list类型的字段名。
等号右边的表达式是全类名(包含package)
下面是一个页面的代码片段:
<s:form action="update" method="post" >
<s:iterator value="peoplelist" status="stat">
<s:hidden
name="peoplelist[%{#stat.index}].id"
value
="%{peoplelist[#stat.index].id}"/>
<s:textfield label="name"
name
="peoplelist[%{#stat.index}].name"
value
="%{peoplelist[#stat.index].name}"/>
<s:textfield label="age"
name
="peoplelist[%{#stat.index}].age"
value
="%{peoplelist[#stat.index].age}" />
<s:textfield label="height"
name
="peoplelist[%{#stat.index}].height"
value
="%{peoplelist[#stat.index].height}"/>
<br/>
s:iterator>
<s:submit value="update"/>
s:form>


使用这段代码,struts2会创建一个person类的arraylist,并且用setpersonlist这个方法把页面表格中的值传递回action。
如果你是想从用户界面中动态创建列表值,需要允许struts2给列表中类的实例。那么在配置文件myaction-conversion.properties中添加一行:
createifnull_peoplelist = true

云自无心水自闲 2008-02-12 21:06
]]>
struts2 and ajax --使用dojo和divhttp://www.blogjava.net/usherlight/archive/2008/02/10/179572.html云自无心水自闲云自无心水自闲sun, 10 feb 2008 12:56:00 gmthttp://www.blogjava.net/usherlight/archive/2008/02/10/179572.htmlhttp://www.blogjava.net/usherlight/comments/179572.htmlhttp://www.blogjava.net/usherlight/archive/2008/02/10/179572.html#feedback6http://www.blogjava.net/usherlight/comments/commentrss/179572.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/179572.html阅读全文

]]>
struts2使用iterator标签显示嵌套maphttp://www.blogjava.net/usherlight/archive/2008/01/25/177741.html云自无心水自闲云自无心水自闲fri, 25 jan 2008 05:16:00 gmthttp://www.blogjava.net/usherlight/archive/2008/01/25/177741.htmlhttp://www.blogjava.net/usherlight/comments/177741.htmlhttp://www.blogjava.net/usherlight/archive/2008/01/25/177741.html#feedback10http://www.blogjava.net/usherlight/comments/commentrss/177741.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/177741.html<%@ taglib prefix="s" uri="/struts-tags"%>

doctype html public "-//w3c//dtd html 4.01 transitional//en">
<html>
    
<head>
        
<s:head />
    
head>

    
<body>

        
<table border="1">
            
<s:iterator value="datamap.keyset()" id="class">
                
<s:iterator value="datamap.get(#class).keyset()" id="group">
                
<tr>
                    
<td><s:property value="group"/>td>
                    
<s:iterator value="datamap.get(#class).get(#group).values()" id="name">
                        
<td><s:property value="name"/>td>
                    
s:iterator>
                
tr>
                
s:iterator>
            
s:iterator>
        
table>
    
body>
html>


]]>
struts2中对于radio list的预选(pre select),即:使一个值被默认选中http://www.blogjava.net/usherlight/archive/2008/01/24/177589.html云自无心水自闲云自无心水自闲thu, 24 jan 2008 14:06:00 gmthttp://www.blogjava.net/usherlight/archive/2008/01/24/177589.htmlhttp://www.blogjava.net/usherlight/comments/177589.htmlhttp://www.blogjava.net/usherlight/archive/2008/01/24/177589.html#feedback4http://www.blogjava.net/usherlight/comments/commentrss/177589.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/177589.html在struts2中,radio标签可以使用一个list来输出一组radio按钮,
       
但是如何设置其中一个被默认选中。

查阅了struts2的文档,发现radio标签有一个value属性是用于对radio的进行预选的: http://struts.apache.org/2.x/docs/radio.html
value: preset the value of input element.
于是,进行了试验,
结果失败了。male的值并没有被选中,经过反复研究,终于得到了正确的结果:
'male'" />
看到其中的区别了吗,就是多了两个单引号。
我认为这是因为value属性的特性引起的。如果male没有加引号,那么struts2会去值的堆栈中寻找变量名为male的值,结果找不到。
加上单引号后,struts2(应该是ognl)把'male'认为是一个简单的字符串。

这样,radio就能够正确地匹配到值,使指定的值默认被选中



云自无心水自闲 2008-01-24 22:06
]]>
struts2动态返回xmlhttp://www.blogjava.net/usherlight/archive/2007/12/14/167858.html云自无心水自闲云自无心水自闲fri, 14 dec 2007 13:14:00 gmthttp://www.blogjava.net/usherlight/archive/2007/12/14/167858.htmlhttp://www.blogjava.net/usherlight/comments/167858.htmlhttp://www.blogjava.net/usherlight/archive/2007/12/14/167858.html#feedback6http://www.blogjava.net/usherlight/comments/commentrss/167858.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/167858.html 开始进行的都比较顺利,但是客户端和服务端一连起来就出问题,页面在加载xml的时候总是弹出一个对话框,说是加载的xml格式不正确。但是我在ie中直接输入action,页面显示的结果十分正确,没有问题。后来,无意中我查看了返回xml页面的源文件,这才发现了问题。
原来,xml的<和>全都被转换成<和>了。
我一开始是想在后台考虑如何对字符串进行转换,后来在查struts2文档的时候发现,

例子已经整理出来了:http://www.blogjava.net/usherlight/archive/2008/08/07/220756.html

云自无心水自闲 2007-12-14 21:14
]]>
网站地图