随笔-34  评论-1965  文章-0  trackbacks-0

在当今——web 2.0概念铺天盖地的internet环境下,简易的ajax集成对于一个成功的web框架来说是不可或缺的。因此,struts 2其中的一个重要的功能(feature)就是“first-class ajax support - add interactivity and flexibility with ajax tags that look and feel just like standard struts tags(大意:一流的ajax支持——通过ajax标志增加互动性和灵活性,而且使用这些ajax标志与普通的struts标志同样简单)”。

实现原理

基于不重新发明轮子的原则,struts 2并没有开发新的ajax框架,而是使用时下java ee平台中比较流行的ajax框架——dojo和dwr。

最近在musachy barroso等同志的无私奉献下,开发了struts 2的json插件(plugin),极大地方便了我们输出json结果(result)。

json插件(plugin)

在struts 2的showcase中的ajax部分,json的结果输出是通过freemaker模板实现。这种方法在简易性和灵活性上都比不上json插件,所以json插件值得向大家五星推荐。

下面让我们看一个json插件的例子。

首先到以下网址下载json插件的jar包,并将其加入你的webcontent\web-inf\lib下。

接下是本例子的action代码:

package tutorial;

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

import com.googlecode.jsonplugin.annotations.json;
import com.opensymphony.xwork2.actionsupport;

publicclass jsonpluginaction extends actionsupport {
   
privatestaticfinallong serialversionuid =-6784977600668791997l;
   
   
privateint bookid;
   
private string title;
   
privatedouble price;
   
private list<string> comments;    
   
privatetransient string secret1;
   
private string secret2;

   @json(name
="isbn")
   
publicint getbookid() {
       
return bookid;
   }


   
publicvoid setbookid(int bookid) {
       
this.bookid = bookid;
   }


   
public list<string> getcomments() {
       
return comments;
   }


   
publicvoid setcomments(list<string> comments) {
       
this.comments = comments;
   }


   
publicdouble getprice() {
       
return price;
   }


   
publicvoid setprice(double price) {
       
this.price = price;
   }


   
public string gettitle() {
       
return title;
   }

   
   
publicvoid settitle(string title) {
       
this.title = title;
   }


   @override
   
public string execute() {
       bookid
=15645912;
       title
="max on java";
       price
=0.9999d;
       comments
=new arraylist<string>(3);
       comments.add(
"it's no bad!");
       comments.add(
"wow!");
       comments.add(
"no comment!");
       secret1
="you can't see me!";
       secret2
="i am invisible!";
       
return success;
   }

}
清单1 src/tutorial/jsonpluginaction.java

以上代码值得注意的是,通过@json的java注释(annotation),我们可以改变json结果的属性名称,另外带有transient修饰符与没有getter方法的字段(field)都不会被串行化为json。

然后,我们来配置一下此action,代码如下:

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>    
   
<package name="struts2_ajax_demo" extends="json-default">
       
<action name="jsonplugin" class="tutorial.jsonpluginaction">
           
<result type="json"/>
       
action>            
   
package>
struts>
清单2 src/struts.xml

上面配置文件的“package”元素和以往不同的是,它扩展了“json-default”而不是“struts-default”。“json-default”是在jsonplugin-0.11.jar包里的struts-plugin.xml中定义的。该文件同时定义了“json”的结果类型,有兴趣的朋友可以打开此文件看看。

发布运行应用程序,在浏览器中键入:,出现下载文件对话框,原因是json插件将http响应(response)的mime类型设为“application/json”。把文件下载下来,用记事本打开,内容如下:

{"isbn":15645912,"comments":["it's no bad!","wow!","no comment!"],"price":0.9999,"title":"max on java"}
清单3 例子1输出的json串

当然这还不是一个完整的ajax的例子,下面让我们写一个html文件将其完成,html代码如下:

doctype html public "-//w3c//dtd xhtml 1.0 transitional//en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
   
<title>json plugintitle>
   
<script type="text/javascript">    
   
var bxmlhttpsupport = (typeof xmlhttprequest !="undefined"|| window.activexobject);
     
   
if (typeof xmlhttprequest =="undefined"&& window.activexobject) {
       
function xmlhttprequest() {
           
var arrsignatures = ["msxml2.xmlhttp.5.0", "msxml2.xmlhttp.4.0",
                                 
"msxml2.xmlhttp.3.0", "msxml2.xmlhttp",
                                 
"microsoft.xmlhttp"];
                             
           
for (var i=0; i < arrsignatures.length; i) {
               
try {        
                   
var orequest =new activexobject(arrsignatures[i]);            
                   
return orequest;        
                }
catch (oerror) { /*ignore*/ }
            }          
    
           
thrownew error("msxml is not installed on your system.");               
        }
    }    
            
   
function retrievebook() {        
       
if(bxmlhttpsupport) {
           
var surl = 'jsonplugin.action';
           
var orequest =new xmlhttprequest();
            orequest.onreadystatechange
=function() {
               
if(orequest.readystate ==4) {                    
                   
var obook = eval('(' orequest.responsetext ')');
                   
var bookholder = document.getelementbyid('bookholder');
                   
var sbook = '<p><b>isbn: b>' obook.isbn 'p>';
                    sbook
= ('<p><b>title: b>' obook.title 'p>');
                    sbook
= ('<p><b>price: b>$' obook.price 'p>');
                    sbook
= ('<b><i>comments: i>b><hr/>');
                   
for(i =0; i < obook.comments.length; i) {
                        sbook
= ('<p><b>#' (i 1) ' b>' obook.comments[i] 'p>');
                    }
                    bookholder.innerhtml
= sbook;
                }
            };
            orequest.open('post', surl);
            orequest.send(
null);
        }
    }
   
script>
head>
<body>
   
<input type="button" value="retrieve book" onclick="retrievebook()"/>
   
<div id="bookholder">div>
body>
html>
清单4 webcontent/jsonplugin.html

以上代码中,我没有使用任何的ajax的javascript包,而是参考《professional javascript for web developer》手工创建xhr(xmlhttprequest),并在xhr完成后使用eval()方法将json字符串变为json对象。需要注意的是,要调用eval函数时,必须使用“(”和“)”将json字符串括起来,否则会出错的。

打开,点击“retrieve book”按钮,页面如下图所示:

图1 jsonplugin.html页面输出
图1 jsonplugin.html页面输出

struts 2与dojo

是开源javascript工具包,它引了widget的概念,方便了javascript面向对象编程(oop),改进javascript的事件模型。在此我不打算对此进行深入的讲解,有兴趣的朋友的可以找网上找一些关于dojo的资料学习。

struts 2基于dojo编写一些ajax标志(在dojo中称为widget),要使用这些标志的ajax功能,需要将标志的“theme”属性设为“ajax”。同时,亦需要将加入在与之间加入。当使用这些标志的ajax功能,有些属性可能会经常用到,所以我会对这些属性稍作解释。

名称 描述
href xhr(xmlhttprequest)请求的地址
listentopics 监听的dojo话题(topic)以触发自身,如可以在可以通过发布(publish)相应的话题,通知重新加载其备选项(options)
notifytopics 完成远程调用后,发出通知,触发相应的javascript函数或dojo widget
formid 需要提交到服务器的表单的id
formfilter 过滤表单字段的javascript函数名称
indicator 在xhr处理过程中,包含用户提示的信息的html元素的id,如图片或div等
表1 常用的ajax标志属性

这些标志包括:等,下面我将分别讲解。

1、

这两个标志方便了我们的调用xhr实现ajax,所以上面的html如果使用了这两标志将会变得更简单,因为我们不用再去理会繁锁的xhr创建和设定的工作。下面是示例代码:

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

doctype html public "-//w3c//dtd xhtml 1.0 transitional//en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
   
<head>
       
<title>json plugintitle>
       
<s:head theme="ajax"/>
       
<script type="text/javascript">                    
        dojo.addonload(
function() {
            dojo.event.topic.subscribe('retrievebook',
this, function(data, type, e){
               
if(type == 'load') {
                    showbook(data);
                }
elseif(type == 'error') {
                    alert('can not retrieve the book');
                }
            });
        });
        
       
function showbook(strbook) {
           
var obook = eval('(' strbook ')');
           
var bookholder = document.getelementbyid('bookholder');
           
var sbook = '<p><b>isbn: b>' obook.isbn 'p>';
            sbook
= ('<p><b>title: b>' obook.title 'p>');
            sbook
= ('<p><b>price: b>$' obook.price 'p>');
            sbook
= ('<b><i>comments: i>b><hr/>');
           
for(i =0; i < obook.comments.length; i) {
                sbook
= ('<p><b>#' (i 1) ' b>' obook.comments[i] 'p>');
            }
            bookholder.innerhtml
= sbook;
        }
       
script>
   
head>
   
<body>
       
<s:url id="bookurl" value="/jsonplugin.action"/>
       
<s:submit href="%{bookurl}" theme="ajax" indicator="indicator"
            value
="retrieve book" align="left" notifytopics="retrievebook"/>
       
<s:a theme="ajax" href="%{bookurl}" indicator="indicator"
            notifytopics
="retrievebook">retrieve books:a>
       
<img id="indicator"
            src
="${pagecontext.request.contextpath}/images/indicator.gif"
            alt
="loading" style="display:none"/>
       
<div id="bookholder">div>
   
body>
html>
清单5 webcontent/linkbutton.jsp

可能上述代码还不够简洁,因为我将html格式化的工作都放在javascript中完成。但如果你的xhr返回的是html片段,你可以简单地将的“targets”属性设为“bookholder”即可,详情大家可以参考struts 2 showcase。至于返回html片段,可以通过action freemaker完成。

2、

autocomplete是比较经典的ajax应用,虽然谷歌已经停止使用这一功能,但就autocompleter自身而言的确是很酷的。下面是一个的例子。

首先,我要伪造一些字符串数据,代码如下:

package tutorial;

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

publicfinalclass datas {
   
publicstaticfinal list<string> names;
   
static{
       names
=new arraylist<string>();
       names.add(
"alabama");
       names.add(
"alaska");
       names.add(
"american samoa");
       names.add(
"arizona");
       names.add(
"arkansas");
       names.add(
"armed forces europe");
       names.add(
"armed forces pacific");
       names.add(
"armed forces the americas");
       names.add(
"california");
       names.add(
"colorado");
       names.add(
"connecticut");
       names.add(
"delaware");
       names.add(
"district of columbia");
       names.add(
"federated states of micronesia");
       names.add(
"florida");
       names.add(
"georgia");
       names.add(
"guam");
       names.add(
"hawaii");
       names.add(
"idaho");
       names.add(
"illinois");
       names.add(
"indiana");
       names.add(
"iowa");
       names.add(
"kansas");
       names.add(
"kentucky");
       names.add(
"louisiana");
       names.add(
"maine");
       names.add(
"marshall islands");
       names.add(
"maryland");
       names.add(
"massachusetts");
       names.add(
"michigan");
       names.add(
"minnesota");
       names.add(
"mississippi");
       names.add(
"missouri");
       names.add(
"montana");
       names.add(
"nebraska");
       names.add(
"nevada");
       names.add(
"new hampshire");
       names.add(
"new jersey");
       names.add(
"new mexico");
       names.add(
"new york");
       names.add(
"north carolina");
       names.add(
"north dakota");
       names.add(
"northern mariana islands");
       names.add(
"ohio");
       names.add(
"oklahoma");
       names.add(
"oregon");
       names.add(
"pennsylvania");
       names.add(
"puerto rico");
       names.add(
"rhode island");
       names.add(
"south carolina");
       names.add(
"south dakota");
       names.add(
"tennessee");
       names.add(
"texas");
       names.add(
"utah");
       names.add(
"vermont");
       names.add(
"virgin islands, u.s.");
       names.add(
"virginia");
       names.add(
"washington");
       names.add(
"west virginia");
       names.add(
"wisconsin");
       names.add(
"wyoming");
   }

}
清单6 src/tutorial/datas.java

然后是用于获取和过滤数据的action,代码如下:

package tutorial;

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

import com.opensymphony.xwork2.actionsupport;

publicclass autocompleteraction extends actionsupport {
   
privatestaticfinallong serialversionuid =-8201401726773589361l;
   
   
private list<string[]> names;    
   
private string start;
   
   
publicvoid setstart(string start) {
       
this.start = start;
   }

   
   
public list<string[]> getnames() {
       
return names;
   }


   @override
   
public string execute() {
       names
=new arraylist<string[]>();
       
if(start ==null||"".equals(start.trim())) {
           start
="a";
       }

       
for(string s : datas.names) {
           
if(s.tolowercase().startswith(start.tolowercase())) {
               names.add(
new string[]{ s, s });
           }

       }

       
return success;
   }

}
清单7 src/tutorial/autocmpleteraction.java

上述action会以json的形式返回以start开头的datas.names的中字符串,以下是此action的配置:

<action name="autocompleter" class="tutorial.autocompleteraction">
   
<result type="json">
       
<param name="root">namesparam>
   
result>
action>
清单8 autocompleter action的配置代码片段

在json类型结果的参数中加入“root”参数可以设定输出json结果的根,以上述情况为例,如果没有“root”参数,输出将为“{ "names": [ ["xxx", "xxx"]...] }”,加了之后变就会成“[ ["xxx", "xxx"]...] ”。接下来,让我们看看页面的代码:

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

doctype html public "-//w3c//dtd xhtml 1.0 transitional//en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
   
<head>
       
<title>struts 2 ajax - autocompletertitle>
       
<s:head theme="ajax"/>
   
head>
   
<body>
       
<h2>
            autocompleter
       
h2>
       
<s:form action="autocompleterform">
           
<s:textfield label="abc" name="abc"/>
           
<tr>
               
<td class="tdlabel">
                   
<label class="label">
                        no ajax autocompleter:
                   
label>
               
td>
               
<td>
                   
<s:autocompleter theme="simple" name="user"
                        list
="@tutorial.datas@names"/>
               
td>
           
tr>
           
<tr>
               
<td class="tdlabel">
                   
<label class="label">
                        ajax autocompleter:
                   
label>
               
td>
               
<td>
                   
<s:url id="dataurl" value="/autocompleter.action"/>
                   
<s:autocompleter theme="ajax" name="start" href="%{dataurl}"
                        loadontextchange
="true" loadminimumcount="1" indicator="indicator"
                        autocomplete
="false" showdownarrow="false"/>
                   
<img id="indicator"
                        src
="${pagecontext.request.contextpath}/images/indicator.gif"
                        alt
="loading" style="display:none"/>
               
td>
           
tr>
       
s:form>
   
body>
html>
清单9 webcontent/autocompleter.jsp

上述页面包含两个标志,前者使用“simple”模板,所以不具有ajax功能,它的数据将以html方式输出到最终页面里;而后者则使用了“ajax”模板,每当输入框的值发生改变时,它都向url“/autocompleter.action”发送请求,action根据请求中的start参数的值,返回相当的json,在请求完成后页面通过回调函数改变输入框的下拉提示,效果如下图所示:

图2 autocompleter.jsp页面输出 
图2 autocompleter.jsp页面输出

3、

树是是比较常用的数据结构,因为它可以很好地体现真实世界中对象之间的关系。的使用也相对简单,但需要说明的是——struts 2.0.6 ga版本的是有bug的,大家可以点击这个链接了解详细的情况。这个bug主要是在的通过“treecollapsedtopic”、“treeexpandedtopic”和“treeselectedtopic”设定的话题(topic)都没有起作用,上述链接相应给出了解决方法,但我认为该方法太麻烦(需要自己重新编译和打包struts 2),所以下面的例子,我将另辟徯径,请参考以下代码。

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

doctype html public "-//w3c//dtd xhtml 1.0 transitional//en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
   
<head>
       
<title>struts 2 ajax - treetitle>
       
<s:head theme="ajax" debug="true"/>
       
<script type="text/javascript">
           
function treenodeselected(arg) {
                alert(arg.source.title
' selected');
            }
            dojo.addonload(
function() {                
               
var s = dojo.widget.byid('parentid').selector;                
                dojo.event.connect(s, 'select', 'treenodeselected');
            });
       
script>
   
head>
   
<body>
       
<h2>
            tree
       
h2>
       
<div style="float:left; margin-right: 50px;">
           
<s:tree label="parent" id="parentid" theme="ajax"
                templatecsspath
="/struts/tree.css" showrootgrid="true"
                showgrid
="true">
               
<s:treenode theme="ajax" label="child1" id="child1id">
                   
<s:treenode theme="ajax" label="grandchild1" id="grandchild1id"/>
                   
<s:treenode theme="ajax" label="grandchild2" id="grandchild2id"/>
                   
<s:treenode theme="ajax" label="grandchild3" id="grandchild3id"/>
               
s:treenode>
               
<s:treenode theme="ajax" label="child2" id="child2id"/>
               
<s:treenode theme="ajax" label="child3" id="child3id"/>
               
<s:treenode theme="ajax" label="child4" id="child4id"/>
               
<s:treenode theme="ajax" label="child5" id="child5id">
                   
<s:treenode theme="ajax" label="gchild1" id="gchild1id"/>
                   
<s:treenode theme="ajax" label="gchild2" id="gchild2id"/>
               
s:treenode>
           
s:tree>
       
div>
   
body>
html>
清单10 webcontent/tree.jsp

因为dojo的树控件,即使在没有设定“selector”情况下,也会自动生成一个默认的selector,所以只要将其事件绑定到特定的事件处理函数即可。

打开,点击任一树节点,页面如下图所示:

图3 tree.jsp页面输出 
图3 tree.jsp页面输出

总结

我原本打算用一篇文章写完这个“struts 2与ajax”。不过在写的过程中,发现内容越来越多。如果勉强写成一篇,朋友们读起来也会很麻烦,所以我决定分开几部分,本文为第一部分。

另外,之前有的朋友建议我建一个google的讨论组,方便大家讨论问题。我觉得这个提议非常好,一直以来都是“一人写,大家留言”,这种相对单向的方式不免有所欠缺,而且本人所知也有限,开个讨论组大家可以相互讨论,共同进步。

因为struts2已经被创建,所以申请了“”,有兴趣的朋友,欢迎加入。

posted on 2007-06-12 18:31 max 阅读(80899) 评论(96)     所属分类: struts 2.0系列

评论:
# re: struts 2与ajax(第一部分)[未登录] 2007-06-12 19:53 |
我一直在关注你的blog,在这里学到了不少关于struts2的东西,可否写一下关于struts2和ext集成的例子,谢谢!  回复  
  
# re: struts 2与ajax(第一部分) 2007-06-12 20:34 | 海边沫沫
好文章,顶  回复  
  
# re: struts 2与ajax(第一部分)[未登录] 2007-06-13 09:19 |
终于等到你发帖了!~  回复  
  
# re: struts 2与ajax(第一部分) 2007-06-13 09:28 | 千山鸟飞绝
建议将struts2树型写得更详细一点,因为现在个人觉得struts2的树型似乎还是一次性的读取所有数据。  回复  
  
# re: struts 2与ajax(第一部分) 2007-06-13 13:27 | 有猫相伴的日子
没有说到dwr与struts2结合的例子  回复  
  
# re: struts 2与ajax(第一部分) 2007-06-13 18:28 |
老兄,现在市面上好像没有struts2 book 你可以整理一下出一本.满足一下市场的需求.这可是机会呀!  回复  
  
# re: struts 2与ajax(第一部分)[未登录] 2007-06-14 09:06 |
顶上
好东西  回复  
  
# re: struts 2与ajax(第一部分) 2007-06-14 09:31 | max
@千山鸟飞绝
可以的话,我会把它完善的。
@有猫相伴的日子
在第二部分应该会dwr与struts 2的例子。
@divid
值得考虑,不过还没有出版商找我:-)  回复  
  
# re: struts 2与ajax(第一部分) 2007-06-14 09:34 | max
struts 2.0.8 ga发布了,不过,我昨晚试了一下,似乎标志的bug还没有解决。  回复  
  
# re: struts 2与ajax(第一部分) 2007-06-14 14:56 |
请教个问题:
我页面中使用的是框架,就是左面菜单,右面页面,现在我是不知道怎么把action的值传到页面了,不知道怎么实现。请帮想个办法,谢谢!
  回复  
  
# re: struts 2与ajax(第一部分) 2007-06-14 23:05 | max
@look
和普通的做法一样。  回复  
  
# re: struts 2与ajax(第一部分) 2007-06-15 09:47 |

我的systemsetpo.getsyscode()的值是001,但从中的出的结果
是1,有什么办法能得到是001?谢谢  回复  
  
# re: struts 2与ajax(第一部分)[未登录] 2007-06-16 09:58 |
@max
dojo框架的tabcontainer控件不支持中文作标签的标题,有没什么办法可以解决啊,谢谢  回复  
  
# re: struts 2与ajax(第一部分) 2007-06-17 01:33 |
一路看来
max的系列指南文章对我学习struts帮助实在是太大了!
真是万分感谢!

不知现在google论坛是否已经建好?
我想如能进一步和一同学习struts2的朋友进行详细讨论,收获会更大。  回复  
  
# re: struts 2与ajax(第一部分) 2007-06-19 00:56 | max
@甜菜侯爵
论坛已经建好,欢迎加入讨论。  回复  
  
# re: struts 2与ajax(第一部分) 2007-06-19 00:59 | max
@look
这需要根据你的systemsetpo.getsyscode()返回是什么类型?可能要自己格式一下,另外,的value属性是支持ognl,所以应该尽量避免使用<%%>的写法。  回复  
  
# re: struts 2与ajax(第一部分) 2007-06-19 01:01 | max
@oliver
我会写一篇关于ajax出现的中文问题的解决方法的文章(如果这段有空的话)。  回复  
  
# re: struts 2与ajax(第一部分)[未登录] 2007-06-19 07:40 |
@max
好的,期待后续大作  回复  
  
# re: struts 2与ajax(第一部分) 2007-06-19 09:43 |
建议把树的部分写的再详细点
文中涉及到的是静态树
能不能把动态树的情况也讲一下
不胜感激!!  回复  
  
# re: struts 2与ajax(第一部分) 2007-06-19 12:35 |
@max
请问在struts2.0中session是怎么用的,我现在做一个项目的登陆模块,我想把登陆信息保存住,但struts2.0中我用了sessionaware,servletrequestaware,servletresponseaware,但是登陆信息还不保存不住,不知道为什么?不知道您是怎么做的?把解决一下,谢谢!  回复  
  
# re: struts 2与ajax(第一部分) 2007-06-19 22:08 | max
@furong
好的,我会在以后的文章多提及的。
@look
这通常的做法无有区别,请参考《》,如果你的通过sessionaware获得的map类型的session中属性集合(假如名为att),则应用使用att.put("user", "max");
如果是通过httpsession session = request.getsession()得到的session,则应使用session.setattribute("user", "max")。
希望这对你有用。  回复  
  
# re: struts 2与ajax(第一部分) 2007-06-22 14:38 |
用标签不能显示,提示:找不到dojo?
/struts/这个目录在那啊
请老兄帮忙!  回复  
  
# re: struts 2与ajax(第一部分) 2007-06-22 16:00 |
怎么才能加你为好友  回复  
  
# re: struts 2与ajax(第一部分) 2007-06-22 22:17 | max
@杨爱友
你可以通过google talk:max.m.yuan@gmail.com找到我。  回复  
  
# re: struts 2与ajax(第一部分) 2007-06-25 15:14 |
为何我的工程中加入“jsonplugin-0[1].13.jar”后就tomcat就不能启动?
console中出现信息为
java.lang.unsupportedclassversionerror: bad version number in .class file
......
我的jdk为1.5版本,难道jsonplugin是用jdk1.6版本编译出来的?  回复  
  
# re: struts 2与ajax(第一部分) 2007-06-25 22:45 | max
@jpma
不是,我使用的jdk就是5.0版本,你是否安装了多个jdk,请确认你的tomcat所使用的jdk的版本。  回复  
  
# re: struts 2与ajax(第一部分) 2007-06-25 22:53 | max
@divid
你可以在struts-core-2.0.6.jar或struts-core-2.0.8.jar包中的org.apache.struts2.static.dojo的路径下找到。  回复  
  
# re: struts 2与ajax(第一部分) 2007-06-27 10:16 |
@max
已经确定是jdk版本的问题,可能我下载的jsonplugin版本是新的吧,我安装了jre1.6后,将tomcat的“java virtural machine”改为1.6的jvm.dll后问题就解决了。  回复  
  
# re: struts 2與ajax(第一部分) 2007-07-01 17:38 |
autocompleter的例子
無法執行???
為什麼  回复  
  
# re: struts 2與ajax(第一部分) 2007-07-01 20:26 |
請問如何在的tag裡加入javascript onchange()的function
???  回复  
  
# re: struts 2与ajax(第一部分)[未登录] 2007-07-02 18:36 |
求助个问题

我用 struts2 的 ajax提交表单时,在服务端得到的值是 null
去掉 头部的 提交正常
这是什么问题?
弄了几天了,请帮忙解决一下,先谢谢了!

下边是部分代码

namespace="/web/usersinfo">




name="userbase.name" required="true" />


提交按钮:

  回复  
  
# re: struts 2与ajax(第一部分) 2007-07-02 23:08 | max
@jj
你可以使用notifytopics属性,如

在之间加入:

希望这对你有用。  回复  
  
# re: struts 2与ajax(第一部分) 2007-07-02 23:12 | max
@sivyer
你可以试一下在中加入href属性,如:

希望这可以解决你的问题。  回复  
  
# re: struts 2与ajax(第一部分)[未登录] 2007-07-13 19:19 |
文章太好了 !感谢作者。
请问我现在有个问题,就是使用的时候,我如果设置了list属性值,比如: 这问题我一直不知道是什么原因造成的,我看struts showcase上也有这个问题.只是showcase上如果result返回的是js文件时,才没有这个问题,但是使用list属性来initial这个tag值就出问题了。
我现在只能通过对每个autocompleter 设置notifytopics这个属性,并且再定义一个空的dojo.event.topic.subscribe来解决这个问题。
请问还有别的凯发天生赢家一触即发官网的解决方案么?  回复  
  
# re: struts 2与ajax(第一部分)[未登录] 2007-07-13 19:20 |
另外,我使用的是struts2.0.8版本  回复  
  
# re: struts 2与ajax(第一部分) 2007-07-20 10:51 |
个人感觉的输出样式不是很好看,
不知道是否可以自定义css?  回复  
  
# re: struts 2与ajax(第一部分) 2007-07-25 19:00 |
“在struts 2的showcase中的ajax部分,json的结果输出是通过freemaker模板实现。”

注意,不是“freemaker”而是“freemarker”(我喜欢将其直译为“自由标记者”),虽然仅仅只是少了一个字母'r',但却容易造成误解,我们程序员讲究的就是严谨的治学态度。

希望max兄在写出精品的同时,更能抓住细节,虽然很辛苦,但您的一举一动都会影响大批立志于java技术的后辈,可以说,在某种意义上,您已经是一面旗帜了。  回复  
  
# re: struts 2与ajax(第一部分) 2007-07-25 23:23 | max
@明人
过奖了,我在发文章之前会进行一下粗略的校对,但这样的错误还是在所难免。  回复  
  
# re: struts 2与ajax(第一部分) 2007-07-25 23:29 | max
@stone
sorry, 不太明白你的意思。  回复  
  
# re: struts 2与ajax(第一部分) 2007-07-28 15:46 |
例子说的 不明不白 配置文件也 很多没帖完全 误人时间  回复  
  
# re: struts 2与ajax(第一部分) 2007-07-31 10:49 |
基于不重新发明轮子的原则,struts 2并没有开发新的ajax框架,而是使用时下java ee平台中比较流行的ajax框架——dojo和dwr。

dwr 官方说的? 我怎么看文档里只说是dojo??

the framework provides a set of tags to help you ajaxify your applications, on dojo. dojo 0.4 is bundled with the distribution.  回复  
  
# re: struts 2与ajax(第一部分) 2007-07-31 23:34 | max
@adma
据我所知,struts 2在struts 2.0.6使用dwr实现ajax表单校验。  回复  
  
# re: struts 2与ajax(第一部分) 2007-08-01 10:04 |
@max
有文档吗?给个链接,谢谢。
  回复  
  
# re: struts 2与ajax(第一部分) 2007-08-10 09:01 |
请问,我的struts2中的datetimepicker这个控件怎么没有用,我按照网上的说法把代码写好了编绎运行后,我看不到这个组件.  回复  
  
# re: struts 2与ajax(第一部分)[未登录] 2007-08-22 09:57 |
@max
谢谢 max 你的关注,我现在再去看了下我提的问题,的确没有描述清楚。  回复  
  
# re: struts 2与ajax(第一部分) 2007-08-23 14:27 |
我想把spring也整合进去,但是出现了问题,如下配置 当extends不是
struts-default时,依赖注入不能实现,请问老大有可什么解决的的方法  回复  
  
# jsonplugin[未登录] 2007-09-12 17:34 |
struts 2 json plugin
json plugin
这两个插件有什么区别呀?有没有json plugin 的参考文档或api呀在哪里呢?
谢谢max大哥哥这么多好的文章  回复  
  
# re: struts 2与ajax(第一部分) 2007-09-13 15:48 |
java.lang.noclassdeffounderror: lorg/codehaus/plexus/plexuscontainer;
at java.lang.class.getdeclaredfields0(native method)
at java.lang.class.privategetdeclaredfields(class.java:2232)
at java.lang.class.getdeclaredfields(class.java:1715)
at com.opensymphony.xwork2.inject.containerimpl.addinjectors(containerimpl.java:102)
at com.opensymphony.xwork2.inject.containerimpl$1.create(containerimpl.java:84)
at com.opensymphony.xwork2.inject.containerimpl$1.create(containerimpl.java:82)
at com.opensymphony.xwork2.inject.util.referencecache$callablecreate.call(referencecache.java:155)
at java.util.concurrent.futuretask$sync.innerrun(futuretask.java:269)
at java.util.concurrent.futuretask.run(futuretask.java:123)
at com.opensymphony.xwork2.inject.util.referencecache.internalcreate(referencecache.java:81)
at com.opensymphony.xwork2.inject.util.referencecache.get(referencecache.java:121)
at com.opensymphony.xwork2.inject.containerimpl$constructorinjector.(containerimpl.java:329)
at com.opensymphony.xwork2.inject.containerimpl$5.create(containerimpl.java:299)
at com.opensymphony.xwork2.inject.containerimpl$5.create(containerimpl.java:298)
at com.opensymphony.xwork2.inject.util.referencecache$callablecreate.call(referencecache.java:155)
at java.util.concurrent.futuretask$sync.innerrun(futuretask.java:269)
at java.util.concurrent.futuretask.run(futuretask.java:123)
at com.opensymphony.xwork2.inject.util.referencecache.internalcreate(referencecache.java:81)
at com.opensymphony.xwork2.inject.util.referencecache.get(referencecache.java:121)
at com.opensymphony.xwork2.inject.containerimpl.getconstructor(containerimpl.java:562)
at com.opensymphony.xwork2.inject.containerimpl.inject(containerimpl.java:460)
at com.opensymphony.xwork2.inject.containerimpl$7.call(containerimpl.java:501)
at com.opensymphony.xwork2.inject.containerimpl.callincontext(containerimpl.java:549)
at com.opensymphony.xwork2.inject.containerimpl.inject(containerimpl.java:499)
at com.opensymphony.xwork2.config.impl.locatablefactory.create(locatablefactory.java:32)
at com.opensymphony.xwork2.inject.containerbuilder$4.create(containerbuilder.java:134)
at com.opensymphony.xwork2.inject.scope$2$1.create(scope.java:49)
at com.opensymphony.xwork2.inject.containerimpl$parameterinjector.inject(containerimpl.java:431)
at com.opensymphony.xwork2.inject.containerimpl.getparameters(containerimpl.java:446)
at com.opensymphony.xwork2.inject.containerimpl.access$000(containerimpl.java:48)
at com.opensymphony.xwork2.inject.containerimpl$methodinjector.inject(containerimpl.java:288)
at com.opensymphony.xwork2.inject.containerimpl$2.call(containerimpl.java:117)
at com.opensymphony.xwork2.inject.containerimpl$2.call(containerimpl.java:115)
at com.opensymphony.xwork2.inject.containerimpl.callincontext(containerimpl.java:542)
at com.opensymphony.xwork2.inject.containerimpl.injectstatics(containerimpl.java:114)
at com.opensymphony.xwork2.inject.containerbuilder.create(containerbuilder.java:494)
at com.opensymphony.xwork2.config.impl.defaultconfiguration.reload(defaultconfiguration.java:145)
at com.opensymphony.xwork2.config.configurationmanager.getconfiguration(configurationmanager.java:52)
at org.apache.struts2.dispatcher.dispatcher.init_preloadconfiguration(dispatcher.java:395)
at org.apache.struts2.dispatcher.dispatcher.init(dispatcher.java:452)
at org.apache.struts2.dispatcher.filterdispatcher.init(filterdispatcher.java:201)
at org.apache.catalina.core.applicationfilterconfig.getfilter(applicationfilterconfig.java:223)
at org.apache.catalina.core.applicationfilterconfig.setfilterdef(applicationfilterconfig.java:304)
at org.apache.catalina.core.applicationfilterconfig.(applicationfilterconfig.java:77)
at org.apache.catalina.core.standardcontext.filterstart(standardcontext.java:3600)
at org.apache.catalina.core.standardcontext.start(standardcontext.java:4193)
at org.apache.catalina.core.containerbase.start(containerbase.java:1013)
at org.apache.catalina.core.standardhost.start(standardhost.java:718)
at org.apache.catalina.core.containerbase.start(containerbase.java:1013)
at org.apache.catalina.core.standardengine.start(standardengine.java:442)
at org.apache.catalina.core.standardservice.start(standardservice.java:450)
at org.apache.catalina.core.standardserver.start(standardserver.java:709)
at org.apache.catalina.startup.catalina.start(catalina.java:551)
at sun.reflect.nativemethodaccessorimpl.invoke0(native method)
at sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:39)
at sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:25)
at java.lang.reflect.method.invoke(method.java:585)
at org.apache.catalina.startup.bootstrap.start(bootstrap.java:294)
at org.apache.catalina.startup.bootstrap.main(bootstrap.java:432)
- error filterstart

struts2.0.1 换成sturts2.0.8出现以上问题,为什么啊..知道的说下.谢谢  回复  
  
# re: struts 2与ajax(第一部分) 2007-09-17 17:15 |
s:autocompleter names 里如果有中文 怎么处理啊? 我debug在action中看到中文都是乱码  回复  
  
# re: struts 2与ajax(第一部分)[未登录] 2007-09-18 14:05 |
你好 ,max, 有个autocomplete的问题一直困扰了我好久 ,我断断续续找资料大概2个月了依旧没有能找到答案。我的问题描述比较长,而且有附件什么的,这里写的不方便。我写在这个地址上:

我在apache网站上找了bug日志,好像也没有提到这个issue,所以我想可能是我的用法不对,如果你能帮我解说一下,万分感谢。  回复  
  
# re: struts 2与ajax(第一部分)[未登录] 2007-09-30 16:59 |
@yy

关于struts2和ext的集成可以用struts2jsonplugin,很方便做grid
  回复  
  
# re: struts 2与ajax(第一部分)[未登录] 2007-10-07 13:24 |
自动完成,对中文没作用  回复  
  
# re: struts 2与ajax(第一部分)[未登录] 2007-10-09 17:33 |
我完全按照楼主的例子做了autocomplete,可是运行后点击三个框都没反应,也不报错,是浏览器设置的原因还是什么原因啊?  回复  
  
# re: struts 2与ajax(第一部分)[未登录] 2007-10-10 13:06 |
问题解决了,犯了个不该犯的错误,原来把类datas忘放到tomcat下了!  回复  
  
# re: struts 2与ajax(第一部分) 2007-10-12 10:28 |
我按着你说的方法做的
jsonplugin的包放到了lib下面,struts.xml也是照写的,可是tomcat报错。

there is no result type defined for type 'json' mapped with name 'success' - result - file:/f:/cvs_root/struts/webcontent/web-inf/classes/struts.xml:42:34

已经设置extends="json-default",还是没有json的的resulttype,请高人指点  回复  
  
# re: struts 2与ajax(第一部分) 2007-12-19 14:25 |
我按照你说的做..我遇到了个问题.给个凯发天生赢家一触即发官网的联系方式?qq或者是msn  回复  
  
# re: struts 2与ajax(第一部分) 2008-01-02 11:39 |
正准备在struts2中用ajax  回复  
  
# re: struts 2与ajax(第一部分) 2008-01-05 15:25 |
期待struts2和ext的集成例子出现,
感谢max,使我在struts2中少走了很多路!
  回复  
  
# re: struts 2与ajax(第一部分)[未登录] 2008-01-07 14:55 |
auto不能成功,谁能给个成功的例子啊  回复  
  
# re: struts 2与ajax(第一部分) 2008-01-08 17:48 |
sod,sodos.jdosslss  回复  
  
# re: struts 2与ajax(第一部分)[未登录] 2008-01-18 10:38 |
楼主,我发生了这个异常,不知是什么原因,请帮忙解决下
servlet.service() for servlet default threw exception
java.lang.illegalaccessexception: class com.googlecode.jsonplugin.jsonwriter can not access a member of class org.apache.commons.dbcp.poolingdatasource$poolguardconnectionwrapper with modifiers "public"  回复  
  
# re: struts 2与ajax(第一部分) 2008-01-18 13:13 |
rewqrewqrwq  回复  
  
# re: struts 2与ajax(第一部分) 2008-01-18 13:14 |
yyyyyyyyyyyy  回复  
  
# re: struts 2与ajax(第一部分)[未登录] 2008-01-30 13:15 |
这篇blog很早就看过了,当时看还没什么感觉
最近在研究ext的grid,用到了json ,再回来看struts2中的json,收获很大
感谢max~~~~  回复  
  
# re: struts 2与ajax(第一部分) 2008-01-31 13:59 |
我照做了您所有的例子。当我看到自动完成的这个例子的时候我异常的兴奋。但是上面都是只支持英文。。我想了很多办法都没有让它支持中文。。这个问题困扰了我1个多星期了。。希望您能帮助一下。。谢谢怎么才能让自动完成支持中文呢????  回复  
  
# re: struts 2与ajax(第一部分) 2008-03-07 10:57 |
中文好像支持不是很好,试了很久,需要改tomcat配置,
tomcat server.xml中 port="8080"中加uriencoding="utf-8"
uriencoding需要和页面中的<%@ page language="java" contenttype="text/html; charset=utf-8"
pageencoding="utf-8"%>
一致,不过好像页面上匹配有问题,找不到原因
  回复  
  
# re: struts 2与ajax(第一部分) 2008-04-03 09:56 |
不错的东西!!!!
  回复  
  
# re: struts 2与ajax(第一部分) 2008-04-03 09:57 |
你好!!  回复  
  
# re: struts 2与ajax(第一部分) 2008-04-03 10:02 |
12334344343  回复  
  
# re: struts 2与ajax(第一部分) 2008-04-03 10:11 |
22222  回复  
  
# re: struts 2与ajax(第一部分) 2008-04-06 18:27 |
中文是支持的!不过是在火狐里支持,在ie里就不支持了,我在start被用作数据库查询的关键字之前,对其进行了重新编码,ok了就。
string sutf8 = new string(start.getbytes("iso8859-1"),"utf8");

谁告诉我为什么在ie里不行在火狐行啊!难道是ie和火狐的默认编码不一样???  回复  
  
# re: struts 2与ajax(第一部分)[未登录] 2008-04-07 17:30 |
困扰了我一天,不支持中文,输入中文直接就不能触发,想了好多办法都不行,郁闷  回复  
  
# re: struts 2与ajax(第一部分) 2008-04-25 11:16 |
不错!max,demo写的很详细,受到不少帮忙,在此表示感谢。继续努力。
顶!!!  回复  
  
# re: struts 2与ajax(第一部分) 2008-04-28 15:34 |

为什么我直接这样写,说publish方法找不到啊?  回复  
  
# re: struts 2与ajax(第一部分) 2008-09-28 13:27 |
问题已解决,javascript提示错误不影响程序正确执行。  回复  
  
# re: struts 2与ajax(第一部分) 2008-11-17 17:23 |
太强了,谢谢你,读了你的博客收获真的非常大  回复  
  
# re: struts 2与ajax(第一部分) 2008-11-21 08:41 |
max在么?任何高手都可以解答。。。
那个autocompleter实现不了啊?什么原因???急。。。谢谢////  回复  
  
# re: struts 2与ajax(第一部分) 2008-11-27 21:34 |
使用了 json 在 action 里 不能直接 调用某个域模型了吗

是不是都要写成 很多的 字段 然后再??调用一定的业务逻辑操作?

那些字段有什么好的办法 简化吗  回复  
  
# re: struts 2与ajax(第一部分) 2009-04-08 18:28 |
function loadajaxcommodity(commodityid) {
dojo.io.bind({
url:"../ajax/loadcommodity.action?id=" commodityid,
handle:drawtable,
method:"get",
sync:false,
mimetype:"text/json"

});
}
为什么在ie中只发送一次请求呢  回复  
  
# tmd,这文章太棒了~![未登录] 2009-04-18 22:14 |
终于看到一篇完整的示例,完整的代码。就是要这样撒,语言口语化 简单明了 很不错!!!!!!!!!!  回复  
  
# re: struts 2与ajax(第一部分)[未登录] 2009-04-27 16:33 |
你好 着个例子好象有点问题
" target="_new" rel="nofollow">http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd">
http://www.w3.org/1999/xhtml" >

json plugin








运行时eval()这里通不过!!希望你调试,最好能将调试好的代码发给我,谢谢!
zhangxiong1203@163.com  回复  
  
# re: struts 2与ajax(第一部分)[未登录] 2009-06-16 10:38 |
@甲生
修改jar里的配置文件,extends=“struts-default”然后保存下,再把修改的文件覆盖到你的工程里就哦了  回复  
  
# re: struts 2与ajax(第一部分) 2009-06-21 15:53 |
max你好,我最近一直在看你的例子学习struts2
但是在这个例子的时候遇到了页面编译不通这的问题,经过一翻测试感觉在用
的时候要做以个修改。
a:导入dojo包<%@ taglib prefix="sx" uri="/struts-dojo-tags" %>
b:
c:标签用,其中不要加入theme="ajax"属性。  回复  
  
# re: struts 2与ajax(第一部分) 2009-07-23 15:08 |


loadontextchange="true" loadminimumcount="1" indicator="indicator"
autocomplete="false" showdownarrow="false" />
src="${pagecontext.request.contextpath}/ecside/images/gird/loading.gif"
alt="loading" style="display: none" />


已经可以取到值了,页面上为什么不能显示?  回复  
  
# re: struts 2与ajax(第一部分) 2009-11-19 11:10 |
突然喜欢上了struts2.0 ,发现技术的更新真是给我莫大的惊喜!  回复  
  
# re: struts 2与ajax(第一部分) 2010-01-15 13:49 |
the import com.googlecode cannot be resolved  回复  
  
# re: struts 2与ajax(第一部分) 2010-08-23 15:08 |
突然喜欢上了struts2.0 ,发现技术的更新真是给我莫大的惊喜!  回复  
  
# re: struts 2与ajax(第一部分) 2010-08-23 15:09 |
以上代码中,我没有使用任何的ajax的javascript包,而是参考《professional javascript for web developer》手工创建xhr(xmlhttprequest),并在xhr完成后使用eval()方法将json字符串变为json对象。需要注意的是,要调用eval函数时,必须使用“(”和“)”将json字符串括起来,否则会出错的。  回复  
  
# re: struts 2与ajax(第一部分)[未登录] 2013-04-17 14:35 |
单击节点后,不能弹出alert框,为什么,楼主  回复  
  
# re: struts 2与ajax(第一部分)[未登录] 2015-12-29 09:54 |
11  回复  
  

只有注册用户后才能发表评论。


网站导航:
              
 
网站地图